private static void MonitorMqtt () { UTF8Encoding Encoder = new UTF8Encoding (false); bool HasLightValue = false; bool HasMotionValue = false; MqttClient Client = null; try { WaitHandle[] Handles = new WaitHandle[]{ updateLeds, updateAlarm }; while (executing) { try { if (Client == null) { Client = new MqttClient ("iot.eclipse.org", MqttClient.DefaultPort, "LearningIoTController", string.Empty, false); //Client.RegisterLineListener (new ConsoleOutLineListenerSink (BinaryFormat.Hexadecimal)); Client.Open (); Client.CONNECT (20, true); Client.OnDataPublished += (Sender, e) => { string Topic = e.Topic; if (!Topic.StartsWith ("Clayster/LearningIoT/Sensor/")) return; string s = System.Text.Encoding.UTF8.GetString (e.Data); PhysicalMagnitude Magnitude; bool b; Topic = Topic.Substring (28); switch (Topic) { case "Light": if (PhysicalMagnitude.TryParse (s, out Magnitude) && Magnitude.Unit == "%" && Magnitude.Value >= 0 && Magnitude.Value <= 100) { lightPercent = Magnitude.Value; if (!HasLightValue) { HasLightValue = true; if (HasMotionValue) hasValues = true; } CheckControlRules (); } break; case "Motion": if (!string.IsNullOrEmpty (s) && XmlUtilities.TryParseBoolean (s, out b)) { motion = b; if (!HasMotionValue) { HasMotionValue = true; if (HasLightValue) hasValues = true; } CheckControlRules (); } break; } }; Client.SUBSCRIBE (new KeyValuePair<string, MqttQoS> ("Clayster/LearningIoT/Sensor/#", MqttQoS.QoS1_Acknowledged)); Log.Information ("Listening on MQTT topic Clayster/LearningIoT/Sensor @ ", EventLevel.Minor, Client.Host + ":" + Client.PortNumber.ToString ()); } switch (WaitHandle.WaitAny (Handles, 1000)) { case 0: // Update LEDS int i; lock (synchObject) { i = lastLedMask; } Client.PUBLISH ("Clayster/LearningIoT/Actuator/do", Encoder.GetBytes (i.ToString ()), MqttQoS.QoS1_Acknowledged, true); // Just to synchronize with the other topics. for (int j = 1; j <= 8; j++) { Client.PUBLISH ("Clayster/LearningIoT/Actuator/do" + j.ToString (), Encoder.GetBytes ((i & 1).ToString ()), MqttQoS.QoS1_Acknowledged, true); i >>= 1; } break; case 1: // Update Alarm bool b; lock (synchObject) { b = lastAlarm.Value; } Client.PUBLISH ("Clayster/LearningIoT/Actuator/ao", Encoder.GetBytes (b ? "1" : "0"), MqttQoS.QoS1_Acknowledged, true); if (b) { Thread T = new Thread (SendAlarmMail); T.Priority = ThreadPriority.BelowNormal; T.Name = "SendAlarmMail"; T.Start (); } break; default: // Timeout CheckSubscriptions (30); break; } } catch (ThreadAbortException) { // Don't log. Exception will be automatically re-raised. } catch (Exception ex) { Log.Exception (ex); if (Client != null) { Client.Dispose (); Client = null; } Thread.Sleep(5000); } } } finally { Client.Dispose (); } }
public static int Main (string[] args) { Log.Register (new ConsoleOutEventLog (80)); Log.Information ("Initializing application..."); HttpSocketClient.RegisterHttpProxyUse (false, false); // Don't look for proxies. DB.BackupConnectionString = "Data Source=actuator.db;Version=3;"; DB.BackupProviderName = "Clayster.Library.Data.Providers.SQLiteServer.SQLiteServerProvider"; db = DB.GetDatabaseProxy ("TheActuator"); Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => { e.Cancel = true; executionLed.Low (); }; // HTTP Interface HttpServer HttpServer = new HttpServer (80, 10, true, true, 1); int i; Log.Information ("HTTP Server receiving requests on port " + HttpServer.Port.ToString ()); HttpServer.RegisterAuthenticationMethod (new DigestAuthentication ("The Actuator Realm", GetDigestUserPasswordHash)); HttpServer.RegisterAuthenticationMethod (new SessionAuthentication ()); credentials = LoginCredentials.LoadCredentials (); if (credentials == null) { credentials = new LoginCredentials (); credentials.UserName = "******"; credentials.PasswordHash = CalcHash ("Admin", "Password"); credentials.SaveNew (); } state = State.LoadState (); if (state == null) { state = new State (); state.SaveNew (); } else { for (i = 0; i < 8; i++) digitalOutputs [i].Value = state.GetDO (i + 1); if (state.Alarm) AlarmOn (); else AlarmOff (); } WebServiceAPI wsApi; HttpServer.Register ("/", HttpGetRoot, HttpPostRoot, false); // Synchronous, no authentication HttpServer.Register ("/credentials", HttpGetCredentials, HttpPostCredentials, false); // Synchronous, no authentication HttpServer.Register ("/set", HttpGetSet, HttpPostSet, true); // Synchronous, http authentication HttpServer.Register ("/xml", HttpGetXml, true); // Synchronous, http authentication HttpServer.Register ("/json", HttpGetJson, true); // Synchronous, http authentication HttpServer.Register ("/turtle", HttpGetTurtle, true); // Synchronous, http authentication HttpServer.Register ("/rdf", HttpGetRdf, true); // Synchronous, http authentication HttpServer.Register (wsApi = new WebServiceAPI (), true); // HTTPS interface // Certificate must be a valid P12 (PFX) certificate file containing a private key. // X509Certificate2 Certificate = new X509Certificate2 ("Certificate.pfx", "PASSWORD"); // HttpServer HttpsServer = new HttpServer (443, 10, true, true, 1, true, false, Certificate); // // HttpsServer.RegisterAuthenticationMethod (new DigestAuthentication ("The Actuator Realm", GetDigestUserPasswordHash)); // // foreach (IHttpServerResource Resource in HttpServer.GetResources()) // HttpsServer.Register (Resource); // // Log.Information ("HTTPS Server receiving requests on port " + HttpsServer.Port.ToString ()); // CoAP Interface CoapEndpoint CoapEndpoint = new CoapEndpoint (); Log.Information ("CoAP endpoint receiving requests on port " + CoapEndpoint.Port.ToString ()); //CoapEndpoint.RegisterLineListener (new ConsoleOutLineListenerSink (BinaryFormat.Hexadecimal, true)); for (i = 1; i <= 8; i++) { CoapEndpoint.RegisterResource ("do" + i.ToString () + "/txt", "Digital Output " + i.ToString () + ", as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, false, CoapGetDigitalOutputTxt, CoapSetDigitalOutputTxt); } CoapEndpoint.RegisterResource ("do/txt", "Digital Outputs, as a number 0-255 as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, false, CoapGetDigitalOutputsTxt, CoapSetDigitalOutputsTxt); CoapEndpoint.RegisterResource ("alarm/txt", "Alarm Output " + i.ToString () + ", as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, false, CoapGetAlarmOutputTxt, CoapSetAlarmOutputTxt); foreach (CoapBlockSize BlockSize in Enum.GetValues(typeof(CoapBlockSize))) { if (BlockSize == CoapBlockSize.BlockLimit_Datagram) continue; string Bytes = (1 << (4 + (int)BlockSize)).ToString (); CoapEndpoint.RegisterResource ("xml/" + Bytes, "Complete sensor readout, in XML. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetXml); CoapEndpoint.RegisterResource ("json/" + Bytes, "Complete sensor readout, in JSON. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetJson); CoapEndpoint.RegisterResource ("turtle/" + Bytes, "Complete sensor readout, in TURTLE. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetTurtle); CoapEndpoint.RegisterResource ("rdf/" + Bytes, "Complete sensor readout, in RDF. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetRdf); } // MQTT MqttClient MqttClient = new MqttClient ("iot.eclipse.org", MqttClient.DefaultPort, "LearningIoTActuator", string.Empty, false); //MqttClient.RegisterLineListener (new ConsoleOutLineListenerSink (BinaryFormat.Hexadecimal)); MqttClient.Open (); MqttClient.CONNECT (20, true); MqttClient.PUBLISH ("Clayster/LearningIoT/Actuator/ao", state.Alarm ? "1" : "0", MqttQoS.QoS1_Acknowledged, true); MqttClient.PUBLISH ("Clayster/LearningIoT/Actuator/do", wsApi.GetDigitalOutputs ().ToString (), MqttQoS.QoS1_Acknowledged, true); for (i = 1; i <= 8; i++) MqttClient.PUBLISH ("Clayster/LearningIoT/Actuator/do" + i.ToString (), wsApi.GetDigitalOutput (i) ? "1" : "0", MqttQoS.QoS1_Acknowledged, true); MqttClient.SUBSCRIBE (new KeyValuePair<string, MqttQoS> ("Clayster/LearningIoT/Actuator/#", MqttQoS.QoS1_Acknowledged)); MqttClient.OnDataPublished += OnMqttDataPublished; Log.Information ("Receiving commands via MQTT from Clayster/LearningIoT/Actuator @ ", EventLevel.Minor, MqttClient.Host + ":" + MqttClient.PortNumber.ToString ()); // Main loop Log.Information ("Initialization complete. Application started..."); try { while (executionLed.Value) { System.Threading.Thread.Sleep (1000); RemoveOldSessions (); } } catch (Exception ex) { Log.Exception (ex); executionLed.Low (); } finally { Log.Information ("Terminating application."); Log.Flush (); Log.Terminate (); HttpServer.Dispose (); //HttpsServer.Dispose (); if (MqttClient != null) MqttClient.Dispose (); executionLed.Dispose (); foreach (DigitalOutput Output in digitalOutputs) Output.Dispose (); if (alarmThread != null) { alarmThread.Abort (); alarmThread = null; } } return 0; }
private static void MqttThread () { WaitHandle[] Events = new WaitHandle[]{ mqttNewTemp, mqttNewLight, mqttNewMotion }; MqttClient Client = null; try { while (true) { try { if (Client == null) { Client = new MqttClient ("iot.eclipse.org", MqttClient.DefaultPort, "LearningIoTSensor", string.Empty, false); //Client.RegisterLineListener (new ConsoleOutLineListenerSink (BinaryFormat.Hexadecimal)); Client.Open (); Client.CONNECT (20, true); Log.Information ("Publishing via MQTT to Clayster/LearningIoT/Sensor @ ", EventLevel.Minor, Client.Host + ":" + Client.PortNumber.ToString ()); } switch (WaitHandle.WaitAny (Events, 1000)) { case 0: // New temperature Client.PUBLISH ("Clayster/LearningIoT/Sensor/Temperature", FieldNumeric.Format (temperatureC, "C", 1), MqttQoS.QoS1_Acknowledged, true); break; case 1: // New light Client.PUBLISH ("Clayster/LearningIoT/Sensor/Light", FieldNumeric.Format (lightPercent, "%", 1), MqttQoS.QoS1_Acknowledged, true); break; case 2: // New motion Client.PUBLISH ("Clayster/LearningIoT/Sensor/Motion", motionDetected ? "1" : "0", MqttQoS.QoS1_Acknowledged, true); break; } } catch (Exception ex) { Log.Exception (ex); if (Client != null) { Client.Dispose (); Client = null; } mqttNewTemp.Set (); mqttNewLight.Set (); mqttNewMotion.Set (); Thread.Sleep(5000); } } } catch (ThreadAbortException) { Thread.ResetAbort (); } catch (Exception ex) { Log.Exception (ex); } finally { if (Client != null) Client.Dispose (); } }
private static void MonitorMqtt() { UTF8Encoding Encoder = new UTF8Encoding(false); bool HasLightValue = false; bool HasMotionValue = false; MqttClient Client = null; try { WaitHandle[] Handles = new WaitHandle[] { updateLeds, updateAlarm }; while (executing) { try { if (Client == null) { Client = new MqttClient("iot.eclipse.org", MqttClient.DefaultPort, "LearningIoTController", string.Empty, false); //Client.RegisterLineListener (new ConsoleOutLineListenerSink (BinaryFormat.Hexadecimal)); Client.Open(); Client.CONNECT(20, true); Client.OnDataPublished += (Sender, e) => { string Topic = e.Topic; if (!Topic.StartsWith("Clayster/LearningIoT/Sensor/")) { return; } string s = System.Text.Encoding.UTF8.GetString(e.Data); PhysicalMagnitude Magnitude; bool b; Topic = Topic.Substring(28); switch (Topic) { case "Light": if (PhysicalMagnitude.TryParse(s, out Magnitude) && Magnitude.Unit == "%" && Magnitude.Value >= 0 && Magnitude.Value <= 100) { lightPercent = Magnitude.Value; if (!HasLightValue) { HasLightValue = true; if (HasMotionValue) { hasValues = true; } } CheckControlRules(); } break; case "Motion": if (!string.IsNullOrEmpty(s) && XmlUtilities.TryParseBoolean(s, out b)) { motion = b; if (!HasMotionValue) { HasMotionValue = true; if (HasLightValue) { hasValues = true; } } CheckControlRules(); } break; } }; Client.SUBSCRIBE(new KeyValuePair <string, MqttQoS> ("Clayster/LearningIoT/Sensor/#", MqttQoS.QoS1_Acknowledged)); Log.Information("Listening on MQTT topic Clayster/LearningIoT/Sensor @ ", EventLevel.Minor, Client.Host + ":" + Client.PortNumber.ToString()); } switch (WaitHandle.WaitAny(Handles, 1000)) { case 0: // Update LEDS int i; lock (synchObject) { i = lastLedMask; } Client.PUBLISH("Clayster/LearningIoT/Actuator/do", Encoder.GetBytes(i.ToString()), MqttQoS.QoS1_Acknowledged, true); // Just to synchronize with the other topics. for (int j = 1; j <= 8; j++) { Client.PUBLISH("Clayster/LearningIoT/Actuator/do" + j.ToString(), Encoder.GetBytes((i & 1).ToString()), MqttQoS.QoS1_Acknowledged, true); i >>= 1; } break; case 1: // Update Alarm bool b; lock (synchObject) { b = lastAlarm.Value; } Client.PUBLISH("Clayster/LearningIoT/Actuator/ao", Encoder.GetBytes(b ? "1" : "0"), MqttQoS.QoS1_Acknowledged, true); if (b) { Thread T = new Thread(SendAlarmMail); T.Priority = ThreadPriority.BelowNormal; T.Name = "SendAlarmMail"; T.Start(); } break; default: // Timeout CheckSubscriptions(30); break; } } catch (ThreadAbortException) { // Don't log. Exception will be automatically re-raised. } catch (Exception ex) { Log.Exception(ex); if (Client != null) { Client.Dispose(); Client = null; } Thread.Sleep(5000); } } } finally { Client.Dispose(); } }
public static int Main(string[] args) { Log.Register(new ConsoleOutEventLog(80)); Log.Information("Initializing application..."); HttpSocketClient.RegisterHttpProxyUse(false, false); // Don't look for proxies. DB.BackupConnectionString = "Data Source=actuator.db;Version=3;"; DB.BackupProviderName = "Clayster.Library.Data.Providers.SQLiteServer.SQLiteServerProvider"; db = DB.GetDatabaseProxy("TheActuator"); Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => { e.Cancel = true; executionLed.Low(); }; // HTTP Interface HttpServer HttpServer = new HttpServer(80, 10, true, true, 1); int i; Log.Information("HTTP Server receiving requests on port " + HttpServer.Port.ToString()); HttpServer.RegisterAuthenticationMethod(new DigestAuthentication("The Actuator Realm", GetDigestUserPasswordHash)); HttpServer.RegisterAuthenticationMethod(new SessionAuthentication()); credentials = LoginCredentials.LoadCredentials(); if (credentials == null) { credentials = new LoginCredentials(); credentials.UserName = "******"; credentials.PasswordHash = CalcHash("Admin", "Password"); credentials.SaveNew(); } state = State.LoadState(); if (state == null) { state = new State(); state.SaveNew(); } else { for (i = 0; i < 8; i++) { digitalOutputs [i].Value = state.GetDO(i + 1); } if (state.Alarm) { AlarmOn(); } else { AlarmOff(); } } WebServiceAPI wsApi; HttpServer.Register("/", HttpGetRoot, HttpPostRoot, false); // Synchronous, no authentication HttpServer.Register("/credentials", HttpGetCredentials, HttpPostCredentials, false); // Synchronous, no authentication HttpServer.Register("/set", HttpGetSet, HttpPostSet, true); // Synchronous, http authentication HttpServer.Register("/xml", HttpGetXml, true); // Synchronous, http authentication HttpServer.Register("/json", HttpGetJson, true); // Synchronous, http authentication HttpServer.Register("/turtle", HttpGetTurtle, true); // Synchronous, http authentication HttpServer.Register("/rdf", HttpGetRdf, true); // Synchronous, http authentication HttpServer.Register(wsApi = new WebServiceAPI(), true); // HTTPS interface // Certificate must be a valid P12 (PFX) certificate file containing a private key. // X509Certificate2 Certificate = new X509Certificate2 ("Certificate.pfx", "PASSWORD"); // HttpServer HttpsServer = new HttpServer (443, 10, true, true, 1, true, false, Certificate); // // HttpsServer.RegisterAuthenticationMethod (new DigestAuthentication ("The Actuator Realm", GetDigestUserPasswordHash)); // // foreach (IHttpServerResource Resource in HttpServer.GetResources()) // HttpsServer.Register (Resource); // // Log.Information ("HTTPS Server receiving requests on port " + HttpsServer.Port.ToString ()); // CoAP Interface CoapEndpoint CoapEndpoint = new CoapEndpoint(); Log.Information("CoAP endpoint receiving requests on port " + CoapEndpoint.Port.ToString()); //CoapEndpoint.RegisterLineListener (new ConsoleOutLineListenerSink (BinaryFormat.Hexadecimal, true)); for (i = 1; i <= 8; i++) { CoapEndpoint.RegisterResource("do" + i.ToString() + "/txt", "Digital Output " + i.ToString() + ", as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, false, CoapGetDigitalOutputTxt, CoapSetDigitalOutputTxt); } CoapEndpoint.RegisterResource("do/txt", "Digital Outputs, as a number 0-255 as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, false, CoapGetDigitalOutputsTxt, CoapSetDigitalOutputsTxt); CoapEndpoint.RegisterResource("alarm/txt", "Alarm Output " + i.ToString() + ", as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, false, CoapGetAlarmOutputTxt, CoapSetAlarmOutputTxt); foreach (CoapBlockSize BlockSize in Enum.GetValues(typeof(CoapBlockSize))) { if (BlockSize == CoapBlockSize.BlockLimit_Datagram) { continue; } string Bytes = (1 << (4 + (int)BlockSize)).ToString(); CoapEndpoint.RegisterResource("xml/" + Bytes, "Complete sensor readout, in XML. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetXml); CoapEndpoint.RegisterResource("json/" + Bytes, "Complete sensor readout, in JSON. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetJson); CoapEndpoint.RegisterResource("turtle/" + Bytes, "Complete sensor readout, in TURTLE. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetTurtle); CoapEndpoint.RegisterResource("rdf/" + Bytes, "Complete sensor readout, in RDF. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetRdf); } // MQTT MqttClient MqttClient = new MqttClient("iot.eclipse.org", MqttClient.DefaultPort, "LearningIoTActuator", string.Empty, false); //MqttClient.RegisterLineListener (new ConsoleOutLineListenerSink (BinaryFormat.Hexadecimal)); MqttClient.Open(); MqttClient.CONNECT(20, true); MqttClient.PUBLISH("Clayster/LearningIoT/Actuator/ao", state.Alarm ? "1" : "0", MqttQoS.QoS1_Acknowledged, true); MqttClient.PUBLISH("Clayster/LearningIoT/Actuator/do", wsApi.GetDigitalOutputs().ToString(), MqttQoS.QoS1_Acknowledged, true); for (i = 1; i <= 8; i++) { MqttClient.PUBLISH("Clayster/LearningIoT/Actuator/do" + i.ToString(), wsApi.GetDigitalOutput(i) ? "1" : "0", MqttQoS.QoS1_Acknowledged, true); } MqttClient.SUBSCRIBE(new KeyValuePair <string, MqttQoS> ("Clayster/LearningIoT/Actuator/#", MqttQoS.QoS1_Acknowledged)); MqttClient.OnDataPublished += OnMqttDataPublished; Log.Information("Receiving commands via MQTT from Clayster/LearningIoT/Actuator @ ", EventLevel.Minor, MqttClient.Host + ":" + MqttClient.PortNumber.ToString()); // Main loop Log.Information("Initialization complete. Application started..."); try { while (executionLed.Value) { System.Threading.Thread.Sleep(1000); RemoveOldSessions(); } } catch (Exception ex) { Log.Exception(ex); executionLed.Low(); } finally { Log.Information("Terminating application."); Log.Flush(); Log.Terminate(); HttpServer.Dispose(); //HttpsServer.Dispose (); if (MqttClient != null) { MqttClient.Dispose(); } executionLed.Dispose(); foreach (DigitalOutput Output in digitalOutputs) { Output.Dispose(); } if (alarmThread != null) { alarmThread.Abort(); alarmThread = null; } } return(0); }