[NF] Schönere und Mehr Ansichten

This commit is contained in:
BlubbFish 2017-09-17 22:13:54 +00:00
parent d92fc88795
commit a9e2e6a0bc
8 changed files with 305 additions and 70 deletions

View File

@ -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;
}
}
} }
} }

View 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;
}
}
}
}
}

View File

@ -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>

View File

@ -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);
})); }));
} }

View File

@ -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++;

View File

@ -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")) {

View File

@ -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">

View File

@ -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;