[NF] Schönere und Mehr Ansichten
This commit is contained in:
parent
d92fc88795
commit
a9e2e6a0bc
@ -9,6 +9,7 @@ namespace Mqtt_SWB_Dashboard.Helper {
|
|||||||
|
|
||||||
public Dictionary<String, Device> Devices { get; private set; }
|
public Dictionary<String, Device> Devices { get; private set; }
|
||||||
public DateTime Active { get; private set; }
|
public DateTime Active { get; private set; }
|
||||||
|
public Boolean Connected { get; private set; }
|
||||||
|
|
||||||
public Household(String did, Device device) {
|
public Household(String did, Device device) {
|
||||||
this.Active = DateTime.Now;
|
this.Active = DateTime.Now;
|
||||||
@ -19,11 +20,21 @@ namespace Mqtt_SWB_Dashboard.Helper {
|
|||||||
|
|
||||||
public Household(JsonData data) {
|
public Household(JsonData data) {
|
||||||
this.Devices = new Dictionary<String, Device>();
|
this.Devices = new Dictionary<String, Device>();
|
||||||
|
if (data.Keys.Contains("Devices")) {
|
||||||
foreach (KeyValuePair<String, JsonData> item in data["Devices"]) {
|
foreach (KeyValuePair<String, JsonData> item in data["Devices"]) {
|
||||||
this.Devices.Add(item.Key, new Device(item.Value));
|
this.Devices.Add(item.Key, new Device(item.Value));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if(data.Keys.Contains("Connected")) {
|
||||||
|
this.Connected = Boolean.Parse(data["Connected"].ToString());
|
||||||
|
if (this.Connected) {
|
||||||
|
this.Active = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(data.Keys.Contains("Active")) {
|
||||||
this.Active = DateTime.Parse(data["Active"].ToString(), new CultureInfo("en-US"));
|
this.Active = DateTime.Parse(data["Active"].ToString(), new CultureInfo("en-US"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void PutDevice(String did, JsonData data, Device.DevType dtype) {
|
public void PutDevice(String did, JsonData data, Device.DevType dtype) {
|
||||||
this.Active = DateTime.Now;
|
this.Active = DateTime.Now;
|
||||||
@ -83,5 +94,12 @@ namespace Mqtt_SWB_Dashboard.Helper {
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void PutConnection(JsonData data) {
|
||||||
|
this.Connected = Boolean.Parse(data["Connected"].ToString());
|
||||||
|
if(this.Connected) {
|
||||||
|
this.Active = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
Mqtt-SWB-Dashboard/Helper/Raspi.cs
Normal file
35
Mqtt-SWB-Dashboard/Helper/Raspi.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using System;
|
||||||
|
using LitJson;
|
||||||
|
|
||||||
|
namespace Mqtt_SWB_Dashboard.Helper {
|
||||||
|
class Raspi {
|
||||||
|
|
||||||
|
public Raspi(JsonData data) {
|
||||||
|
PutStatus(data);
|
||||||
|
if(data.Keys.Contains("Connected")) {
|
||||||
|
this.Connected = Boolean.Parse(data["Connected"].ToString());
|
||||||
|
}
|
||||||
|
if (data.Keys.Contains("Uptime")) {
|
||||||
|
this.Uptime = Double.Parse(data["Uptime"].ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean Connected { get; private set; }
|
||||||
|
public Double Uptime { get; private set; }
|
||||||
|
|
||||||
|
internal void PutStatus(JsonData data) {
|
||||||
|
if (data.Keys.Contains("message")) {
|
||||||
|
if (data["message"].Keys.Contains("status")) {
|
||||||
|
this.Connected = (data["message"]["status"].ToString() == "disconnected") ? false : true;
|
||||||
|
if (!this.Connected) {
|
||||||
|
this.Uptime = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (data["message"].Keys.Contains("uptime")) {
|
||||||
|
this.Uptime = Double.Parse(data["message"]["uptime"].ToString());
|
||||||
|
this.Connected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,20 +7,27 @@
|
|||||||
xmlns:models="clr-namespace:Mqtt_SWB_Dashboard.Models"
|
xmlns:models="clr-namespace:Mqtt_SWB_Dashboard.Models"
|
||||||
xmlns:local="clr-namespace:Mqtt_SWB_Dashboard"
|
xmlns:local="clr-namespace:Mqtt_SWB_Dashboard"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="MainWindow" Height="350" Width="525" Closed="OnClosed">
|
Title="SWB-Tempora" Height="350" Width="525" Closed="OnClosed">
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<models:PowerChartModel />
|
<models:PowerChartModel />
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextBlock HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="Haushalte" VerticalAlignment="Top" Width="60"/>
|
<TextBlock HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="Haushalte" VerticalAlignment="Top" Width="70" TextAlignment="Center"/>
|
||||||
<TextBlock HorizontalAlignment="Left" Margin="75,10,0,0" TextWrapping="Wrap" Text="Geräte" VerticalAlignment="Top" Width="40"/>
|
<TextBlock HorizontalAlignment="Left" Margin="85,10,0,0" TextWrapping="Wrap" Text="Geräte" VerticalAlignment="Top" Width="40" TextAlignment="Center"/>
|
||||||
<TextBlock x:Name="countHouses" HorizontalAlignment="Left" Margin="10,31,0,0" TextWrapping="Wrap" Text="0 / 0" VerticalAlignment="Top" Width="60" TextAlignment="Center"/>
|
<TextBlock HorizontalAlignment="Left" Margin="10,94,0,0" TextWrapping="Wrap" Text="Power" VerticalAlignment="Top" Width="115" TextAlignment="Center"/>
|
||||||
<TextBlock x:Name="countDevices" HorizontalAlignment="Left" Margin="75,31,0,0" TextWrapping="Wrap" Text="0 / 0" VerticalAlignment="Top" Width="40" TextAlignment="Center"/>
|
<TextBlock HorizontalAlignment="Left" Margin="10,52,0,0" TextWrapping="Wrap" Text="Verbrauch" VerticalAlignment="Top" Width="115" TextAlignment="Center"/>
|
||||||
<TextBlock HorizontalAlignment="Left" Margin="10,94,0,0" TextWrapping="Wrap" Text="Power" VerticalAlignment="Top" Width="105"/>
|
<TextBlock HorizontalAlignment="Left" Margin="130,10,0,0" TextWrapping="Wrap" Text="Raspis" VerticalAlignment="Top" Width="50" TextAlignment="Center"/>
|
||||||
<TextBlock HorizontalAlignment="Left" Margin="10,52,0,0" TextWrapping="Wrap" Text="Verbrauch" VerticalAlignment="Top" Width="105"/>
|
<TextBlock HorizontalAlignment="Left" Margin="185,10,0,0" TextWrapping="Wrap" Text="Most Uptime" VerticalAlignment="Top" Width="185" TextAlignment="Center"/>
|
||||||
<TextBlock x:Name="countPower" HorizontalAlignment="Left" Margin="10,115,0,0" TextWrapping="Wrap" Text="0 / 0" VerticalAlignment="Top" Width="105" TextAlignment="Center"/>
|
<TextBlock HorizontalAlignment="Left" Margin="375,10,0,0" TextWrapping="Wrap" Text="Avg Uptime" VerticalAlignment="Top" Width="120" TextAlignment="Center"/>
|
||||||
<TextBlock x:Name="countColum" HorizontalAlignment="Left" Margin="10,73,0,0" TextWrapping="Wrap" Text="0 / 0" VerticalAlignment="Top" Width="105" TextAlignment="Center"/>
|
<TextBlock x:Name="countHouses" HorizontalAlignment="Left" Margin="10,31,0,0" TextWrapping="Wrap" Text="0 / 0 / 0" VerticalAlignment="Top" Width="70" TextAlignment="Center"/>
|
||||||
<TextBlock Margin="272,94,32,191" Text="{Binding TotalNumberOfPoints, StringFormat='Total number of data points: {0}'}"/>
|
<TextBlock x:Name="countDevices" HorizontalAlignment="Left" Margin="85,31,0,0" TextWrapping="Wrap" Text="0 / 0" VerticalAlignment="Top" Width="40" TextAlignment="Center"/>
|
||||||
|
<TextBlock x:Name="countPower" HorizontalAlignment="Left" Margin="10,115,0,0" TextWrapping="Wrap" Text="0W / 0W" VerticalAlignment="Top" Width="115" TextAlignment="Center"/>
|
||||||
|
<TextBlock x:Name="countColum" HorizontalAlignment="Left" Margin="10,73,0,0" TextWrapping="Wrap" Text="0kW / 0kW" VerticalAlignment="Top" Width="115" TextAlignment="Center"/>
|
||||||
|
<TextBlock x:Name="countRaspis" HorizontalAlignment="Left" Margin="130,31,0,0" TextWrapping="Wrap" Text="0 / 0" VerticalAlignment="Top" Width="50" TextAlignment="Center"/>
|
||||||
|
<TextBlock x:Name="maxRaspi" HorizontalAlignment="Left" Margin="185,31,0,0" TextWrapping="Wrap" Text="- / 0" VerticalAlignment="Top" Width="185" TextAlignment="Center"/>
|
||||||
|
<TextBlock x:Name="avgUptime" HorizontalAlignment="Left" Margin="375,31,0,0" TextWrapping="Wrap" Text="0t 00:00:00" VerticalAlignment="Top" Width="120" TextAlignment="Center"/>
|
||||||
|
<TextBlock HorizontalAlignment="Left" Margin="130,115,0,0" TextWrapping="Wrap" Text="{Binding TotalNumberOfPoints, StringFormat='Total number of data points: {0}'}" VerticalAlignment="Top"/>
|
||||||
<oxy:PlotView Margin="10,136,10,10" Model="{Binding Model}" />
|
<oxy:PlotView Margin="10,136,10,10" Model="{Binding Model}" />
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
@ -25,10 +25,16 @@ namespace Mqtt_SWB_Dashboard {
|
|||||||
this.Dispatcher.BeginInvoke((Action)(() => {
|
this.Dispatcher.BeginInvoke((Action)(() => {
|
||||||
this.countHouses.Text = sender.GetNumberHouseholds();
|
this.countHouses.Text = sender.GetNumberHouseholds();
|
||||||
this.countDevices.Text = sender.GetNumberDevices();
|
this.countDevices.Text = sender.GetNumberDevices();
|
||||||
this.countColum.Text = sender.GetCurrentColum();
|
|
||||||
|
|
||||||
|
this.countRaspis.Text = sender.GetNumberRaspis();
|
||||||
|
this.maxRaspi.Text = sender.GetMostRaspiUptime();
|
||||||
|
this.avgUptime.Text = sender.GetAvgRaspiUptime();
|
||||||
Tuple<Double, Double> power = sender.GetCurrentPower();
|
Tuple<Double, Double> power = sender.GetCurrentPower();
|
||||||
this.countPower.Text = power.Item1 + "W / "+power.Item2+"W";
|
this.countPower.Text = power.Item1 + "W / " + power.Item2 + "W";
|
||||||
((Models.PowerChartModel)this.DataContext).AddPower(power);
|
Tuple<Double, Double> colum = sender.GetCurrentColum();
|
||||||
|
this.countColum.Text = colum.Item1.ToString("F1") + "kW / " + colum.Item2.ToString("F1") + "kW";
|
||||||
|
((Models.PowerChartModel)this.DataContext).AddPower(power, colum);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@ using OxyPlot.Series;
|
|||||||
|
|
||||||
namespace Mqtt_SWB_Dashboard.Models {
|
namespace Mqtt_SWB_Dashboard.Models {
|
||||||
public class PowerChartModel : INotifyPropertyChanged {
|
public class PowerChartModel : INotifyPropertyChanged {
|
||||||
private Double MaximumDrawn = 5;
|
private Double MaximumDrawnL = 5;
|
||||||
|
private Double MaximumDrawnR = 5;
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
@ -19,26 +20,45 @@ namespace Mqtt_SWB_Dashboard.Models {
|
|||||||
Instance = this;
|
Instance = this;
|
||||||
this.Model = new PlotModel { Title = "Stromverbrauch" };
|
this.Model = new PlotModel { Title = "Stromverbrauch" };
|
||||||
this.Model.Axes.Add(new DateTimeAxis { Position = AxisPosition.Bottom, AbsoluteMinimum = DateTimeAxis.ToDouble(DateTime.Now), AbsoluteMaximum = DateTimeAxis.ToDouble(DateTime.Now.AddMinutes(1)), IsZoomEnabled = false });
|
this.Model.Axes.Add(new DateTimeAxis { Position = AxisPosition.Bottom, AbsoluteMinimum = DateTimeAxis.ToDouble(DateTime.Now), AbsoluteMaximum = DateTimeAxis.ToDouble(DateTime.Now.AddMinutes(1)), IsZoomEnabled = false });
|
||||||
this.Model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, AbsoluteMinimum = 0, AbsoluteMaximum = 1, IsZoomEnabled = false });
|
this.Model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, AbsoluteMinimum = 0, Minimum = 0, AbsoluteMaximum = 1, IsZoomEnabled = false });
|
||||||
|
this.Model.Axes.Add(new LinearAxis { Position = AxisPosition.Right, AbsoluteMinimum = 0, Minimum = 0, AbsoluteMaximum = 1, IsZoomEnabled = false, Key = "Right" });
|
||||||
|
|
||||||
this.Model.Series.Add(new LineSeries { Title = "Active [W]", Color = OxyColor.FromRgb(0, 150, 0) });
|
this.Model.Series.Add(new LineSeries { Title = "Active [W]", Color = OxyColor.FromRgb(0, 150, 0) });
|
||||||
this.Model.Series.Add(new LineSeries { Title = "Seen [W]", Color = OxyColor.FromRgb(0, 255, 0) });
|
this.Model.Series.Add(new LineSeries { Title = "Seen [W]", Color = OxyColor.FromRgb(0, 255, 0) });
|
||||||
|
this.Model.Series.Add(new LineSeries { Title = "Active [kW]", Color = OxyColor.FromRgb(0, 0, 150), YAxisKey= "Right" });
|
||||||
|
this.Model.Series.Add(new LineSeries { Title = "Seen [kW]", Color = OxyColor.FromRgb(0, 0, 255), YAxisKey = "Right" });
|
||||||
this.RaisePropertyChanged("Model");
|
this.RaisePropertyChanged("Model");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddPower(Tuple<Double, Double> power) {
|
internal void AddPower(Tuple<Double, Double> power, Tuple<Double, Double> colum) {
|
||||||
|
if((power.Item1 == 0 && power.Item2 == 0) || (colum.Item1 == 0 && colum.Item2 == 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
((LineSeries)this.Model.Series[0]).Points.Add(new DataPoint(DateTimeAxis.ToDouble(DateTime.Now), power.Item1));
|
((LineSeries)this.Model.Series[0]).Points.Add(new DataPoint(DateTimeAxis.ToDouble(DateTime.Now), power.Item1));
|
||||||
((LineSeries)this.Model.Series[1]).Points.Add(new DataPoint(DateTimeAxis.ToDouble(DateTime.Now), power.Item2));
|
((LineSeries)this.Model.Series[1]).Points.Add(new DataPoint(DateTimeAxis.ToDouble(DateTime.Now), power.Item2));
|
||||||
|
((LineSeries)this.Model.Series[2]).Points.Add(new DataPoint(DateTimeAxis.ToDouble(DateTime.Now), colum.Item1));
|
||||||
|
((LineSeries)this.Model.Series[3]).Points.Add(new DataPoint(DateTimeAxis.ToDouble(DateTime.Now), colum.Item2));
|
||||||
|
|
||||||
if(this.MaximumDrawn < power.Item1) {
|
if (this.MaximumDrawnL < power.Item1) {
|
||||||
this.MaximumDrawn = power.Item1;
|
this.MaximumDrawnL = power.Item1;
|
||||||
}
|
}
|
||||||
if (this.MaximumDrawn < power.Item2) {
|
if (this.MaximumDrawnL < power.Item2) {
|
||||||
this.MaximumDrawn = power.Item2;
|
this.MaximumDrawnL = power.Item2;
|
||||||
}
|
}
|
||||||
this.Model.Axes[1].Minimum = 0;
|
if (this.MaximumDrawnR < colum.Item1) {
|
||||||
this.Model.Axes[1].Maximum = this.MaximumDrawn*1.1;
|
this.MaximumDrawnR = colum.Item1;
|
||||||
this.Model.Axes[1].AbsoluteMaximum = this.MaximumDrawn*1.1;
|
}
|
||||||
|
if (this.MaximumDrawnR < colum.Item2) {
|
||||||
|
this.MaximumDrawnR = colum.Item2;
|
||||||
|
}
|
||||||
|
//this.Model.Axes[1].Minimum = 0;
|
||||||
|
//this.Model.Axes[2].Minimum = 0;
|
||||||
|
this.Model.Axes[1].Maximum = this.MaximumDrawnL * 1.1;
|
||||||
|
this.Model.Axes[1].AbsoluteMaximum = this.MaximumDrawnL * 1.1;
|
||||||
|
|
||||||
|
this.Model.Axes[2].Maximum = this.MaximumDrawnR * 1.05;
|
||||||
|
this.Model.Axes[2].AbsoluteMaximum = this.MaximumDrawnR * 1.05;
|
||||||
|
|
||||||
this.Model.Axes[0].AbsoluteMaximum = DateTimeAxis.ToDouble(DateTime.Now);
|
this.Model.Axes[0].AbsoluteMaximum = DateTimeAxis.ToDouble(DateTime.Now);
|
||||||
|
|
||||||
this.TotalNumberOfPoints++;
|
this.TotalNumberOfPoints++;
|
||||||
|
@ -19,11 +19,19 @@ namespace Mqtt_SWB_Dashboard {
|
|||||||
this.p.StartInfo.CreateNoWindow = true;
|
this.p.StartInfo.CreateNoWindow = true;
|
||||||
this.p.StartInfo.UseShellExecute = false;
|
this.p.StartInfo.UseShellExecute = false;
|
||||||
this.p.StartInfo.RedirectStandardOutput = true;
|
this.p.StartInfo.RedirectStandardOutput = true;
|
||||||
|
this.p.StartInfo.RedirectStandardError = true;
|
||||||
this.p.OutputDataReceived += this.P_OutputDataReceived;
|
this.p.OutputDataReceived += this.P_OutputDataReceived;
|
||||||
|
this.p.ErrorDataReceived += this.P_ErrorDataReceived;
|
||||||
this.p.Start();
|
this.p.Start();
|
||||||
this.p.BeginOutputReadLine();
|
this.p.BeginOutputReadLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void P_ErrorDataReceived(Object sender, DataReceivedEventArgs e) {
|
||||||
|
if (e.Data != null) {
|
||||||
|
throw new NotImplementedException(e.Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void P_OutputDataReceived(Object sender, DataReceivedEventArgs e) {
|
private void P_OutputDataReceived(Object sender, DataReceivedEventArgs e) {
|
||||||
if (e.Data != null) {
|
if (e.Data != null) {
|
||||||
if (e.Data.StartsWith("Client mosqsub")) {
|
if (e.Data.StartsWith("Client mosqsub")) {
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
</ApplicationDefinition>
|
</ApplicationDefinition>
|
||||||
<Compile Include="Helper\Device.cs" />
|
<Compile Include="Helper\Device.cs" />
|
||||||
<Compile Include="Helper\Household.cs" />
|
<Compile Include="Helper\Household.cs" />
|
||||||
|
<Compile Include="Helper\Raspi.cs" />
|
||||||
<Compile Include="Models\PowerChartModel.cs" />
|
<Compile Include="Models\PowerChartModel.cs" />
|
||||||
<Compile Include="Stats.cs" />
|
<Compile Include="Stats.cs" />
|
||||||
<Page Include="MainWindow.xaml">
|
<Page Include="MainWindow.xaml">
|
||||||
|
@ -9,55 +9,100 @@ using Mqtt_SWB_Dashboard.Helper;
|
|||||||
namespace Mqtt_SWB_Dashboard {
|
namespace Mqtt_SWB_Dashboard {
|
||||||
internal class Stats : IDisposable {
|
internal class Stats : IDisposable {
|
||||||
private Dictionary<String, Household> households = new Dictionary<String, Household>();
|
private Dictionary<String, Household> households = new Dictionary<String, Household>();
|
||||||
|
private Dictionary<String, Raspi> raspis = new Dictionary<String, Raspi>();
|
||||||
private Mosquitto mosquitto;
|
private Mosquitto mosquitto;
|
||||||
|
|
||||||
public delegate void UpdateMessage(Stats sender, EventArgs e);
|
public delegate void UpdateMessage(Stats sender, EventArgs e);
|
||||||
public event UpdateMessage UpdatedConsumption;
|
public event UpdateMessage UpdatedConsumption;
|
||||||
|
|
||||||
public Stats(Mosquitto mosquitto) {
|
public Stats(Mosquitto mosquitto) {
|
||||||
LoadHouseholds();
|
LoadSavedData();
|
||||||
this.mosquitto = mosquitto;
|
this.mosquitto = mosquitto;
|
||||||
this.mosquitto.MessageIncomming += this.Mosquitto_MessageIncomming;
|
this.mosquitto.MessageIncomming += this.Mosquitto_MessageIncomming;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadHouseholds() {
|
private void LoadSavedData() {
|
||||||
if(File.Exists("household.json")) {
|
if (File.Exists("household.json")) {
|
||||||
try {
|
try {
|
||||||
String json = File.ReadAllText("household.json");
|
JsonData data = JsonMapper.ToObject(File.ReadAllText("household.json"));
|
||||||
JsonData data = JsonMapper.ToObject(json);
|
|
||||||
foreach (KeyValuePair<String, JsonData> item in data) {
|
foreach (KeyValuePair<String, JsonData> item in data) {
|
||||||
this.households.Add(item.Key, new Household(item.Value));
|
this.households.Add(item.Key, new Household(item.Value));
|
||||||
}
|
}
|
||||||
} catch (Exception) { }
|
} catch (Exception) { }
|
||||||
}
|
}
|
||||||
|
if (File.Exists("raspi.json")) {
|
||||||
|
JsonData data = JsonMapper.ToObject(File.ReadAllText("raspi.json"));
|
||||||
|
foreach (KeyValuePair<String, JsonData> item in data) {
|
||||||
|
this.raspis.Add(item.Key, new Raspi(item.Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
private void Mosquitto_MessageIncomming(Object sender, MqttEventArgs e) {
|
private void Mosquitto_MessageIncomming(Object sender, MqttEventArgs e) {
|
||||||
if (e.Topic == "/flex4grid/VersionControl/LocalGateway/groups/BONN_1") {
|
if (e.Topic == "/flex4grid/VersionControl/LocalGateway/groups/BONN_1") {
|
||||||
|
this.LvcMessages(e);
|
||||||
} else if (Regex.Match(e.Topic, "/flex4grid/VersionControl/LocalGateway/hosts/.*/status").Success ||
|
} else if (Regex.Match(e.Topic, "/flex4grid/VersionControl/LocalGateway/hosts/.*/status").Success ||
|
||||||
e.Topic == "/flex4grid/VersionControl/LocalGateway/status" ||
|
e.Topic == "/flex4grid/VersionControl/LocalGateway/status") {
|
||||||
Regex.Match(e.Topic, "/flex4grid/VersionControl/LocalGateway/hosts/.*/logs/gateway/plugs/gateway_plugs_1").Success) {
|
this.RaspiStatus(e);
|
||||||
this.GatewayPing(e);
|
} else if(Regex.Match(e.Topic, "/flex4grid/VersionControl/LocalGateway/hosts/.*/logs/gateway/plugs/gateway_plugs_1").Success) {
|
||||||
|
this.RaspiLogs(e);
|
||||||
} else if (Regex.Match(e.Topic, "/flex4grid/v1/households/.*/connection").Success) {
|
} else if (Regex.Match(e.Topic, "/flex4grid/v1/households/.*/connection").Success) {
|
||||||
this.HouseholdPing(e);
|
this.HouseholdStatus(e);
|
||||||
} else if (Regex.Match(e.Topic, "/flex4grid/v1/households/.*/consumption").Success ||
|
} else if (Regex.Match(e.Topic, "/flex4grid/v1/households/.*/consumption").Success ||
|
||||||
Regex.Match(e.Topic, "/flex4grid/v1/households/.*/device/consumption").Success ||
|
Regex.Match(e.Topic, "/flex4grid/v1/households/.*/device/consumption").Success ||
|
||||||
Regex.Match(e.Topic, "/flex4grid/v1/households/.*/device/state").Success) {
|
Regex.Match(e.Topic, "/flex4grid/v1/households/.*/device/state").Success) {
|
||||||
this.HouseholdConsumption(e);
|
this.HouseholdConsumption(e);
|
||||||
} else if (Regex.Match(e.Topic, "/flex4grid/v1/households/.*/devices/state/request").Success) {
|
} else if (Regex.Match(e.Topic, "/flex4grid/v1/households/.*/devices/state/request").Success ||
|
||||||
this.HouseholdRequest(e);
|
Regex.Match(e.Topic, "/flex4grid/v1/households/.*/devices/state/response").Success) {
|
||||||
|
this.DeviceStates(e);
|
||||||
|
} else if (Regex.Match(e.Topic, "/flex4grid/v1/households/.*/device/actuate").Success) {
|
||||||
|
this.DeviceSwitching(e);
|
||||||
} else {
|
} else {
|
||||||
throw new NotImplementedException(e.Topic);
|
System.Windows.MessageBox.Show(e.Topic + " " + e.Message);
|
||||||
}//
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HouseholdRequest(MqttEventArgs e) {
|
/// <summary>
|
||||||
//throw new NotImplementedException();
|
/// LogMessages eines Raspis
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void RaspiLogs(MqttEventArgs e) {
|
||||||
|
// /flex4grid/VersionControl/LocalGateway/hosts/F4G-B827EB705A1F/logs/gateway/plugs/gateway_plugs_1 2017-09-17T20:31:13.081733337Z
|
||||||
|
// [main] MQTTPulbisher.onConnectionLost() lost connection to the broker: pingresp not received, disconnecting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Nachrichten des LVC-Images
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void LvcMessages(MqttEventArgs e) {
|
||||||
|
//"/flex4grid/VersionControl/LocalGateway/groups/BONN_1 {\n \"src\": \"fc.flex4grid.eu\",\n \"type\": \"config_update\",\n..." -> Nachricht vom Lvc Image
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Nachricht wenn ein gerät umgeschaltet werden soll von der App aus.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void DeviceSwitching(MqttEventArgs e) {
|
||||||
|
// "/flex4grid/v1/households/911b2e25-8ac4-4ad0-90ae-c8cff42c4224/device/actuate {"command":"OFF","deviceId":"6","timestamp":"2017-09-17T16:41:50.963000Z"}" -> App Gerät Schalten
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Status der Geräte von der App aus abfragen und den Schaltzustand antworten
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void DeviceStates(MqttEventArgs e) {
|
||||||
|
// "/flex4grid/v1/households/911b2e25-8ac4-4ad0-90ae-c8cff42c4224/devices/state/request {"timestamp": "2017-09-17T16:40:46.456000Z"}" -> App Gerät Abfragen
|
||||||
|
// "/flex4grid/v1/households/911b2e25-8ac4-4ad0-90ae-c8cff42c4224/devices/state/response {"2": "active", "3": "active", "4": "active", "5": "active", "6": "active", "timestamp": "2017-09-17T14:43:52.536676Z"}" -> App Gerät Antworten
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Schaltstatus, Stromverbrauch und Produktion von PowerPlugs
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e"></param>
|
||||||
private void HouseholdConsumption(MqttEventArgs e) {
|
private void HouseholdConsumption(MqttEventArgs e) {
|
||||||
Match m = Regex.Match(e.Topic, "/flex4grid/v1/households/([^/]*)/(consumption|device/(consumption|state))");
|
Match m = Regex.Match(e.Topic, "/flex4grid/v1/households/([^/]*)/(consumption|device/(consumption|state))");
|
||||||
String id = m.Groups[1].Value;
|
String id = m.Groups[1].Value;
|
||||||
@ -78,61 +123,154 @@ namespace Mqtt_SWB_Dashboard {
|
|||||||
this.households.Add(id, new Household(did, new Device(data, dtype)));
|
this.households.Add(id, new Household(did, new Device(data, dtype)));
|
||||||
}
|
}
|
||||||
this.UpdatedConsumption?.Invoke(this, null);
|
this.UpdatedConsumption?.Invoke(this, null);
|
||||||
} catch (Exception) { }
|
} catch (Exception) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeviceStatus(MqttEventArgs e) {
|
/// <summary>
|
||||||
throw new NotImplementedException();
|
/// Nachricht ob ein Gerät verbunden ist (Vermutlich vom Master)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private void HouseholdStatus(MqttEventArgs e) {
|
||||||
|
Match m = Regex.Match(e.Topic, "/flex4grid/v1/households/([^/]*)/connection");
|
||||||
|
String id = m.Groups[1].Value;
|
||||||
|
try {
|
||||||
|
JsonData data = JsonMapper.ToObject(e.Message.Replace("connected", "Connected"));
|
||||||
|
if (this.households.Keys.Contains(id)) {
|
||||||
|
this.households[id].PutConnection(data);
|
||||||
|
} else {
|
||||||
|
this.households.Add(id, new Household(data));
|
||||||
|
}
|
||||||
|
this.UpdatedConsumption?.Invoke(this, null);
|
||||||
|
} catch (Exception) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HouseholdPing(MqttEventArgs e) {
|
private void RaspiStatus(MqttEventArgs e) {
|
||||||
//throw new NotImplementedException();
|
try {
|
||||||
|
JsonData data = JsonMapper.ToObject(e.Message);
|
||||||
|
String id = data["src"].ToString();
|
||||||
|
if (this.raspis.Keys.Contains(id)) {
|
||||||
|
this.raspis[id].PutStatus(data);
|
||||||
|
} else {
|
||||||
|
this.raspis.Add(id, new Raspi(data));
|
||||||
|
}
|
||||||
|
this.UpdatedConsumption?.Invoke(this, null);
|
||||||
|
} catch (Exception) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GatewayPing(MqttEventArgs e) {
|
#region Statistics Output
|
||||||
//throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal String GetNumberDevices() {
|
internal String GetNumberDevices() {
|
||||||
Int32 active = 0;
|
Int32 active = 0;
|
||||||
Int32 all = 0;
|
Int32 all = 0;
|
||||||
|
try {
|
||||||
foreach (KeyValuePair<String, Household> item in this.households) {
|
foreach (KeyValuePair<String, Household> item in this.households) {
|
||||||
active += item.Value.GetActive();
|
active += item.Value.GetActive();
|
||||||
all += item.Value.Devices.Count;
|
all += item.Value.Devices.Count;
|
||||||
}
|
}
|
||||||
|
} catch(Exception) {
|
||||||
|
return "0 / 0";
|
||||||
|
}
|
||||||
return active.ToString() + " / " + all.ToString();
|
return active.ToString() + " / " + all.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal String GetNumberHouseholds() {
|
internal String GetNumberHouseholds() {
|
||||||
Int32 active = 0;
|
Int32 active = 0;
|
||||||
|
Int32 ping = 0;
|
||||||
Int32 all = this.households.Count;
|
Int32 all = this.households.Count;
|
||||||
|
try {
|
||||||
foreach (KeyValuePair<String, Household> item in this.households) {
|
foreach (KeyValuePair<String, Household> item in this.households) {
|
||||||
if (item.Value.Active > DateTime.Now.AddMinutes(-10)) {
|
if (item.Value.Active > DateTime.Now.AddMinutes(-10)) {
|
||||||
|
ping++;
|
||||||
|
}
|
||||||
|
if (item.Value.Connected) {
|
||||||
active++;
|
active++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return active.ToString() + " / " + all.ToString();
|
} catch (Exception) {
|
||||||
|
return "0 / 0 / 0";
|
||||||
|
}
|
||||||
|
return ping + " / " + active + " / " + all;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Tuple<Double, Double> GetCurrentPower() {
|
internal Tuple<Double, Double> GetCurrentPower() {
|
||||||
Double active = 0;
|
Double active = 0;
|
||||||
Double all = 0;
|
Double all = 0;
|
||||||
|
try {
|
||||||
foreach (KeyValuePair<String, Household> item in this.households) {
|
foreach (KeyValuePair<String, Household> item in this.households) {
|
||||||
active += item.Value.GetPower();
|
active += item.Value.GetPower();
|
||||||
all += item.Value.GetAllPower();
|
all += item.Value.GetAllPower();
|
||||||
}
|
}
|
||||||
|
} catch(Exception) {
|
||||||
|
return new Tuple<Double, Double>(0d, 0d);
|
||||||
|
}
|
||||||
return new Tuple<Double, Double>(active, all);
|
return new Tuple<Double, Double>(active, all);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal String GetCurrentColum() {
|
internal Tuple<Double, Double> GetCurrentColum() {
|
||||||
Double active = 0;
|
Double active = 0;
|
||||||
Double all = 0;
|
Double all = 0;
|
||||||
|
try {
|
||||||
foreach (KeyValuePair<String, Household> item in this.households) {
|
foreach (KeyValuePair<String, Household> item in this.households) {
|
||||||
active += item.Value.GetColum();
|
active += item.Value.GetColum();
|
||||||
all += item.Value.GetAllColum();
|
all += item.Value.GetAllColum();
|
||||||
}
|
}
|
||||||
return active.ToString("F1") + "kW / " + all.ToString("F1") + "kW";
|
} catch(Exception) {
|
||||||
|
return new Tuple<Double, Double>(0d, 0d);
|
||||||
}
|
}
|
||||||
|
return new Tuple<Double, Double>(active, all);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal String GetNumberRaspis() {
|
||||||
|
Int32 active = 0;
|
||||||
|
Int32 all = this.raspis.Count;
|
||||||
|
try {
|
||||||
|
foreach (KeyValuePair<String, Raspi> item in this.raspis) {
|
||||||
|
if(item.Value.Connected) {
|
||||||
|
active++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception) {
|
||||||
|
return "0 / 0";
|
||||||
|
}
|
||||||
|
return active.ToString() + " / " + all.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal String GetAvgRaspiUptime() {
|
||||||
|
Double values = 0;
|
||||||
|
Int32 count = 0;
|
||||||
|
try {
|
||||||
|
foreach (KeyValuePair<String, Raspi> item in this.raspis) {
|
||||||
|
if (item.Value.Connected) {
|
||||||
|
values += item.Value.Uptime;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception) {
|
||||||
|
return "0t 00:00:00";
|
||||||
|
}
|
||||||
|
return new TimeSpan((Int64)((values/count) * 10000000d)).ToString("%d't 'hh':'mm':'ss");
|
||||||
|
}
|
||||||
|
|
||||||
|
internal String GetMostRaspiUptime() {
|
||||||
|
Double max = 0;
|
||||||
|
String name="";
|
||||||
|
try {
|
||||||
|
foreach (KeyValuePair<String, Raspi> item in this.raspis) {
|
||||||
|
if (item.Value.Connected && max < item.Value.Uptime) {
|
||||||
|
max = item.Value.Uptime;
|
||||||
|
name = item.Key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception) {
|
||||||
|
return "- / 0";
|
||||||
|
}
|
||||||
|
return name + " / " + new TimeSpan((Int64)(max * 10000000d)).ToString("%d't 'hh':'mm':'ss");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region IDisposable Support
|
#region IDisposable Support
|
||||||
private Boolean disposedValue = false; // Dient zur Erkennung redundanter Aufrufe.
|
private Boolean disposedValue = false; // Dient zur Erkennung redundanter Aufrufe.
|
||||||
@ -141,8 +279,10 @@ namespace Mqtt_SWB_Dashboard {
|
|||||||
if (!this.disposedValue) {
|
if (!this.disposedValue) {
|
||||||
if (disposing) {
|
if (disposing) {
|
||||||
this.mosquitto.MessageIncomming -= this.Mosquitto_MessageIncomming;
|
this.mosquitto.MessageIncomming -= this.Mosquitto_MessageIncomming;
|
||||||
String json = JsonMapper.ToJson(this.households);
|
String households = JsonMapper.ToJson(this.households);
|
||||||
File.WriteAllText("household.json", json);
|
File.WriteAllText("household.json", households);
|
||||||
|
String raspis = JsonMapper.ToJson(this.raspis);
|
||||||
|
File.WriteAllText("raspi.json", raspis);
|
||||||
this.mosquitto.Dispose();
|
this.mosquitto.Dispose();
|
||||||
}
|
}
|
||||||
this.mosquitto = null;
|
this.mosquitto = null;
|
||||||
|
Loading…
Reference in New Issue
Block a user