diff --git a/Mqtt-Dashboard/Connector/Mosquitto.cs b/Mqtt-Dashboard/Connector/Mosquitto.cs index 75edd61..39f620a 100644 --- a/Mqtt-Dashboard/Connector/Mosquitto.cs +++ b/Mqtt-Dashboard/Connector/Mosquitto.cs @@ -11,23 +11,24 @@ namespace Dashboard.Connector { public override event MqttMessage MessageIncomming; public override event MqttMessage MessageSending; - public Mosquitto(Dictionary settings) { + public Mosquitto(Dictionary mqtt_settings) { + this.settings = mqtt_settings; //mosquitto_sub --cafile ca.pem --cert cert.pem --key cert.key -h swb.broker.flex4grid.eu -p 8883 -t /# -v this.message = ""; this.p = new Process(); - this.p.StartInfo.FileName = "mosquitto_sub.exe"; - String args = "-h " + settings["server"]+" "; - if(settings.ContainsKey("port")) { - args += "-p "+ settings["port"]+" "; + this.p.StartInfo.FileName = "mosquitto_sub"; + String args = "-h " + this.settings["server"]+" "; + if(this.settings.ContainsKey("port")) { + args += "-p "+ this.settings["port"]+" "; } - if (settings.ContainsKey("cafile")) { - args += "--cafile " + settings["cafile"] + " "; + if (this.settings.ContainsKey("cafile")) { + args += "--cafile " + this.settings["cafile"] + " "; } - if (settings.ContainsKey("cert")) { - args += "--cert " + settings["cert"] + " "; + if (this.settings.ContainsKey("cert")) { + args += "--cert " + this.settings["cert"] + " "; } - if (settings.ContainsKey("key")) { - args += "--key " + settings["key"] + " "; + if (this.settings.ContainsKey("key")) { + args += "--key " + this.settings["key"] + " "; } this.p.StartInfo.Arguments = args+"-t /# -v -d"; this.p.StartInfo.CreateNoWindow = true; @@ -38,9 +39,30 @@ namespace Dashboard.Connector { this.p.ErrorDataReceived += this.P_ErrorDataReceived; this.p.Start(); this.p.BeginOutputReadLine(); + } public override void Send(String topic, String data) { + Process send = new Process(); + send.StartInfo.FileName = "mosquitto_pub"; + String args = "-h " + this.settings["server"] + " "; + if (this.settings.ContainsKey("port")) { + args += "-p " + this.settings["port"] + " "; + } + if (this.settings.ContainsKey("cafile")) { + args += "--cafile " + this.settings["cafile"] + " "; + } + if (this.settings.ContainsKey("cert")) { + args += "--cert " + this.settings["cert"] + " "; + } + if (this.settings.ContainsKey("key")) { + args += "--key " + this.settings["key"] + " "; + } + send.StartInfo.Arguments = args + "-m \""+data.Replace("\"","\\\"")+"\" -t \""+topic+"\" -d"; + send.StartInfo.CreateNoWindow = true; + send.StartInfo.UseShellExecute = false; + send.Start(); + send.WaitForExit(); MessageSending?.Invoke(this, new MqttEventArgs(data, topic)); } @@ -68,6 +90,7 @@ namespace Dashboard.Connector { #region IDisposable Support private Boolean disposedValue = false; // Dient zur Erkennung redundanter Aufrufe. + private readonly Dictionary settings; protected virtual void Dispose(Boolean disposing) { if (!this.disposedValue) { diff --git a/Mqtt-Dashboard/Dashboard.csproj b/Mqtt-Dashboard/Dashboard.csproj index c6628d1..121f1e4 100644 --- a/Mqtt-Dashboard/Dashboard.csproj +++ b/Mqtt-Dashboard/Dashboard.csproj @@ -66,6 +66,7 @@ + diff --git a/Mqtt-Dashboard/Form1.Designer.cs b/Mqtt-Dashboard/Form1.Designer.cs index 489c590..99dc06f 100644 --- a/Mqtt-Dashboard/Form1.Designer.cs +++ b/Mqtt-Dashboard/Form1.Designer.cs @@ -29,9 +29,9 @@ // // statusStrip1 // - this.statusStrip1.Location = new System.Drawing.Point(0, 370); + this.statusStrip1.Location = new System.Drawing.Point(0, 490); this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Size = new System.Drawing.Size(843, 22); + this.statusStrip1.Size = new System.Drawing.Size(1247, 22); this.statusStrip1.TabIndex = 0; this.statusStrip1.Text = "statusStrip1"; // @@ -39,14 +39,14 @@ // this.flowLayoutPanel2.Location = new System.Drawing.Point(12, 12); this.flowLayoutPanel2.Name = "flowLayoutPanel2"; - this.flowLayoutPanel2.Size = new System.Drawing.Size(819, 355); + this.flowLayoutPanel2.Size = new System.Drawing.Size(1223, 475); this.flowLayoutPanel2.TabIndex = 3; // // Dashboard // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(843, 392); + this.ClientSize = new System.Drawing.Size(1247, 512); this.Controls.Add(this.flowLayoutPanel2); this.Controls.Add(this.statusStrip1); this.Name = "Dashboard"; diff --git a/Mqtt-Dashboard/Form1.cs b/Mqtt-Dashboard/Form1.cs index aff0be1..4aef8fe 100644 --- a/Mqtt-Dashboard/Form1.cs +++ b/Mqtt-Dashboard/Form1.cs @@ -21,6 +21,7 @@ namespace Dashboard { this.SizeChanged += this.Dashboard_SizeChanged; AMqtt.Instance.MessageIncomming += this.Instance_MessageIncomming; + AMqtt.Instance.MessageSending += this.Instance_MessageSending; } private void Dashboard_SizeChanged(Object sender, EventArgs e) { @@ -55,8 +56,13 @@ namespace Dashboard { AMqtt.Instance.Dispose(); this.Dispose(true); } + private void Instance_MessageIncomming(Object sender, MqttEventArgs e) { System.Diagnostics.Debug.WriteLine("Received = " + e.Message + " on topic " + e.Topic+" at "+DateTime.Now.ToUniversalTime()); } + + private void Instance_MessageSending(Object sender, MqttEventArgs e) { + System.Diagnostics.Debug.WriteLine("Sended = " + e.Message + " on topic " + e.Topic + " at " + DateTime.Now.ToUniversalTime()); + } } } diff --git a/Mqtt-Dashboard/Sensor/ASensor.cs b/Mqtt-Dashboard/Sensor/ASensor.cs index 1f7b252..b7f86bc 100644 --- a/Mqtt-Dashboard/Sensor/ASensor.cs +++ b/Mqtt-Dashboard/Sensor/ASensor.cs @@ -3,36 +3,41 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading; +using System.Text.RegularExpressions; namespace Dashboard.Sensor { public abstract class ASensor : IDisposable { - private String topic; - private Int32 pollcount; + protected String topic; + protected Int32 pollcount; private Dictionary settings; private Thread updateThread; + private Boolean pollEnabled = false; public ASensor(Dictionary settings) { this.GetBool = true; this.GetFloat = 0.0f; this.GetInt = 0; this.topic = (settings.Keys.Contains("topic")) ? settings["topic"] : ""; - this.Polling = (settings.Keys.Contains("polling")) ? Int32.Parse(settings["polling"]) : 60; - this.pollcount = this.Polling; this.settings = settings; AMqtt.Instance.MessageIncomming += this.IncommingMqttMessage; - this.updateThread = new Thread(this.SensorPolling); - this.updateThread.Start(); + if (settings.Keys.Contains("polling")) { + this.pollEnabled = true; + this.Polling = Int32.Parse(settings["polling"]); + this.pollcount = this.Polling; + this.updateThread = new Thread(this.SensorPolling); + this.updateThread.Start(); + } } private void SensorPolling() { - while(true) { + while(this.pollEnabled) { Thread.Sleep(1000); this.Poll(); } } private void IncommingMqttMessage(Object sender, MqttEventArgs e) { - if(e.Topic == this.topic) { + if(Regex.Match(e.Topic, this.topic).Success) { if (this.UpdateValue(e)) { this.Timestamp = DateTime.Now; this.Update?.Invoke(this, e); @@ -51,7 +56,7 @@ namespace Dashboard.Sensor { return (ASensor)t.GetConstructor(new Type[] { typeof(Dictionary) }).Invoke(new Object[] { dictionary }); } - private void Poll() { + protected virtual void Poll() { if(this.pollcount++ >= this.Polling) { this.pollcount = 1; AMqtt.Instance.Send(this.topic + "/status",""); @@ -80,11 +85,16 @@ namespace Dashboard.Sensor { #region IDisposable Support private Boolean disposedValue = false; + + protected virtual void Dispose(Boolean disposing) { if(!this.disposedValue) { if(disposing) { - this.updateThread.Abort(); - while(this.updateThread.ThreadState != ThreadState.Aborted) { } + this.pollEnabled = false; + if (this.updateThread != null && this.updateThread.ThreadState == ThreadState.Running) { + this.updateThread.Abort(); + while (this.updateThread.ThreadState != ThreadState.Aborted) { } + } AMqtt.Instance.MessageIncomming -= this.IncommingMqttMessage; } this.settings = null; diff --git a/Mqtt-Dashboard/Sensor/Flex4GridSwitch.cs b/Mqtt-Dashboard/Sensor/Flex4GridSwitch.cs new file mode 100644 index 0000000..c9f800d --- /dev/null +++ b/Mqtt-Dashboard/Sensor/Flex4GridSwitch.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text.RegularExpressions; +using Dashboard.Connector; +using LitJson; + +namespace Dashboard.Sensor { + class Flex4gridswitch : ASensor { + private String id; + + public Flex4gridswitch(Dictionary settings) : base(settings) { + this.Datatypes = Types.Bool; + this.id = settings["id"]; + } + + protected override Boolean UpdateValue(MqttEventArgs e) { + CultureInfo info = new CultureInfo("de-DE"); + info.NumberFormat.NumberDecimalSeparator = "."; + CultureInfo.DefaultThreadCurrentCulture = info; + CultureInfo.DefaultThreadCurrentUICulture = info; + System.Threading.Thread.CurrentThread.CurrentCulture = info; + System.Threading.Thread.CurrentThread.CurrentUICulture = info; + try { + JsonData data = JsonMapper.ToObject(e.Message); + if (data.Keys.Contains("id") && data["id"].ToString() == this.id) { + this.GetBool = data["status"].ToString() == "active" ? true : false; + return true; + } + if(data.Keys.Contains(this.id)) { + this.GetBool = data[this.id].ToString() == "active" ? true : false; + return true; + } + } catch (Exception) { + } + return false; + } + + protected override void Poll() { + if (this.pollcount++ >= this.Polling) { + this.pollcount = 1; + String hid = Regex.Match(this.topic, "/flex4grid/v1/households/([^/]*)/device/state").Groups[1].Value; + AMqtt.Instance.Send("/flex4grid/v1/households/" + hid + "/devices/state/request", "{\"timestamp\": \"" + DateTime.Now.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'ffffff'Z'") + "\"}"); + } + } + + internal override void SetBool(Boolean v) { + String hid = Regex.Match(this.topic, "/flex4grid/v1/households/([^/]*)/device/state").Groups[1].Value; + AMqtt.Instance.Send("/flex4grid/v1/households/" + hid + "/device/actuate", "{\"command\":\""+(v ? "ON" : "OFF") + "\",\"deviceId\":\"6\",\"timestamp\":\"" + DateTime.Now.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'ffffff'Z'") + "\"}"); + } + } +} \ No newline at end of file diff --git a/Mqtt-Dashboard/Sensor/Flex4gridPower.cs b/Mqtt-Dashboard/Sensor/Flex4gridPower.cs index ac52449..a21d439 100644 --- a/Mqtt-Dashboard/Sensor/Flex4gridPower.cs +++ b/Mqtt-Dashboard/Sensor/Flex4gridPower.cs @@ -9,9 +9,6 @@ namespace Dashboard.Sensor { private String id; public Flex4gridpower(Dictionary settings) : base(settings) { - this.GetBool = true; - this.GetFloat = 0.0f; - this.GetInt = 0; this.Datatypes = Types.Float; this.id = settings["id"]; } diff --git a/Mqtt-Dashboard/bin/Release/Dashboard.exe b/Mqtt-Dashboard/bin/Release/Dashboard.exe index 407abd6..62faf5e 100644 Binary files a/Mqtt-Dashboard/bin/Release/Dashboard.exe and b/Mqtt-Dashboard/bin/Release/Dashboard.exe differ