private async void Init() { try { Log.Informational("Starting application."); Types.Initialize( typeof(FilesProvider).GetTypeInfo().Assembly, typeof(RuntimeSettings).GetTypeInfo().Assembly, typeof(IContentEncoder).GetTypeInfo().Assembly, typeof(ICoapContentFormat).GetTypeInfo().Assembly, typeof(IDtlsCredentials).GetTypeInfo().Assembly, typeof(Lwm2mClient).GetTypeInfo().Assembly, typeof(App).GetTypeInfo().Assembly); db = new FilesProvider(Windows.Storage.ApplicationData.Current.LocalFolder.Path + Path.DirectorySeparatorChar + "Data", "Default", 8192, 1000, 8192, Encoding.UTF8, 10000); Database.Register(db); await db.RepairIfInproperShutdown(null); await db.Start(); #if GPIO gpio = GpioController.GetDefault(); if (gpio != null) { if (gpio.TryOpenPin(gpioOutputPin, GpioSharingMode.Exclusive, out this.gpioPin, out GpioOpenStatus Status) && Status == GpioOpenStatus.PinOpened) { if (this.gpioPin.IsDriveModeSupported(GpioPinDriveMode.Output)) { this.gpioPin.SetDriveMode(GpioPinDriveMode.Output); this.output = await RuntimeSettings.GetAsync("Actuator.Output", false); this.gpioPin.Write(this.output.Value ? GpioPinValue.High : GpioPinValue.Low); this.digitalOutput0?.Set(this.output.Value); this.actuation0?.Set(this.output.Value); await MainPage.Instance.OutputSet(this.output.Value); Log.Informational("Setting Control Parameter.", string.Empty, "Startup", new KeyValuePair <string, object>("Output", this.output.Value)); } else { Log.Error("Output mode not supported for GPIO pin " + gpioOutputPin.ToString()); } } else { Log.Error("Unable to get access to GPIO pin " + gpioOutputPin.ToString()); } } #else DeviceInformationCollection Devices = await UsbSerial.listAvailableDevicesAsync(); DeviceInformation DeviceInfo = this.FindDevice(Devices, "Arduino", "USB Serial Device"); if (DeviceInfo is null) { Log.Error("Unable to find Arduino device."); } else { Log.Informational("Connecting to " + DeviceInfo.Name); this.arduinoUsb = new UsbSerial(DeviceInfo); this.arduinoUsb.ConnectionEstablished += () => Log.Informational("USB connection established."); this.arduino = new RemoteDevice(this.arduinoUsb); this.arduino.DeviceReady += async() => { try { Log.Informational("Device ready."); this.arduino.pinMode(13, PinMode.OUTPUT); // Onboard LED. this.arduino.digitalWrite(13, PinState.HIGH); this.arduino.pinMode(8, PinMode.INPUT); // PIR sensor (motion detection). this.arduino.pinMode(9, PinMode.OUTPUT); // Relay. this.output = await RuntimeSettings.GetAsync("Actuator.Output", false); this.arduino.digitalWrite(9, this.output.Value ? PinState.HIGH : PinState.LOW); this.digitalOutput0?.Set(this.output.Value); this.actuation0?.Set(this.output.Value); await MainPage.Instance.OutputSet(this.output.Value); Log.Informational("Setting Control Parameter.", string.Empty, "Startup", new KeyValuePair <string, object>("Output", this.output.Value)); this.arduino.pinMode("A0", PinMode.ANALOG); // Light sensor. } catch (Exception ex) { Log.Critical(ex); } }; this.arduinoUsb.ConnectionFailed += message => { Log.Error("USB connection failed: " + message); }; this.arduinoUsb.ConnectionLost += message => { Log.Error("USB connection lost: " + message); }; this.arduinoUsb.begin(57600, SerialConfig.SERIAL_8N1); } #endif this.deviceId = await RuntimeSettings.GetAsync("DeviceId", string.Empty); if (string.IsNullOrEmpty(this.deviceId)) { this.deviceId = Guid.NewGuid().ToString().Replace("-", string.Empty); await RuntimeSettings.SetAsync("DeviceId", this.deviceId); } Log.Informational("Device ID: " + this.deviceId); /************************************************************************************ * To create an unencrypted CoAP Endpoint on the default CoAP port: * * this.coapEndpoint = new CoapEndpoint(); * * To create an unencrypted CoAP Endpoint on the default CoAP port, * with a sniffer that outputs communication to the window: * * this.coapEndpoint = new CoapEndpoint(new LogSniffer()); * * To create a DTLS encrypted CoAP endpoint, on the default CoAPS port, using * the users defined in the IUserSource users: * * this.coapEndpoint = new CoapEndpoint(CoapEndpoint.DefaultCoapsPort, this.users); * * To create a CoAP endpoint, that listens to both the default CoAP port, for * unencrypted communication, and the default CoAPS port, for encrypted, * authenticated and authorized communication, using * the users defined in the IUserSource users. Only users having the given * privilege (if not empty) will be authorized to access resources on the endpoint: * * this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, * new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, "PRIVILEGE", false, false); * ************************************************************************************/ this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, string.Empty, false, false); this.outputResource = this.coapEndpoint.Register("/Output", (req, resp) => { string s; if (this.output.HasValue) { s = this.output.Value ? "true" : "false"; } else { s = "-"; } resp.Respond(CoapCode.Content, s, 64); }, async(req, resp) => { try { string s = req.Decode() as string; if (s is null && req.Payload != null) { s = Encoding.UTF8.GetString(req.Payload); } if (s is null || !CommonTypes.TryParse(s, out bool Output)) { resp.RST(CoapCode.BadRequest); } else { resp.Respond(CoapCode.Changed); await this.SetOutput(Output, req.From.ToString()); } } catch (Exception ex) { Log.Critical(ex); } }, Notifications.Acknowledged, "Digital Output.", null, null,
private async void Init() { try { Log.Informational("Starting application."); Types.Initialize( typeof(FilesProvider).GetTypeInfo().Assembly, typeof(RuntimeSettings).GetTypeInfo().Assembly, typeof(IContentEncoder).GetTypeInfo().Assembly, typeof(ICoapContentFormat).GetTypeInfo().Assembly, typeof(IDtlsCredentials).GetTypeInfo().Assembly, typeof(App).GetTypeInfo().Assembly); db = new FilesProvider(Windows.Storage.ApplicationData.Current.LocalFolder.Path + Path.DirectorySeparatorChar + "Data", "Default", 8192, 1000, 8192, Encoding.UTF8, 10000); Database.Register(db); await db.RepairIfInproperShutdown(null); await db.Start(); DeviceInformationCollection Devices = await UsbSerial.listAvailableDevicesAsync(); DeviceInformation DeviceInfo = this.FindDevice(Devices, "Arduino", "USB Serial Device"); if (DeviceInfo is null) { Log.Error("Unable to find Arduino device."); } else { Log.Informational("Connecting to " + DeviceInfo.Name); this.arduinoUsb = new UsbSerial(DeviceInfo); this.arduinoUsb.ConnectionEstablished += () => Log.Informational("USB connection established."); this.arduino = new RemoteDevice(this.arduinoUsb); this.arduino.DeviceReady += () => { Log.Informational("Device ready."); this.arduino.pinMode(13, PinMode.OUTPUT); // Onboard LED. this.arduino.digitalWrite(13, PinState.HIGH); this.arduino.pinMode(8, PinMode.INPUT); // PIR sensor (motion detection). PinState Pin8 = this.arduino.digitalRead(8); this.lastMotion = Pin8 == PinState.HIGH; MainPage.Instance.DigitalPinUpdated(8, Pin8); this.arduino.pinMode(9, PinMode.OUTPUT); // Relay. this.arduino.digitalWrite(9, 0); // Relay set to 0 this.arduino.pinMode("A0", PinMode.ANALOG); // Light sensor. MainPage.Instance.AnalogPinUpdated("A0", this.arduino.analogRead("A0")); this.sampleTimer = new Timer(this.SampleValues, null, 1000 - DateTime.Now.Millisecond, 1000); }; this.arduino.AnalogPinUpdated += (pin, value) => { MainPage.Instance.AnalogPinUpdated(pin, value); }; this.arduino.DigitalPinUpdated += (pin, value) => { MainPage.Instance.DigitalPinUpdated(pin, value); if (pin == 8) { this.lastMotion = (value == PinState.HIGH); this.motionResource?.TriggerAll(); this.momentaryResource?.TriggerAll(); } }; this.arduinoUsb.ConnectionFailed += message => { Log.Error("USB connection failed: " + message); }; this.arduinoUsb.ConnectionLost += message => { Log.Error("USB connection lost: " + message); }; this.arduinoUsb.begin(57600, SerialConfig.SERIAL_8N1); } this.deviceId = await RuntimeSettings.GetAsync("DeviceId", string.Empty); if (string.IsNullOrEmpty(this.deviceId)) { this.deviceId = Guid.NewGuid().ToString().Replace("-", string.Empty); await RuntimeSettings.SetAsync("DeviceId", this.deviceId); } Log.Informational("Device ID: " + this.deviceId); /************************************************************************************ * To create an unencrypted CoAP Endpoint on the default CoAP port: * * this.coapEndpoint = new CoapEndpoint(); * * To create an unencrypted CoAP Endpoint on the default CoAP port, * with a sniffer that outputs communication to the window: * * this.coapEndpoint = new CoapEndpoint(new LogSniffer()); * * To create a DTLS encrypted CoAP endpoint, on the default CoAPS port, using * the users defined in the IUserSource users: * * this.coapEndpoint = new CoapEndpoint(CoapEndpoint.DefaultCoapsPort, this.users); * * To create a CoAP endpoint, that listens to both the default CoAP port, for * unencrypted communication, and the default CoAPS port, for encrypted, * authenticated and authorized communication, using * the users defined in the IUserSource users. Only users having the given * privilege (if not empty) will be authorized to access resources on the endpoint: * * this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, * new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, "PRIVILEGE", false, false); * ************************************************************************************/ this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, string.Empty, false, false); this.lightResource = this.coapEndpoint.Register("/Light", (req, resp) => { string s; if (this.lastLight.HasValue) { s = ToString(this.lastLight.Value, 2) + " %"; } else { s = "-"; } resp.Respond(CoapCode.Content, s, 64); }, Notifications.Unacknowledged, "Light, in %.", null, null, new int[] { PlainText.ContentFormatCode }); this.lightResource?.TriggerAll(new TimeSpan(0, 0, 5)); this.motionResource = this.coapEndpoint.Register("/Motion", (req, resp) => { string s; if (this.lastMotion.HasValue) { s = this.lastMotion.Value ? "true" : "false"; } else { s = "-"; } resp.Respond(CoapCode.Content, s, 64); }, Notifications.Acknowledged, "Motion detector.", null, null, new int[] { PlainText.ContentFormatCode }); this.motionResource?.TriggerAll(new TimeSpan(0, 1, 0)); this.momentaryResource = this.coapEndpoint.Register("/Momentary", (req, resp) => { if (req.IsAcceptable(Xml.ContentFormatCode)) { this.ReturnMomentaryAsXml(req, resp); } else if (req.IsAcceptable(Json.ContentFormatCode)) { this.ReturnMomentaryAsJson(req, resp); } else if (req.IsAcceptable(PlainText.ContentFormatCode)) { this.ReturnMomentaryAsPlainText(req, resp); } else if (req.Accept.HasValue) { throw new CoapException(CoapCode.NotAcceptable); } else { this.ReturnMomentaryAsPlainText(req, resp); } }, Notifications.Acknowledged, "Momentary values.", null, null, new int[] { Xml.ContentFormatCode, Json.ContentFormatCode, PlainText.ContentFormatCode }); this.momentaryResource?.TriggerAll(new TimeSpan(0, 0, 5)); } catch (Exception ex) { Log.Emergency(ex); MessageDialog Dialog = new MessageDialog(ex.Message, "Error"); await MainPage.Instance.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => await Dialog.ShowAsync()); } }
public void TestInitialize() { this.SetupClientServer(); this.server.Register("/test", (req, resp) => { resp.Respond(CoapCode.Content, ResponseTest, 64); }, Notifications.None, "Default test resource"); this.server.Register("/", (req, resp) => { resp.Respond(CoapCode.Content, ResponseRoot, 64); }); this.server.Register("/separate", (req, resp) => { Task.Run(() => { Thread.Sleep(2000); resp.Respond(CoapCode.Content, ResponseTest, 64); }); }, Notifications.None, "Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way."); this.server.Register("/seg1", (req, resp) => { resp.Respond(CoapCode.Content, ResponseTest, 64); }, Notifications.None, "Long path resource"); this.server.Register("/seg1/seg2", (req, resp) => { resp.Respond(CoapCode.Content, ResponseTest, 64); }, Notifications.None, "Long path resource"); this.server.Register("/seg1/seg2/seg3", (req, resp) => { resp.Respond(CoapCode.Content, ResponseTest, 64); }, Notifications.None, "Long path resource"); this.server.Register("/large", (req, resp) => { resp.Respond(CoapCode.Content, ResponseLarge, 64); }, Notifications.None, "Large resource", new string[] { "block" }, null, null, 1280); this.server.Register("/large-separate", (req, resp) => { Task.Run(() => { Thread.Sleep(2000); resp.Respond(CoapCode.Content, ResponseLarge, 64); }); }, Notifications.None, "Large resource", new string[] { "block" }, null, null, 1280); this.server.Register("/multi-format", (req, resp) => { if (req.IsAcceptable(PlainText.ContentFormatCode)) { resp.Respond(CoapCode.Content, ResponseTest, 64); } else if (req.IsAcceptable(Xml.ContentFormatCode)) { resp.Respond(CoapCode.Content, "<text>" + ResponseTest + "</text>", 64, new CoapOptionContentFormat(Xml.ContentFormatCode)); } else { throw new CoapException(CoapCode.NotAcceptable); } }, Notifications.None, "Resource that exists in different content formats (text/plain utf8 and application/xml)", null, null, new int[] { PlainText.ContentFormatCode, Xml.ContentFormatCode }); this.server.Register("/path", (req, resp) => { resp.Respond(CoapCode.Content, ResponseHierarchical, 64, new CoapOptionContentFormat(CoreLinkFormat.ContentFormatCode)); }, Notifications.None, "Hierarchical link description entry", null, null, new int[] { CoreLinkFormat.ContentFormatCode }); this.server.Register("/path/sub1", (req, resp) => { resp.Respond(CoapCode.Content, "/path/sub1", 64); }, Notifications.None, "Hierarchical link description sub-resource"); this.server.Register("/path/sub2", (req, resp) => { resp.Respond(CoapCode.Content, "/path/sub2", 64); }, Notifications.None, "Hierarchical link description sub-resource"); this.server.Register("/path/sub3", (req, resp) => { resp.Respond(CoapCode.Content, "/path/sub3", 64); }, Notifications.None, "Hierarchical link description sub-resource"); this.server.Register("/query", (req, resp) => { StringBuilder sb = new StringBuilder(); bool First = true; foreach (CoapOption Option in req.Options) { if (Option is CoapOptionUriQuery Query) { if (First) { First = false; sb.Append('?'); } else { sb.Append('&'); } sb.Append(Query.Key); sb.Append('='); sb.Append(Query.KeyValue); } } resp.Respond(CoapCode.Content, sb.ToString(), 64); }, Notifications.None, "Resource accepting query parameters"); CoapResource Obs = this.server.Register("/obs", (req, resp) => { resp.Respond(CoapCode.Content, DateTime.Now.ToString("T"), 64); }, Notifications.Acknowledged, "Observable resource which changes every 5 seconds", new string[] { "observe" }); Obs.TriggerAll(new TimeSpan(0, 0, 5)); Obs = this.server.Register("/obs-large", (req, resp) => { string s = DateTime.Now.ToString("T"); int i = 61 - s.Length; s = '|' + new string(' ', i / 2) + s + new string(' ', i - (i / 2)) + "|\r\n"; string Response = "/-------------------------------------------------------------\\\r\n" + s + "\\-------------------------------------------------------------/\r\n"; resp.Respond(CoapCode.Content, Response, 64); }, Notifications.Acknowledged, "Observable resource which changes every 5 seconds", new string[] { "observe" }); Obs.TriggerAll(new TimeSpan(0, 0, 5)); Obs = this.server.Register("/obs-non", (req, resp) => { resp.Respond(CoapCode.Content, DateTime.Now.ToString("T"), 64); }, Notifications.Unacknowledged, "Observable resource which changes every 5 seconds", new string[] { "observe" }); Obs.TriggerAll(new TimeSpan(0, 0, 5)); Obs = this.server.Register("/obs-pumping", (req, resp) => { resp.Respond(CoapCode.Content, DateTime.Now.ToString("T"), 64); }, Notifications.Acknowledged, "Observable resource which changes every 5 seconds", new string[] { "observe" }); Obs.TriggerAll(new TimeSpan(0, 0, 5)); Obs = this.server.Register("/obs-pumping-non", (req, resp) => { resp.Respond(CoapCode.Content, DateTime.Now.ToString("T"), 64); }, Notifications.Unacknowledged, "Observable resource which changes every 5 seconds", new string[] { "observe" }); Obs.TriggerAll(new TimeSpan(0, 0, 5)); this.server.Register("/location-query", null, (req, resp) => { resp.Respond(CoapCode.Content, req.Payload, 64); }, Notifications.None, "Perform POST transaction with responses containing several Location-Query options (CON mode)"); this.server.Register("/large-create", null, (req, resp) => { resp.Respond(CoapCode.Created, req.Payload, 64); }, Notifications.None, "Large resource that can be created using POST method", new string[] { "block" }, null, new int[] { 0 }, 2000); this.server.Register("/large-post", null, (req, resp) => { resp.Respond(CoapCode.Content, req.Payload, 64); }, Notifications.None, "Handle POST with two-way blockwise transfer", new string[] { "block" }); this.server.Register(new LargeUpdate()); }
private async void Init() { try { Log.Informational("Starting application."); Types.Initialize( typeof(FilesProvider).GetTypeInfo().Assembly, typeof(RuntimeSettings).GetTypeInfo().Assembly, typeof(IContentEncoder).GetTypeInfo().Assembly, typeof(ICoapContentFormat).GetTypeInfo().Assembly, typeof(IDtlsCredentials).GetTypeInfo().Assembly, typeof(Lwm2mClient).GetTypeInfo().Assembly, typeof(App).GetTypeInfo().Assembly); Database.Register(new FilesProvider(Windows.Storage.ApplicationData.Current.LocalFolder.Path + Path.DirectorySeparatorChar + "Data", "Default", 8192, 1000, 8192, Encoding.UTF8, 10000)); #if GPIO gpio = GpioController.GetDefault(); if (gpio != null) { if (gpio.TryOpenPin(gpioOutputPin, GpioSharingMode.Exclusive, out this.gpioPin, out GpioOpenStatus Status) && Status == GpioOpenStatus.PinOpened) { if (this.gpioPin.IsDriveModeSupported(GpioPinDriveMode.Output)) { this.gpioPin.SetDriveMode(GpioPinDriveMode.Output); this.output = await RuntimeSettings.GetAsync("Actuator.Output", false); this.gpioPin.Write(this.output.Value ? GpioPinValue.High : GpioPinValue.Low); this.digitalOutput0?.Set(this.output.Value); this.actuation0?.Set(this.output.Value); await MainPage.Instance.OutputSet(this.output.Value); Log.Informational("Setting Control Parameter.", string.Empty, "Startup", new KeyValuePair <string, object>("Output", this.output.Value)); } else { Log.Error("Output mode not supported for GPIO pin " + gpioOutputPin.ToString()); } } else { Log.Error("Unable to get access to GPIO pin " + gpioOutputPin.ToString()); } } #else DeviceInformationCollection Devices = await UsbSerial.listAvailableDevicesAsync(); foreach (DeviceInformation DeviceInfo in Devices) { if (DeviceInfo.IsEnabled && DeviceInfo.Name.StartsWith("Arduino")) { Log.Informational("Connecting to " + DeviceInfo.Name); this.arduinoUsb = new UsbSerial(DeviceInfo); this.arduinoUsb.ConnectionEstablished += () => Log.Informational("USB connection established."); this.arduino = new RemoteDevice(this.arduinoUsb); this.arduino.DeviceReady += async() => { try { Log.Informational("Device ready."); this.arduino.pinMode(13, PinMode.OUTPUT); // Onboard LED. this.arduino.digitalWrite(13, PinState.HIGH); this.arduino.pinMode(8, PinMode.INPUT); // PIR sensor (motion detection). this.arduino.pinMode(9, PinMode.OUTPUT); // Relay. this.output = await RuntimeSettings.GetAsync("Actuator.Output", false); this.arduino.digitalWrite(9, this.output.Value ? PinState.HIGH : PinState.LOW); this.digitalOutput0?.Set(this.output.Value); this.actuation0?.Set(this.output.Value); await MainPage.Instance.OutputSet(this.output.Value); Log.Informational("Setting Control Parameter.", string.Empty, "Startup", new KeyValuePair <string, object>("Output", this.output.Value)); this.arduino.pinMode("A0", PinMode.ANALOG); // Light sensor. } catch (Exception ex) { Log.Critical(ex); } }; this.arduinoUsb.ConnectionFailed += message => { Log.Error("USB connection failed: " + message); }; this.arduinoUsb.ConnectionLost += message => { Log.Error("USB connection lost: " + message); }; this.arduinoUsb.begin(57600, SerialConfig.SERIAL_8N1); break; } } #endif this.deviceId = await RuntimeSettings.GetAsync("DeviceId", string.Empty); if (string.IsNullOrEmpty(this.deviceId)) { this.deviceId = Guid.NewGuid().ToString().Replace("-", string.Empty); await RuntimeSettings.SetAsync("DeviceId", this.deviceId); } Log.Informational("Device ID: " + this.deviceId); /************************************************************************************ * To create an unencrypted CoAP Endpoint on the default CoAP port: * * this.coapEndpoint = new CoapEndpoint(); * * To create an unencrypted CoAP Endpoint on the default CoAP port, * with a sniffer that outputs communication to the window: * * this.coapEndpoint = new CoapEndpoint(new LogSniffer()); * * To create a DTLS encrypted CoAP endpoint, on the default CoAPS port, using * the users defined in the IUserSource users: * * this.coapEndpoint = new CoapEndpoint(CoapEndpoint.DefaultCoapsPort, this.users); * * To create a CoAP endpoint, that listens to both the default CoAP port, for * unencrypted communication, and the default CoAPS port, for encrypted, * authenticated and authorized communication, using * the users defined in the IUserSource users. Only users having the given * privilege (if not empty) will be authorized to access resources on the endpoint: * * this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, * new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, "PRIVILEGE", false, false); * ************************************************************************************/ this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, string.Empty, false, false); this.outputResource = this.coapEndpoint.Register("/Output", (req, resp) => { string s; if (this.output.HasValue) { s = this.output.Value ? "true" : "false"; } else { s = "-"; } resp.Respond(CoapCode.Content, s, 64); }, async(req, resp) => { try { string s = req.Decode() as string; if (s == null && req.Payload != null) { s = Encoding.UTF8.GetString(req.Payload); } if (s == null || !CommonTypes.TryParse(s, out bool Output)) { resp.RST(CoapCode.BadRequest); } else { resp.Respond(CoapCode.Changed); await this.SetOutput(Output, req.From.ToString()); } } catch (Exception ex) { Log.Critical(ex); } }, Notifications.Acknowledged, "Digital Output.", null, null, new int[] { PlainText.ContentFormatCode }); this.outputResource?.TriggerAll(new TimeSpan(0, 1, 0)); this.lwm2mClient = new Lwm2mClient("MIoT:Actuator:" + this.deviceId, this.coapEndpoint, new Lwm2mSecurityObject(), new Lwm2mServerObject(), new Lwm2mAccessControlObject(), new Lwm2mDeviceObject("Waher Data AB", "ActuatorLwm2m", this.deviceId, "1.0", "Actuator", "1.0", "1.0"), new DigitalOutput(this.digitalOutput0 = new DigitalOutputInstance(0, this.output.HasValue && this.output.Value, "Relay")), new Actuation(this.actuation0 = new ActuationInstance(0, this.output.HasValue && this.output.Value, "Relay"))); this.digitalOutput0.OnRemoteUpdate += async(Sender, e) => { try { await this.SetOutput(((DigitalOutputInstance)Sender).Value, e.Request.From.ToString()); } catch (Exception ex) { Log.Critical(ex); } }; this.actuation0.OnRemoteUpdate += async(Sender, e) => { try { await this.SetOutput(((ActuationInstance)Sender).Value, e.Request.From.ToString()); } catch (Exception ex) { Log.Critical(ex); } }; await this.lwm2mClient.LoadBootstrapInfo(); this.lwm2mClient.OnStateChanged += (sender, e) => { Log.Informational("LWM2M state changed to " + this.lwm2mClient.State.ToString() + "."); }; this.lwm2mClient.OnBootstrapCompleted += (sender, e) => { Log.Informational("Bootstrap procedure completed."); }; this.lwm2mClient.OnBootstrapFailed += (sender, e) => { Log.Error("Bootstrap procedure failed."); this.coapEndpoint.ScheduleEvent(async(P) => { try { await this.RequestBootstrap(); } catch (Exception ex) { Log.Critical(ex); } }, DateTime.Now.AddMinutes(15), null); }; this.lwm2mClient.OnRegistrationSuccessful += (sender, e) => { Log.Informational("Server registration completed."); }; this.lwm2mClient.OnRegistrationFailed += (sender, e) => { Log.Error("Server registration failed."); }; this.lwm2mClient.OnDeregistrationSuccessful += (sender, e) => { Log.Informational("Server deregistration completed."); }; this.lwm2mClient.OnDeregistrationFailed += (sender, e) => { Log.Error("Server deregistration failed."); }; this.lwm2mClient.OnRebootRequest += async(sender, e) => { Log.Warning("Reboot is requested."); try { await this.RequestBootstrap(); } catch (Exception ex) { Log.Critical(ex); } }; await this.RequestBootstrap(); } catch (Exception ex) { Log.Emergency(ex); MessageDialog Dialog = new MessageDialog(ex.Message, "Error"); await MainPage.Instance.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => await Dialog.ShowAsync()); } }
private async void Init() { try { Log.Informational("Starting application."); Types.Initialize( typeof(FilesProvider).GetTypeInfo().Assembly, typeof(RuntimeSettings).GetTypeInfo().Assembly, typeof(IContentEncoder).GetTypeInfo().Assembly, typeof(ICoapContentFormat).GetTypeInfo().Assembly, typeof(IDtlsCredentials).GetTypeInfo().Assembly, typeof(Lwm2mClient).GetTypeInfo().Assembly, typeof(App).GetTypeInfo().Assembly); Database.Register(new FilesProvider(Windows.Storage.ApplicationData.Current.LocalFolder.Path + Path.DirectorySeparatorChar + "Data", "Default", 8192, 1000, 8192, Encoding.UTF8, 10000)); DeviceInformationCollection Devices = await UsbSerial.listAvailableDevicesAsync(); foreach (DeviceInformation DeviceInfo in Devices) { if (DeviceInfo.IsEnabled && DeviceInfo.Name.StartsWith("Arduino")) { Log.Informational("Connecting to " + DeviceInfo.Name); this.arduinoUsb = new UsbSerial(DeviceInfo); this.arduinoUsb.ConnectionEstablished += () => Log.Informational("USB connection established."); this.arduino = new RemoteDevice(this.arduinoUsb); this.arduino.DeviceReady += () => { Log.Informational("Device ready."); this.arduino.pinMode(13, PinMode.OUTPUT); // Onboard LED. this.arduino.digitalWrite(13, PinState.HIGH); this.arduino.pinMode(0, PinMode.INPUT); // PIR sensor (motion detection). PinState Pin0 = this.arduino.digitalRead(0); this.lastMotion = Pin0 == PinState.HIGH; MainPage.Instance.DigitalPinUpdated(0, Pin0); this.arduino.pinMode(1, PinMode.OUTPUT); // Relay. this.arduino.digitalWrite(1, 0); // Relay set to 0 this.arduino.pinMode("A0", PinMode.ANALOG); // Light sensor. MainPage.Instance.AnalogPinUpdated("A0", this.arduino.analogRead("A0")); this.sampleTimer = new Timer(this.SampleValues, null, 1000 - DateTime.Now.Millisecond, 1000); }; this.arduino.AnalogPinUpdated += (pin, value) => { MainPage.Instance.AnalogPinUpdated(pin, value); }; this.arduino.DigitalPinUpdated += (pin, value) => { MainPage.Instance.DigitalPinUpdated(pin, value); if (pin == 0) { bool Input = (value == PinState.HIGH); this.lastMotion = Input; this.digitalInput0?.Set(Input); this.presenceSensor0?.Set(Input); this.genericSensor0?.Set(Input ? 1.0 : 0.0); this.motionResource?.TriggerAll(); this.momentaryResource?.TriggerAll(); } }; this.arduinoUsb.ConnectionFailed += message => { Log.Error("USB connection failed: " + message); }; this.arduinoUsb.ConnectionLost += message => { Log.Error("USB connection lost: " + message); }; this.arduinoUsb.begin(57600, SerialConfig.SERIAL_8N1); break; } } this.deviceId = await RuntimeSettings.GetAsync("DeviceId", string.Empty); if (string.IsNullOrEmpty(this.deviceId)) { this.deviceId = Guid.NewGuid().ToString().Replace("-", string.Empty); await RuntimeSettings.SetAsync("DeviceId", this.deviceId); } Log.Informational("Device ID: " + this.deviceId); /************************************************************************************ * To create an unencrypted CoAP Endpoint on the default CoAP port: * * this.coapEndpoint = new CoapEndpoint(); * * To create an unencrypted CoAP Endpoint on the default CoAP port, * with a sniffer that outputs communication to the window: * * this.coapEndpoint = new CoapEndpoint(new LogSniffer()); * * To create a DTLS encrypted CoAP endpoint, on the default CoAPS port, using * the users defined in the IUserSource users: * * this.coapEndpoint = new CoapEndpoint(CoapEndpoint.DefaultCoapsPort, this.users); * * To create a CoAP endpoint, that listens to both the default CoAP port, for * unencrypted communication, and the default CoAPS port, for encrypted, * authenticated and authorized communication, using * the users defined in the IUserSource users. Only users having the given * privilege (if not empty) will be authorized to access resources on the endpoint: * * this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, * new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, "PRIVILEGE", false, false); * ************************************************************************************/ //this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, // new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, string.Empty, false, false); this.coapEndpoint = new CoapEndpoint(new int[] { 5783 }, new int[] { 5784 }, null, null, false, false); this.lightResource = this.coapEndpoint.Register("/Light", (req, resp) => { string s; if (this.lastLight.HasValue) { s = ToString(this.lastLight.Value, 2) + " %"; } else { s = "-"; } resp.Respond(CoapCode.Content, s, 64); }, Notifications.Unacknowledged, "Light, in %.", null, null, new int[] { PlainText.ContentFormatCode }); this.lightResource?.TriggerAll(new TimeSpan(0, 0, 5)); this.motionResource = this.coapEndpoint.Register("/Motion", (req, resp) => { string s; if (this.lastMotion.HasValue) { s = this.lastMotion.Value ? "true" : "false"; } else { s = "-"; } resp.Respond(CoapCode.Content, s, 64); }, Notifications.Acknowledged, "Motion detector.", null, null, new int[] { PlainText.ContentFormatCode }); this.motionResource?.TriggerAll(new TimeSpan(0, 1, 0)); this.momentaryResource = this.coapEndpoint.Register("/Momentary", (req, resp) => { if (req.IsAcceptable(Xml.ContentFormatCode)) { this.ReturnMomentaryAsXml(req, resp); } else if (req.IsAcceptable(Json.ContentFormatCode)) { this.ReturnMomentaryAsJson(req, resp); } else if (req.IsAcceptable(PlainText.ContentFormatCode)) { this.ReturnMomentaryAsPlainText(req, resp); } else if (req.Accept.HasValue) { throw new CoapException(CoapCode.NotAcceptable); } else { this.ReturnMomentaryAsPlainText(req, resp); } }, Notifications.Acknowledged, "Momentary values.", null, null, new int[] { Xml.ContentFormatCode, Json.ContentFormatCode, PlainText.ContentFormatCode }); this.momentaryResource?.TriggerAll(new TimeSpan(0, 0, 5)); this.lwm2mClient = new Lwm2mClient("MIoT:Sensor:" + this.deviceId, this.coapEndpoint, new Lwm2mSecurityObject(), new Lwm2mServerObject(), new Lwm2mAccessControlObject(), new Lwm2mDeviceObject("Waher Data AB", "SensorLwm2m", this.deviceId, "1.0", "Sensor", "1.0", "1.0"), new DigitalInput(this.digitalInput0 = new DigitalInputInstance(0, this.lastMotion, "Motion Detector", "PIR")), new AnalogInput(this.analogInput0 = new AnalogInputInstance(0, this.lastLight, 0, 100, "Ambient Light Sensor", "%")), new GenericSensor(this.genericSensor0 = new GenericSensorInstance(0, null, string.Empty, 0, 1, "Motion Detector", "PIR"), this.genericSensor1 = new GenericSensorInstance(1, this.lastLight, "%", 0, 100, "Ambient Light Sensor", "%")), new IlluminanceSensor(this.illuminanceSensor0 = new IlluminanceSensorInstance(0, this.lastLight, "%", 0, 100)), new PresenceSensor(this.presenceSensor0 = new PresenceSensorInstance(0, this.lastMotion, "PIR")), new PercentageSensor(this.percentageSensor0 = new PercentageSensorInstance(0, this.lastLight, 0, 100, "Ambient Light Sensor"))); await this.lwm2mClient.LoadBootstrapInfo(); this.lwm2mClient.OnStateChanged += (sender, e) => { Log.Informational("LWM2M state changed to " + this.lwm2mClient.State.ToString() + "."); }; this.lwm2mClient.OnBootstrapCompleted += (sender, e) => { Log.Informational("Bootstrap procedure completed."); }; this.lwm2mClient.OnBootstrapFailed += (sender, e) => { Log.Error("Bootstrap procedure failed."); this.coapEndpoint.ScheduleEvent(async(P) => { try { await this.RequestBootstrap(); } catch (Exception ex) { Log.Critical(ex); } }, DateTime.Now.AddMinutes(15), null); }; this.lwm2mClient.OnRegistrationSuccessful += (sender, e) => { Log.Informational("Server registration completed."); }; this.lwm2mClient.OnRegistrationFailed += (sender, e) => { Log.Error("Server registration failed."); }; this.lwm2mClient.OnDeregistrationSuccessful += (sender, e) => { Log.Informational("Server deregistration completed."); }; this.lwm2mClient.OnDeregistrationFailed += (sender, e) => { Log.Error("Server deregistration failed."); }; this.lwm2mClient.OnRebootRequest += async(sender, e) => { Log.Warning("Reboot is requested."); try { await this.RequestBootstrap(); } catch (Exception ex) { Log.Critical(ex); } }; await this.RequestBootstrap(); } catch (Exception ex) { Log.Emergency(ex); MessageDialog Dialog = new MessageDialog(ex.Message, "Error"); await MainPage.Instance.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => await Dialog.ShowAsync()); } }
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=sensor.db;Version=3;"; DB.BackupProviderName = "Clayster.Library.Data.Providers.SQLiteServer.SQLiteServerProvider"; db = DB.GetDatabaseProxy ("TheSensor"); Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => { e.Cancel = true; executionLed.Low (); }; // Initializing hardware and retrieving current sensor values try { tmp102.Configure (false, TexasInstrumentsTMP102.FaultQueue.ConsecutiveFaults_6, TexasInstrumentsTMP102.AlertPolarity.AlertActiveLow, TexasInstrumentsTMP102.ThermostatMode.ComparatorMode, false, TexasInstrumentsTMP102.ConversionRate.Hz_1, false); temp = (short)tmp102.ReadTemperatureRegister (); temperatureC = temp / 256.0; for (int i = 0; i < 10; i++) tempAvgWindow [i] = temp; sumTemp = temp * 10; } catch (Exception ex) { Log.Exception (ex); sumTemp = 0; temperatureC = 0; errorLed.High (); } try { adc.Configure (true, false, false, false, false, false); light = adc.ReadRegistersBinary () [0]; lightPercent = (100.0 * light) / 0x0fff; for (int i = 0; i < 10; i++) lightAvgWindow [i] = light; sumLight = light * 10; } catch (Exception ex) { Log.Exception (ex); sumLight = 0; lightPercent = 0; errorLed.High (); } // Loading historical Sensor Values Log.Information ("Loading Minute Values."); perMinute.AddRange (Record.LoadRecords (Rank.Minute)); Log.Information ("Loading Hour Values."); perHour.AddRange (Record.LoadRecords (Rank.Hour)); Log.Information ("Loading Day Values."); perDay.AddRange (Record.LoadRecords (Rank.Day)); Log.Information ("Loading Month Values."); perMonth.AddRange (Record.LoadRecords (Rank.Month)); // Resuming average calculations int Pos = perSecond.Count; DateTime CurrentTime = DateTime.Now; DateTime Timestamp; while (Pos-- > 0) { Record Rec = perSecond [Pos]; Timestamp = Rec.Timestamp; if (Timestamp.Minute == CurrentTime.Minute && Timestamp.Hour == CurrentTime.Hour && Timestamp.Date == CurrentTime.Date) { sumSeconds += Rec; nrSeconds++; } else break; } Pos = perMinute.Count; while (Pos-- > 0) { Record Rec = perMinute [Pos]; Timestamp = Rec.Timestamp; if (Timestamp.Hour == CurrentTime.Hour && Timestamp.Date == CurrentTime.Date) { sumMinutes += Rec; nrMinutes++; } else break; } Pos = perHour.Count; while (Pos-- > 0) { Record Rec = perHour [Pos]; Timestamp = Rec.Timestamp; if (Timestamp.Date == CurrentTime.Date) { sumHours += Rec; nrHours++; } else break; } Pos = perDay.Count; while (Pos-- > 0) { Record Rec = perDay [Pos]; Timestamp = Rec.Timestamp; if (Timestamp.Month == CurrentTime.Month && Timestamp.Year == CurrentTime.Year) { sumDays += Rec; nrDays++; } else break; } // Sampling of new Sensor Values Timer Timer = new Timer (SampleSensorValues, null, 1000 - DateTime.Now.Millisecond, 1000); // Every second. // HTTP Interface HttpServer HttpServer = new HttpServer (80, 10, true, true, 1); Log.Information ("HTTP Server receiving requests on port " + HttpServer.Port.ToString ()); HttpServer.RegisterAuthenticationMethod (new DigestAuthentication ("The Sensor Realm", GetDigestUserPasswordHash)); HttpServer.RegisterAuthenticationMethod (new SessionAuthentication ()); credentials = LoginCredentials.LoadCredentials (); if (credentials == null) { credentials = new LoginCredentials (); credentials.UserName = "******"; credentials.PasswordHash = CalcHash ("Admin", "Password"); credentials.SaveNew (); } HttpServer.Register ("/", HttpGetRoot, HttpPostRoot, false); // Synchronous, no authentication HttpServer.Register ("/html", HttpGetHtml, false); // Synchronous, no authentication HttpServer.Register ("/historygraph", HttpGetHistoryGraph, false); // Synchronous, no authentication HttpServer.Register ("/credentials", HttpGetCredentials, HttpPostCredentials, false); // Synchronous, no 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 ("/event/xml", HttpGetEventXml, true, false); // Asynchronous, http authentication HttpServer.Register ("/event/json", HttpGetEventJson, true, false); // Asynchronous, http authentication HttpServer.Register ("/event/turtle", HttpGetEventTurtle, true, false); // Asynchronous, http authentication HttpServer.Register ("/event/rdf", HttpGetEventRdf, true, false); // Asynchronous, http authentication // 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 Sensor Realm", GetDigestUserPasswordHash)); // HttpsServer.RegisterAuthenticationMethod (new SessionAuthentication ()); // // 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)); CoapEndpoint.RegisterResource ("temp/txt", "Current Temperature, as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, true, (Request, Payload) => { return FieldNumeric.Format (temperatureC, "C", 1); }); motionTxt = CoapEndpoint.RegisterResource ("motion/txt", "Motion detection, as text.", CoapBlockSize.BlockLimit_64Bytes, false, 10, true, (Request, Payload) => { return motionDetected ? "1" : "0"; }); CoapEndpoint.RegisterResource ("light/txt", "Current Light Density, as text.", CoapBlockSize.BlockLimit_64Bytes, false, 2, true, (Request, Payload) => { return FieldNumeric.Format (lightPercent, "%", 1); }); 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 mqttThread = new Thread (MqttThread); mqttThread.Name = "MQTT"; mqttThread.Priority = ThreadPriority.BelowNormal; mqttThread.Start (); // Main loop Log.Information ("Initialization complete. Application started..."); try { while (executionLed.Value) { System.Threading.Thread.Sleep (1000); } } catch (Exception ex) { Log.Exception (ex); executionLed.Low (); } finally { Log.Information ("Terminating application."); Log.Flush (); Log.Terminate (); Timer.Dispose (); HttpServer.Dispose (); //HttpsServer.Dispose (); CoapEndpoint.Dispose (); if (mqttThread != null) { mqttThread.Abort (); mqttThread = null; } executionLed.Dispose (); measurementLed.Dispose (); errorLed.Dispose (); networkLed.Dispose (); motion.Dispose (); i2cBus.Dispose (); } return 0; }