/// <summary> /// This function is here to allow setting the harvesterState to specific values for all rows matching the queryWhere condition /// </summary> private void BatchUpdateStates() { IEnumerable <BookModel> bookList = _parseClient.GetBooks(out bool didExitPrematurely, _options.QueryWhere); if (didExitPrematurely) { _logger.LogError("GetBooks() encountered an error and did not return all results. Aborting."); return; } foreach (var bookModel in bookList) { _logger.LogInfo($"Updating objectId {bookModel.ObjectId} from {bookModel.HarvestState} to {NewState}"); string newStateStr = ""; if (NewState != HarvestState.Unknown) { newStateStr = NewState.ToString(); } if (!IsDryRun) { bookModel.HarvestState = newStateStr; bookModel.FlushUpdateToDatabase(_parseClient); } } _logger.LogInfo($"{bookList.Count()} objects processed."); if (IsDryRun) { _logger.LogInfo("Dry run done. (No updates were actually made)"); } }
public override string ToString() { string state = ChangeState ? NewState.ToString() : "None"; string value = ChangeValue ? NewValue.ToString() : "None"; return($"{state}, {value}, {ReaderStep}"); }
public void CalculateNewTaxRate() { decimal result; string state = NewState.ToString(); TaxRate rate = TaxRateRepo.TaxRateList.Find(x => x.StateAbbreviation.Contains(state)); result = rate.Rate; NewTaxRate = result; }
public void SensorData_Test_05_Subscribe_ChangeDown() { this.ConnectClients(); try { ManualResetEvent Done = new ManualResetEvent(false); ManualResetEvent Error = new ManualResetEvent(false); IEnumerable <Field> Fields = null; SensorDataSubscriptionRequest Request = this.sensorClient.Subscribe(this.client2.FullJID, FieldType.All, new FieldSubscriptionRule[] { new FieldSubscriptionRule("Temperature", this.temp, 1, null) }, Duration.Parse("PT1S"), Duration.Parse("PT5S"), false); Request.OnStateChanged += (sender, NewState) => { Console.Out.WriteLine(NewState.ToString()); return(Task.CompletedTask); }; Request.OnErrorsReceived += (sender, Errors) => { Error.Set(); return(Task.CompletedTask); }; Request.OnFieldsReceived += (sender, NewFields) => { Fields = NewFields; Done.Set(); return(Task.CompletedTask); }; this.temp += 1; this.sensorServer.NewMomentaryValues(new QuantityField(ThingReference.Empty, DateTime.Now, "Temperature", this.temp, 1, "C", FieldType.Momentary, FieldQoS.AutomaticReadout)); Thread.Sleep(2000); this.temp -= 2; this.sensorServer.NewMomentaryValues(new QuantityField(ThingReference.Empty, DateTime.Now, "Temperature", this.temp, 1, "C", FieldType.Momentary, FieldQoS.AutomaticReadout)); Assert.AreEqual(0, WaitHandle.WaitAny(new WaitHandle[] { Done, Error }, 10000), "Subscription not performed correctly"); foreach (Field Field in Fields) { Console.Out.WriteLine(Field.ToString()); } } finally { this.DisposeClients(); } }
public void SensorData_Test_01_ReadAll() { this.ConnectClients(); try { ManualResetEvent Done = new ManualResetEvent(false); ManualResetEvent Error = new ManualResetEvent(false); IEnumerable <Field> Fields = null; SensorDataClientRequest Request = this.sensorClient.RequestReadout(this.client2.FullJID, FieldType.All); Request.OnStateChanged += (sender, NewState) => { Console.Out.WriteLine(NewState.ToString()); return(Task.CompletedTask); }; Request.OnErrorsReceived += (sender, Errors) => { Error.Set(); return(Task.CompletedTask); }; Request.OnFieldsReceived += (sender, NewFields) => { Fields = NewFields; Done.Set(); return(Task.CompletedTask); }; Assert.AreEqual(0, WaitHandle.WaitAny(new WaitHandle[] { Done, Error }, 20000), "Readout not performed correctly"); foreach (Field Field in Fields) { Console.Out.WriteLine(Field.ToString()); } } finally { this.DisposeClients(); } }
private async void StartSensor() { try { Log.Informational("Starting application."); XmppCredentials Credentials = SimpleXmppConfiguration.GetConfigUsingSimpleConsoleDialog("xmpp.config", Guid.NewGuid().ToString().Replace("-", string.Empty), // Default user name. Guid.NewGuid().ToString().Replace("-", string.Empty), // Default password. typeof(App).GetTypeInfo().Assembly); Log.Informational("Connecting to XMPP server."); xmppClient = new XmppClient(Credentials, "en", typeof(App).GetTypeInfo().Assembly); if (Credentials.Sniffer && MainPage.Sniffer != null) { xmppClient.Add(MainPage.Sniffer); } if (!string.IsNullOrEmpty(Credentials.Events)) { Log.Register(new XmppEventSink("XMPP Event Sink", xmppClient, Credentials.Events, false)); } if (!string.IsNullOrEmpty(Credentials.ThingRegistry)) { thingRegistryClient = new ThingRegistryClient(xmppClient, Credentials.ThingRegistry); thingRegistryClient.Claimed += (sender, e) => { ownerJid = e.JID; Log.Informational("Thing has been claimed.", ownerJid, new KeyValuePair <string, object>("Public", e.IsPublic)); this.RaiseOwnershipChanged(); }; thingRegistryClient.Disowned += (sender, e) => { Log.Informational("Thing has been disowned.", ownerJid); ownerJid = string.Empty; this.Register(); // Will call this.OwnershipChanged() after successful registration. }; thingRegistryClient.Removed += (sender, e) => { Log.Informational("Thing has been removed from the public registry.", ownerJid); }; } if (!string.IsNullOrEmpty(Credentials.Provisioning)) { provisioningClient = new ProvisioningClient(xmppClient, Credentials.Provisioning); } Timer ConnectionTimer = new Timer((P) => { if (xmppClient.State == XmppState.Offline || xmppClient.State == XmppState.Error || xmppClient.State == XmppState.Authenticating) { try { Log.Informational("Reconnecting."); xmppClient.Reconnect(); } catch (Exception ex) { Log.Critical(ex); } } }, null, 60000, 60000); xmppClient.OnStateChanged += (sender, NewState) => { Log.Informational(NewState.ToString()); switch (NewState) { case XmppState.Connected: connected = true; if (!registered && thingRegistryClient != null) { this.Register(); } break; case XmppState.Offline: immediateReconnect = connected; connected = false; if (immediateReconnect) { xmppClient.Reconnect(); } break; } }; xmppClient.OnPresenceSubscribe += (sender, e) => { Log.Informational("Subscription request received from " + e.From + "."); e.Accept(); // TODO: Provisioning RosterItem Item = xmppClient.GetRosterItem(e.FromBareJID); if (Item is null || Item.State == SubscriptionState.None || Item.State == SubscriptionState.From) { xmppClient.RequestPresenceSubscription(e.FromBareJID); } xmppClient.SetPresence(Availability.Chat); }; xmppClient.OnPresenceUnsubscribe += (sender, e) => { Log.Informational("Unsubscription request received from " + e.From + "."); e.Accept(); }; xmppClient.OnRosterItemUpdated += (sender, e) => { if (e.State == SubscriptionState.None && e.PendingSubscription != PendingSubscription.Subscribe) { xmppClient.RemoveRosterItem(e.BareJid); } }; LinkedList <DayHistoryRecord> DayHistoricalValues = new LinkedList <DayHistoryRecord>(); LinkedList <MinuteHistoryRecord> MinuteHistoricalValues = new LinkedList <MinuteHistoryRecord>(); DateTime SampleTime = DateTime.Now; DateTime PeriodStart = SampleTime.Date; DateTime Now; DateTime MinTime = SampleTime; DateTime MaxTime = SampleTime; double CurrentTemperature = this.ReadTemp(); double MinTemp = CurrentTemperature; double MaxTemp = CurrentTemperature; double SumTemp = CurrentTemperature; int NrTemp = 1; int NrDayRecords = 0; int NrMinuteRecords = 0; object SampleSynch = new object(); this.sampleTimer = new Timer((P) => { lock (SampleSynch) { Now = DateTime.Now; if (Now.Date != PeriodStart.Date) { DayHistoryRecord Rec = new DayHistoryRecord(PeriodStart.Date, PeriodStart.Date.AddDays(1).AddMilliseconds(-1), MinTemp, MaxTemp, SumTemp / NrTemp); DayHistoricalValues.AddFirst(Rec); if (NrDayRecords < MaxRecordsPerPeriod) { NrDayRecords++; } else { DayHistoricalValues.RemoveLast(); } // TODO: Persistence PeriodStart = Now.Date; SumTemp = 0; NrTemp = 0; } CurrentTemperature = this.ReadTemp(); if (Now.Minute != SampleTime.Minute) { MinuteHistoryRecord Rec = new MinuteHistoryRecord(Now, CurrentTemperature); MinuteHistoricalValues.AddFirst(Rec); if (NrMinuteRecords < MaxRecordsPerPeriod) { NrMinuteRecords++; } else { MinuteHistoricalValues.RemoveLast(); } // TODO: Persistence } SampleTime = Now; if (CurrentTemperature < MinTemp) { MinTemp = CurrentTemperature; MinTime = SampleTime; } if (CurrentTemperature > MaxTemp) { MaxTemp = CurrentTemperature; MaxTime = SampleTime; } SumTemp += CurrentTemperature; NrTemp++; } if (this.sensorServer.HasSubscriptions(ThingReference.Empty)) { this.sensorServer.NewMomentaryValues(new QuantityField(ThingReference.Empty, SampleTime, "Temperature", CurrentTemperature, 1, "°C", FieldType.Momentary, FieldQoS.AutomaticReadout)); } this.UpdateMainWindow(CurrentTemperature, MinTemp, MaxTemp, SumTemp / NrTemp); }, null, 1000 - PeriodStart.Millisecond, 1000); this.sensorServer = new SensorServer(xmppClient, provisioningClient, true); this.sensorServer.OnExecuteReadoutRequest += (Sender, Request) => { Log.Informational("Readout requested by " + Request.From, string.Empty, Request.Actor); List <Field> Fields = new List <Field>(); bool IncludeTemp = Request.IsIncluded("Temperature"); bool IncludeTempMin = Request.IsIncluded("Temperature, Min"); bool IncludeTempMax = Request.IsIncluded("Temperature, Max"); bool IncludeTempAvg = Request.IsIncluded("Temperature, Average"); bool IncludePeak = Request.IsIncluded(FieldType.Peak); bool IncludeComputed = Request.IsIncluded(FieldType.Computed); lock (SampleSynch) { if (IncludeTemp && Request.IsIncluded(FieldType.Momentary)) { Fields.Add(new QuantityField(ThingReference.Empty, SampleTime, "Temperature", CurrentTemperature, 1, "°C", FieldType.Momentary, FieldQoS.AutomaticReadout)); } if (IncludePeak) { if (IncludeTempMin) { Fields.Add(new QuantityField(ThingReference.Empty, MinTime, "Temperature, Min", MinTemp, 1, "°C", FieldType.Peak, FieldQoS.AutomaticReadout)); } if (IncludeTempMax) { Fields.Add(new QuantityField(ThingReference.Empty, MaxTime, "Temperature, Max", MaxTemp, 1, "°C", FieldType.Peak, FieldQoS.AutomaticReadout)); } } if (IncludeTempAvg && IncludeComputed) { Fields.Add(new QuantityField(ThingReference.Empty, SampleTime, "Temperature, Average", SumTemp / NrTemp, 2, "°C", FieldType.Computed, FieldQoS.AutomaticReadout)); } if (Request.IsIncluded(FieldType.Historical)) { foreach (DayHistoryRecord Rec in DayHistoricalValues) { if (!Request.IsIncluded(Rec.PeriodStart)) { continue; } if (Fields.Count >= 100) { Request.ReportFields(false, Fields); Fields.Clear(); } if (IncludePeak) { if (IncludeTempMin) { Fields.Add(new QuantityField(ThingReference.Empty, Rec.PeriodStart, "Temperature, Min", Rec.MinTemperature, 1, "°C", FieldType.Peak | FieldType.Historical, FieldQoS.AutomaticReadout)); } if (IncludeTempMax) { Fields.Add(new QuantityField(ThingReference.Empty, Rec.PeriodStart, "Temperature, Max", Rec.MaxTemperature, 1, "°C", FieldType.Peak | FieldType.Historical, FieldQoS.AutomaticReadout)); } } if (IncludeTempAvg && IncludeComputed) { Fields.Add(new QuantityField(ThingReference.Empty, Rec.PeriodStart, "Temperature, Average", Rec.AverageTemperature, 1, "°C", FieldType.Computed | FieldType.Historical, FieldQoS.AutomaticReadout)); } } foreach (MinuteHistoryRecord Rec in MinuteHistoricalValues) { if (!Request.IsIncluded(Rec.Timestamp)) { continue; } if (IncludeTemp) { if (Fields.Count >= 100) { Request.ReportFields(false, Fields); Fields.Clear(); } Fields.Add(new QuantityField(ThingReference.Empty, Rec.Timestamp, "Temperature", Rec.Temperature, 1, "°C", FieldType.Historical, FieldQoS.AutomaticReadout)); } } } } Request.ReportFields(true, Fields); }; this.bobClient = new BobClient(this.xmppClient, Path.Combine(Path.GetTempPath(), "BitsOfBinary")); this.chatServer = new ChatServer(this.xmppClient, this.bobClient, this.sensorServer, this.provisioningClient); this.interoperabilityServer = new InteroperabilityServer(xmppClient); this.interoperabilityServer.OnGetInterfaces += (sender, e) => { e.Add("XMPP.IoT.Sensor.Temperature", "XMPP.IoT.Sensor.Temperature.History", "XMPP.IoT.Sensor.Temperature.Average", "XMPP.IoT.Sensor.Temperature.Average.History", "XMPP.IoT.Sensor.Temperature.Min", "XMPP.IoT.Sensor.Temperature.Min.History", "XMPP.IoT.Sensor.Temperature.Max", "XMPP.IoT.Sensor.Temperature.Max.History"); }; xmppClient.Connect(); } catch (Exception ex) { Log.Emergency(ex); MessageDialog Dialog = new MessageDialog(ex.Message, "Error"); await Dialog.ShowAsync(); } }
/// <summary> /// Loads simple XMPP component configuration from an XML file. If file does not exist, or is not valid, a console dialog with the /// user is performed, to get the relevant information, test it, and create the corresponding XML file for later use. /// </summary> /// <param name="FileName">Name of configuration file.</param> /// <returns>Simple XMPP component configuration.</returns> public static SimpleComponentConfiguration GetConfigUsingSimpleConsoleDialog(string FileName) { try { return(new SimpleComponentConfiguration(FileName)); } catch (Exception) { SimpleComponentConfiguration Config = new SimpleComponentConfiguration(); bool Ok; Config.host = string.Empty; Config.port = DefaultPort; Config.component = string.Empty; Config.secret = string.Empty; #if WINDOWS_UWP using (XmppComponent Component = new XmppComponent(Config.host, Config.port, Config.component, Config.secret, "collaboration", "test", "Test Component")) { ManualResetEvent Connected = new ManualResetEvent(false); ManualResetEvent Failure = new ManualResetEvent(false); Component.OnStateChanged += (sender, NewState) => { Console.Out.WriteLine(NewState.ToString()); switch (NewState) { case XmppState.Connected: Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine("Connection successful."); Connected.Set(); break; case XmppState.Error: Console.ForegroundColor = ConsoleColor.Red; Console.Out.WriteLine("Connection failed. Please update connection information."); Failure.Set(); break; } }; switch (WaitHandle.WaitAny(new WaitHandle[] { Connected, Failure }, 20000)) { case 0: Ok = true; break; case 1: default: Ok = false; break; } if (!Ok) { throw; } } #else ConsoleColor FgBak = Console.ForegroundColor; string s; string Default; do { Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine(); Console.Out.WriteLine("To setup a connection with the XMPP component, please answer the following"); Console.Out.WriteLine("questions:"); Default = Config.host; Console.Out.WriteLine(); Console.Out.WriteLine("What XMPP server do you want to use? Press ENTER to use " + Default); do { Console.ForegroundColor = ConsoleColor.White; Console.Out.Write("XMPP Server: "); Config.host = Console.In.ReadLine(); if (string.IsNullOrEmpty(Config.host)) { Config.host = Default; } Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine(); Console.Out.WriteLine("You've selected to use '" + Config.host + "'. Is this correct? [y/n]"); s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); Default = Config.port.ToString(); Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("What port do you want to connect to? Press ENTER to use " + Default); do { Console.ForegroundColor = ConsoleColor.White; do { Console.Out.Write("Port Number: "); s = Console.In.ReadLine(); if (string.IsNullOrEmpty(s)) { s = Default; } }while (!int.TryParse(s, out Config.port) || Config.port < 1 || Config.port > 65535); Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine(); Console.Out.WriteLine("You've selected to use '" + Config.port.ToString() + "'. Is this correct? [y/n]"); s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); Default = Config.component; Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("What component to you want to connect to?"); if (!string.IsNullOrEmpty(Default)) { Console.Out.WriteLine("Press ENTER to use " + Default); } do { Console.ForegroundColor = ConsoleColor.White; do { Console.Out.Write("Component: "); Config.component = Console.In.ReadLine(); if (string.IsNullOrEmpty(Config.component)) { Config.component = Default; } }while (string.IsNullOrEmpty(Config.component)); Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine(); Console.Out.WriteLine("You've selected to use '" + Config.component + "'. Is this correct? [y/n]"); s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); Default = Config.secret; Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("What secret goes with the component? Remember that the configuration will,"); Console.Out.WriteLine("be stored in a simple text file along with the application."); if (!string.IsNullOrEmpty(Default)) { Console.Out.WriteLine("Press ENTER to use " + Default); } do { Console.ForegroundColor = ConsoleColor.White; do { Console.Out.Write("Secret: "); Config.secret = Console.In.ReadLine(); if (string.IsNullOrEmpty(Config.secret)) { Config.secret = Default; } }while (string.IsNullOrEmpty(Config.secret)); Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine(); Console.Out.WriteLine("You've selected to use '" + Config.secret + "'. Is this correct? [y/n]"); s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("I will now try to connect to the server to see if the information"); Console.Out.WriteLine("provided is correct."); using (XmppComponent Component = new XmppComponent(Config.host, Config.port, Config.component, Config.secret, "collaboration", "test", "Test Component")) { ManualResetEvent Connected = new ManualResetEvent(false); ManualResetEvent Failure = new ManualResetEvent(false); Component.OnStateChanged += (sender, NewState) => { Console.Out.WriteLine(NewState.ToString()); switch (NewState) { case XmppState.Connected: Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine("Connection successful."); Connected.Set(); break; case XmppState.Error: Console.ForegroundColor = ConsoleColor.Red; Console.Out.WriteLine("Connection failed. Please update connection information."); Failure.Set(); break; } }; switch (WaitHandle.WaitAny(new WaitHandle[] { Connected, Failure }, 20000)) { case 0: Ok = true; break; case 1: default: Ok = false; break; } } }while (!Ok); Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("Do you want to use a sniffer? If you use a sniffer, XMPP network"); Console.Out.WriteLine("communication will be Output to the console in real-time. This can"); Console.Out.WriteLine("come in handy when debugging network communication."); do { Console.ForegroundColor = ConsoleColor.White; Console.Out.Write("Sniffer [y/n]? "); s = Console.In.ReadLine(); Config.sniffer = s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase); }while (!Config.sniffer && !s.StartsWith("n", StringComparison.InvariantCultureIgnoreCase)); Console.Out.WriteLine(); Console.ForegroundColor = FgBak; #endif Config.Save(FileName); return(Config); } }
private async void StartActuator() { try { Log.Informational("Starting application."); SimpleXmppConfiguration xmppConfiguration = SimpleXmppConfiguration.GetConfigUsingSimpleConsoleDialog("xmpp.config", Guid.NewGuid().ToString().Replace("-", string.Empty), // Default user name. Guid.NewGuid().ToString().Replace("-", string.Empty), // Default password. FormSignatureKey, FormSignatureSecret, typeof(App).GetTypeInfo().Assembly); Log.Informational("Connecting to XMPP server."); xmppClient = xmppConfiguration.GetClient("en", typeof(App).GetTypeInfo().Assembly, false); xmppClient.AllowRegistration(FormSignatureKey, FormSignatureSecret); if (xmppConfiguration.Sniffer && MainPage.Sniffer != null) { xmppClient.Add(MainPage.Sniffer); } if (!string.IsNullOrEmpty(xmppConfiguration.Events)) { Log.Register(new XmppEventSink("XMPP Event Sink", xmppClient, xmppConfiguration.Events, false)); } if (!string.IsNullOrEmpty(xmppConfiguration.ThingRegistry)) { thingRegistryClient = new ThingRegistryClient(xmppClient, xmppConfiguration.ThingRegistry); thingRegistryClient.Claimed += (sender, e) => { ownerJid = e.JID; Log.Informational("Thing has been claimed.", ownerJid, new KeyValuePair <string, object>("Public", e.IsPublic)); this.RaiseOwnershipChanged(); }; thingRegistryClient.Disowned += (sender, e) => { Log.Informational("Thing has been disowned.", ownerJid); ownerJid = string.Empty; this.Register(); // Will call this.OwnershipChanged() after successful registration. }; thingRegistryClient.Removed += (sender, e) => { Log.Informational("Thing has been removed from the public registry.", ownerJid); }; } if (!string.IsNullOrEmpty(xmppConfiguration.Provisioning)) { provisioningClient = new ProvisioningClient(xmppClient, xmppConfiguration.Provisioning); } Timer ConnectionTimer = new Timer((P) => { if (xmppClient.State == XmppState.Offline || xmppClient.State == XmppState.Error || xmppClient.State == XmppState.Authenticating) { try { Log.Informational("Reconnecting."); xmppClient.Reconnect(); } catch (Exception ex) { Log.Critical(ex); } } }, null, 60000, 60000); xmppClient.OnStateChanged += (sender, NewState) => { Log.Informational(NewState.ToString()); switch (NewState) { case XmppState.Connected: connected = true; if (!registered && thingRegistryClient != null) { Register(); } break; case XmppState.Offline: immediateReconnect = connected; connected = false; if (immediateReconnect) { xmppClient.Reconnect(); } break; } }; xmppClient.OnPresenceSubscribe += (sender, e) => { Log.Informational("Subscription request received from " + e.From + "."); e.Accept(); // TODO: Provisioning RosterItem Item = xmppClient.GetRosterItem(e.FromBareJID); if (Item == null || Item.State == SubscriptionState.None || Item.State == SubscriptionState.From) { xmppClient.RequestPresenceSubscription(e.FromBareJID); } xmppClient.SetPresence(Availability.Chat); }; xmppClient.OnPresenceUnsubscribe += (sender, e) => { Log.Informational("Unsubscription request received from " + e.From + "."); e.Accept(); }; xmppClient.OnRosterItemUpdated += (sender, e) => { if (e.State == SubscriptionState.None && e.PendingSubscription != PendingSubscription.Subscribe) { xmppClient.RemoveRosterItem(e.BareJid); } }; bool SwitchOn = false; sensorServer = new SensorServer(xmppClient, provisioningClient, false); sensorServer.OnExecuteReadoutRequest += (Sender, Request) => { DateTime Now = DateTime.Now; Log.Informational("Readout requested", string.Empty, Request.Actor); Request.ReportFields(true, new BooleanField(ThingReference.Empty, Now, "Lamp", SwitchOn, FieldType.Momentary, FieldQoS.AutomaticReadout)); }; controlServer = new ControlServer(xmppClient, new BooleanControlParameter("Lamp", "Control", "Lamp switch on.", "If checked, lamp is turned on.", (Node) => SwitchOn, (Node, Value) => { SwitchOn = Value; Log.Informational("Lamp turned " + (SwitchOn ? "ON" : "OFF")); UpdateMainWindow(SwitchOn); })); this.bobClient = new BobClient(this.xmppClient, Path.Combine(Path.GetTempPath(), "BitsOfBinary")); this.chatServer = new ChatServer(xmppClient, this.bobClient, this.sensorServer, this.controlServer); interoperabilityServer = new InteroperabilityServer(xmppClient); interoperabilityServer.OnGetInterfaces += (sender, e) => { e.Add("XMPP.IoT.Actuator.Lamp"); }; xmppClient.Connect(); } catch (Exception ex) { Log.Emergency(ex); MessageDialog Dialog = new MessageDialog(ex.Message, "Error"); await Dialog.ShowAsync(); } }
/// <summary> /// Loads simple XMPP configuration from an XML file. If file does not exist, or is not valid, a console dialog with the user is performed, /// to get the relevant information, test it, and create the corresponding XML file for later use. /// </summary> /// <param name="FileName">Name of configuration file.</param> /// <param name="DefaultAccountName">Default account name.</param> /// <param name="DefaultPassword">Default password.</param> /// <param name="AppAssembly">Application assembly.</param> /// <returns>Simple XMPP configuration.</returns> public static XmppCredentials GetConfigUsingSimpleConsoleDialog(string FileName, string DefaultAccountName, string DefaultPassword, Assembly AppAssembly) { try { return(Load(FileName)); } catch (Exception #if WINDOWS_UWP ex #endif ) { XmppCredentials Credentials = new XmppCredentials(); bool Ok; Credentials.Host = DefaultXmppServer; Credentials.Port = XmppCredentials.DefaultPort; Credentials.Account = DefaultAccountName; Credentials.Password = DefaultPassword; #if WINDOWS_UWP using (XmppClient Client = new XmppClient(Credentials, "en", AppAssembly)) { Client.Connect(); ManualResetEvent Connected = new ManualResetEvent(false); ManualResetEvent Failure = new ManualResetEvent(false); Client.OnStateChanged += (sender, NewState) => { switch (NewState) { case XmppState.Connected: Credentials.Password = Client.PasswordHash; Credentials.PasswordType = Client.PasswordHashMethod; Connected.Set(); break; case XmppState.Error: Failure.Set(); break; } }; switch (WaitHandle.WaitAny(new WaitHandle[] { Connected, Failure }, 20000)) { case 0: Ok = true; break; case 1: default: Ok = false; break; } if (Ok) { ServiceItemsDiscoveryEventArgs e = Client.ServiceItemsDiscovery(Client.Domain, 10000); foreach (Item Item in e.Items) { ServiceDiscoveryEventArgs e2 = Client.ServiceDiscovery(Item.JID, 10000); if (e2.Features.ContainsKey("urn:ieee:iot:disco:1.0") && string.IsNullOrEmpty(Credentials.ThingRegistry)) { Credentials.ThingRegistry = Item.JID; } else { Credentials.ThingRegistry = string.Empty; } if (e2.Features.ContainsKey("urn:ieee:iot:prov:d:1.0") && string.IsNullOrEmpty(Credentials.Provisioning)) { Credentials.Provisioning = Item.JID; } else { Credentials.Provisioning = string.Empty; } if (e2.Features.ContainsKey("urn:xmpp:eventlog") && string.IsNullOrEmpty(Credentials.Events)) { Credentials.Events = Item.JID; } else { Credentials.Events = string.Empty; } } } else { System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(ex).Throw(); } } #else ConsoleColor FgBak = Console.ForegroundColor; string s; string Default; do { Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine(); Console.Out.WriteLine("To setup a connection to the XMPP network, please answer the following"); Console.Out.WriteLine("questions:"); Default = Credentials.Host; Console.Out.WriteLine(); Console.Out.WriteLine("What XMPP server do you want to use? Press ENTER to use " + Default); do { Console.ForegroundColor = ConsoleColor.White; Console.Out.Write("XMPP Server: "); Credentials.Host = Console.In.ReadLine(); if (string.IsNullOrEmpty(Credentials.Host)) { Credentials.Host = Default; } Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine(); Console.Out.WriteLine("You've selected to use '" + Credentials.Host + "'. Is this correct? [y/n]"); s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); Default = Credentials.Port.ToString(); Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("What port do you want to connect to? Press ENTER to use " + Default); do { Console.ForegroundColor = ConsoleColor.White; int Port; do { Console.Out.Write("Port Number: "); s = Console.In.ReadLine(); if (string.IsNullOrEmpty(s)) { s = Default; } }while (!int.TryParse(s, out Port) || Port < 1 || Port > 65535); Credentials.Port = Port; Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine(); Console.Out.WriteLine("You've selected to use '" + Credentials.Port.ToString() + "'. Is this correct? [y/n]"); s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); Default = Credentials.Account; Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("What account to you want to connect with? If the account does not exist,"); Console.Out.WriteLine("but the server supports In-band registration, the account will be created."); if (!string.IsNullOrEmpty(Default)) { Console.Out.WriteLine("Press ENTER to use " + Default); } do { Console.ForegroundColor = ConsoleColor.White; do { Console.Out.Write("Account: "); Credentials.Account = Console.In.ReadLine(); if (string.IsNullOrEmpty(Credentials.Account)) { Credentials.Account = Default; } }while (string.IsNullOrEmpty(Credentials.Account)); Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine(); Console.Out.WriteLine("You've selected to use '" + Credentials.Account + "'. Is this correct? [y/n]"); s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); Default = Credentials.Password; Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("What password goes with the account? Remember that the configuration will,"); Console.Out.Write("be stored in a simple text file along with the application. "); if (!string.IsNullOrEmpty(Default)) { Console.Out.WriteLine("Press ENTER to use " + Default); } do { Console.ForegroundColor = ConsoleColor.White; do { Console.Out.Write("Password: "******"You've selected to use '" + Credentials.Password + "'. Is this correct? [y/n]"); s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("Do you want to trust the server? It's better not to trust the server."); Console.Out.WriteLine("This will force the server certificate to be validated, and the server"); Console.Out.WriteLine("trusted only if the certificate is valid. If there's a valid problem with"); Console.Out.WriteLine("the server certificate however, you might need to trust the server to"); Console.Out.WriteLine("be able to proceed."); do { Console.ForegroundColor = ConsoleColor.White; Console.Out.Write("Trust server [y/n]? "); s = Console.In.ReadLine(); Credentials.TrustServer = s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase); }while (!Credentials.TrustServer && !s.StartsWith("n", StringComparison.InvariantCultureIgnoreCase)); Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("Do you want to create an account on the server?"); do { Console.ForegroundColor = ConsoleColor.White; Console.Out.Write("Create account [y/n]? "); s = Console.In.ReadLine(); Credentials.AllowRegistration = s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase); }while (!Credentials.AllowRegistration && !s.StartsWith("n", StringComparison.InvariantCultureIgnoreCase)); if (Credentials.AllowRegistration) { Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine(); Console.Out.WriteLine("Some servers require an API key to allow account creation."); Console.Out.WriteLine("If so, please enter an API key below."); Default = Credentials.FormSignatureKey; Console.Out.WriteLine(); Console.Out.WriteLine("What API Key do you want to use? Press ENTER to use " + Default); do { Console.ForegroundColor = ConsoleColor.White; Console.Out.Write("API Key: "); Credentials.FormSignatureKey = Console.In.ReadLine(); if (string.IsNullOrEmpty(Credentials.FormSignatureKey)) { Credentials.FormSignatureKey = Default; } Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine(); Console.Out.WriteLine("You've selected to use '" + Credentials.FormSignatureKey + "'. Is this correct? [y/n]"); s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); if (!string.IsNullOrEmpty(Credentials.FormSignatureKey)) { Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine(); Console.Out.WriteLine("Please provide the corresponding secret below."); Default = Credentials.FormSignatureSecret; Console.Out.WriteLine(); Console.Out.WriteLine("What secret belongs to the API key? Press ENTER to use " + Default); do { Console.ForegroundColor = ConsoleColor.White; Console.Out.Write("Secret: "); Credentials.FormSignatureSecret = Console.In.ReadLine(); if (string.IsNullOrEmpty(Credentials.FormSignatureSecret)) { Credentials.FormSignatureSecret = Default; } Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine(); Console.Out.WriteLine("You've selected to use '" + Credentials.FormSignatureSecret + "'. Is this correct? [y/n]"); s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); } } Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("I will now try to connect to the server to see if the information"); Console.Out.WriteLine("provided is correct."); using (XmppClient Client = new XmppClient(Credentials, "en", AppAssembly)) { Client.Connect(); ManualResetEvent Connected = new ManualResetEvent(false); ManualResetEvent Failure = new ManualResetEvent(false); Client.OnStateChanged += (sender, NewState) => { Console.Out.WriteLine(NewState.ToString()); switch (NewState) { case XmppState.Connected: Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine("Connection successful."); Credentials.Password = Client.PasswordHash; Credentials.PasswordType = Client.PasswordHashMethod; Credentials.AllowRegistration = false; Credentials.FormSignatureKey = string.Empty; Credentials.FormSignatureSecret = string.Empty; Connected.Set(); break; case XmppState.Error: Console.ForegroundColor = ConsoleColor.Red; Console.Out.WriteLine("Connection failed. Please update connection information."); Failure.Set(); break; } }; switch (WaitHandle.WaitAny(new WaitHandle[] { Connected, Failure }, 20000)) { case 0: Ok = true; break; case 1: default: Ok = false; break; } if (Ok) { Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("Checking server capabilities."); ServiceItemsDiscoveryEventArgs e = Client.ServiceItemsDiscovery(Client.Domain, 10000); foreach (Item Item in e.Items) { Console.Out.WriteLine("Checking " + Item.JID + "."); ServiceDiscoveryEventArgs e2 = Client.ServiceDiscovery(Item.JID, 10000); if (e2.Features.ContainsKey("urn:ieee:iot:disco:1.0") && string.IsNullOrEmpty(Credentials.ThingRegistry)) { Console.Out.WriteLine("Thing registry found."); Credentials.ThingRegistry = Item.JID; } else { Credentials.ThingRegistry = string.Empty; } if (e2.Features.ContainsKey("urn:ieee:iot:prov:d:1.0") && string.IsNullOrEmpty(Credentials.Provisioning)) { Console.Out.WriteLine("Provisioning server found."); Credentials.Provisioning = Item.JID; } else { Credentials.Provisioning = string.Empty; } if (e2.Features.ContainsKey("urn:xmpp:eventlog") && string.IsNullOrEmpty(Credentials.Events)) { Console.Out.WriteLine("Event log found."); Credentials.Events = Item.JID; } else { Credentials.Events = string.Empty; } } } } }while (!Ok); Default = Credentials.ThingRegistry; Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("What thing registry do you want to use? The use of a thing registry is optional."); if (string.IsNullOrEmpty(Default)) { Console.Out.WriteLine("Press ENTER to not use a thing registry."); } else { Console.Out.WriteLine("Press ENTER to use " + Default); } do { Console.ForegroundColor = ConsoleColor.White; Console.Out.Write("Thing Registry: "); Credentials.ThingRegistry = Console.In.ReadLine(); if (string.IsNullOrEmpty(Credentials.ThingRegistry)) { Credentials.ThingRegistry = Default; } Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine(); if (string.IsNullOrEmpty(Credentials.ThingRegistry)) { Console.Out.WriteLine("You've selected to not use a thing registry. Is this correct? [y/n]"); } else { Console.Out.WriteLine("You've selected to use '" + Credentials.ThingRegistry + "'. Is this correct? [y/n]"); } s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); Default = Credentials.Provisioning; Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("What provisioning server do you want to use? The use of a provisioning server"); Console.Out.WriteLine("is optional."); if (string.IsNullOrEmpty(Default)) { Console.Out.WriteLine("Press ENTER to not use a provisioning server."); } else { Console.Out.WriteLine("Press ENTER to use " + Default); } do { Console.ForegroundColor = ConsoleColor.White; Console.Out.Write("Provisioning Server: "); Credentials.Provisioning = Console.In.ReadLine(); if (string.IsNullOrEmpty(Credentials.Provisioning)) { Credentials.Provisioning = Default; } Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine(); if (string.IsNullOrEmpty(Credentials.Provisioning)) { Console.Out.WriteLine("You've selected to not use a provisioning server. Is this correct? [y/n]"); } else { Console.Out.WriteLine("You've selected to use '" + Credentials.Provisioning + "'. Is this correct? [y/n]"); } s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); Default = Credentials.Events; Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("What event log do you want to use? The use of a event logs is optional."); if (string.IsNullOrEmpty(Default)) { Console.Out.WriteLine("Press ENTER to not use an event log."); } else { Console.Out.WriteLine("Press ENTER to use " + Default); } do { Console.ForegroundColor = ConsoleColor.White; Console.Out.Write("Event Log: "); Credentials.Events = Console.In.ReadLine(); if (string.IsNullOrEmpty(Credentials.Events)) { Credentials.Events = Default; } Console.ForegroundColor = ConsoleColor.Green; Console.Out.WriteLine(); if (string.IsNullOrEmpty(Credentials.Events)) { Console.Out.WriteLine("You've selected to not use an event log. Is this correct? [y/n]"); } else { Console.Out.WriteLine("You've selected to use '" + Credentials.Events + "'. Is this correct? [y/n]"); } s = Console.In.ReadLine(); Console.Out.WriteLine(); }while (!s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase)); Console.ForegroundColor = ConsoleColor.Yellow; Console.Out.WriteLine("Do you want to use a sniffer? If you use a sniffer, XMPP network"); Console.Out.WriteLine("communication will be Output to the console in real-time. This can"); Console.Out.WriteLine("come in handy when debugging network communication."); do { Console.ForegroundColor = ConsoleColor.White; Console.Out.Write("Sniffer [y/n]? "); s = Console.In.ReadLine(); Credentials.Sniffer = s.StartsWith("y", StringComparison.InvariantCultureIgnoreCase); }while (!Credentials.Sniffer && !s.StartsWith("n", StringComparison.InvariantCultureIgnoreCase)); Console.Out.WriteLine(); Console.ForegroundColor = FgBak; #endif SaveSimpleXmppConfiguration(FileName, Credentials); return(Credentials); } }
private async void StartActuator() { try { Log.Informational("Starting application."); SimpleXmppConfiguration xmppConfiguration = SimpleXmppConfiguration.GetConfigUsingSimpleConsoleDialog("xmpp.config", Guid.NewGuid().ToString().Replace("-", string.Empty), // Default user name. Guid.NewGuid().ToString().Replace("-", string.Empty), // Default password. FormSignatureKey, FormSignatureSecret, typeof(App).GetTypeInfo().Assembly); Log.Informational("Connecting to XMPP server."); xmppClient = xmppConfiguration.GetClient("en", typeof(App).GetTypeInfo().Assembly, false); xmppClient.AllowRegistration(FormSignatureKey, FormSignatureSecret); if (xmppConfiguration.Sniffer && MainPage.Sniffer != null) xmppClient.Add(MainPage.Sniffer); if (!string.IsNullOrEmpty(xmppConfiguration.Events)) Log.Register(new XmppEventSink("XMPP Event Sink", xmppClient, xmppConfiguration.Events, false)); if (!string.IsNullOrEmpty(xmppConfiguration.ThingRegistry)) { thingRegistryClient = new ThingRegistryClient(xmppClient, xmppConfiguration.ThingRegistry); thingRegistryClient.Claimed += (sender, e) => { ownerJid = e.JID; Log.Informational("Thing has been claimed.", ownerJid, new KeyValuePair<string, object>("Public", e.IsPublic)); this.RaiseOwnershipChanged(); }; thingRegistryClient.Disowned += (sender, e) => { Log.Informational("Thing has been disowned.", ownerJid); ownerJid = string.Empty; this.Register(); // Will call this.OwnershipChanged() after successful registration. }; thingRegistryClient.Removed += (sender, e) => { Log.Informational("Thing has been removed from the public registry.", ownerJid); }; } if (!string.IsNullOrEmpty(xmppConfiguration.Provisioning)) provisioningClient = new ProvisioningClient(xmppClient, xmppConfiguration.Provisioning); Timer ConnectionTimer = new Timer((P) => { if (xmppClient.State == XmppState.Offline || xmppClient.State == XmppState.Error || xmppClient.State == XmppState.Authenticating) { try { Log.Informational("Reconnecting."); xmppClient.Reconnect(); } catch (Exception ex) { Log.Critical(ex); } } }, null, 60000, 60000); xmppClient.OnStateChanged += (sender, NewState) => { Log.Informational(NewState.ToString()); switch (NewState) { case XmppState.Connected: connected = true; if (!registered && this.thingRegistryClient != null) this.Register(); break; case XmppState.Offline: immediateReconnect = connected; connected = false; if (immediateReconnect) xmppClient.Reconnect(); break; } }; xmppClient.OnPresenceSubscribe += (sender, e) => { Log.Informational("Subscription request received from " + e.From + "."); e.Accept(); // TODO: Provisioning RosterItem Item = xmppClient.GetRosterItem(e.FromBareJID); if (Item == null || Item.State == SubscriptionState.None || Item.State == SubscriptionState.From) xmppClient.RequestPresenceSubscription(e.FromBareJID); xmppClient.SetPresence(Availability.Chat); }; xmppClient.OnPresenceUnsubscribe += (sender, e) => { Log.Informational("Unsubscription request received from " + e.From + "."); e.Accept(); }; xmppClient.OnRosterItemUpdated += (sender, e) => { if (e.State == SubscriptionState.None && e.PendingSubscription != PendingSubscription.Subscribe) xmppClient.RemoveRosterItem(e.BareJid); }; gpio = GpioController.GetDefault(); if (gpio != null) { int c = gpio.PinCount; int i; for (i = 0; i < c; i++) { if (gpio.TryOpenPin(i, GpioSharingMode.Exclusive, out GpioPin Pin, out GpioOpenStatus Status) && Status == GpioOpenStatus.PinOpened) { gpioPins[i] = new KeyValuePair<GpioPin, KeyValuePair<TextBlock, TextBlock>>(Pin, MainPage.Instance.AddPin("GPIO" + i.ToString(), Pin.GetDriveMode(), Pin.Read().ToString())); Pin.ValueChanged += async (sender, e) => { if (!this.gpioPins.TryGetValue(sender.PinNumber, out KeyValuePair<GpioPin, KeyValuePair<TextBlock, TextBlock>> P)) return; PinState Value = e.Edge == GpioPinEdge.FallingEdge ? PinState.LOW : PinState.HIGH; if (this.sensorServer.HasSubscriptions(ThingReference.Empty)) { DateTime TP = DateTime.Now; string s = "GPIO" + sender.PinNumber.ToString(); this.sensorServer.NewMomentaryValues( new EnumField(ThingReference.Empty, TP, s, Value, FieldType.Momentary, FieldQoS.AutomaticReadout)); } await P.Value.Value.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => P.Value.Value.Text = Value.ToString()); }; } } } DeviceInformationCollection Devices = await Microsoft.Maker.Serial.UsbSerial.listAvailableDevicesAsync(); foreach (DeviceInformation DeviceInfo in Devices) { if (DeviceInfo.IsEnabled && DeviceInfo.Name.StartsWith("Arduino")) { Log.Informational("Connecting to " + DeviceInfo.Name); arduinoUsb = new UsbSerial(DeviceInfo); arduinoUsb.ConnectionEstablished += () => { Log.Informational("USB connection established."); }; arduino = new RemoteDevice(arduinoUsb); arduino.DeviceReady += async () => { Log.Informational("Device ready."); Dictionary<int, bool> DisabledPins = new Dictionary<int, bool>(); Dictionary<string, KeyValuePair<Enum, string>> Values = new Dictionary<string, KeyValuePair<Enum, string>>(); PinMode Mode; PinState State; string s; ushort Value; foreach (byte PinNr in arduino.DeviceHardwareProfile.DisabledPins) DisabledPins[PinNr] = true; foreach (byte PinNr in arduino.DeviceHardwareProfile.AnalogPins) { if (DisabledPins.ContainsKey(PinNr)) continue; s = "A" + (PinNr - arduino.DeviceHardwareProfile.AnalogOffset).ToString(); if (arduino.DeviceHardwareProfile.isAnalogSupported(PinNr)) arduino.pinMode(s, PinMode.ANALOG); Mode = arduino.getPinMode(s); Value = arduino.analogRead(s); Values[s] = new KeyValuePair<Enum, string>(Mode, Value.ToString()); } foreach (byte PinNr in arduino.DeviceHardwareProfile.DigitalPins) { if (DisabledPins.ContainsKey(PinNr) || (PinNr > 6 && PinNr != 13)) // Not sure why this limitation is necessary. Without it, my Arduino board (or the Microsoft Firmata library) stops providing me with pin update events. continue; if (PinNr == 13) { arduino.pinMode(13, PinMode.OUTPUT); // Onboard LED. arduino.digitalWrite(13, PinState.HIGH); } else { if (arduino.DeviceHardwareProfile.isDigitalInputSupported(PinNr)) arduino.pinMode(PinNr, PinMode.INPUT); } s = "D" + PinNr.ToString(); Mode = arduino.getPinMode(PinNr); State = arduino.digitalRead(PinNr); Values[s] = new KeyValuePair<Enum, string>(Mode, State.ToString()); } await MainPage.Instance.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { lock (arduinoPins) { foreach (KeyValuePair<string, KeyValuePair<Enum, string>> P in Values) arduinoPins[P.Key] = MainPage.Instance.AddPin(P.Key, P.Value.Key, P.Value.Value); } }); this.SetupControlServer(); }; arduino.AnalogPinUpdated += async (pin, value) => { KeyValuePair<TextBlock, TextBlock> P; DateTime TP = DateTime.Now; lock (this.arduinoPins) { if (!this.arduinoPins.TryGetValue(pin, out P)) return; } if (this.sensorServer.HasSubscriptions(ThingReference.Empty)) { this.sensorServer.NewMomentaryValues( new Int32Field(ThingReference.Empty, TP, pin + ", Raw", value, FieldType.Momentary, FieldQoS.AutomaticReadout), new QuantityField(ThingReference.Empty, TP, pin, value / 10.24, 2, "%", FieldType.Momentary, FieldQoS.AutomaticReadout)); } await P.Value.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => P.Value.Text = value.ToString()); }; arduino.DigitalPinUpdated += async (pin, value) => { KeyValuePair<TextBlock, TextBlock> P; DateTime TP = DateTime.Now; string s = "D" + pin.ToString(); lock (this.arduinoPins) { if (!this.arduinoPins.TryGetValue("D" + pin.ToString(), out P)) return; } if (this.sensorServer.HasSubscriptions(ThingReference.Empty)) { this.sensorServer.NewMomentaryValues( new EnumField(ThingReference.Empty, TP, s, value, FieldType.Momentary, FieldQoS.AutomaticReadout)); } await P.Value.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => P.Value.Text = value.ToString()); }; arduinoUsb.ConnectionFailed += message => { Log.Error("USB connection failed: " + message); }; arduinoUsb.ConnectionLost += message => { Log.Error("USB connection lost: " + message); }; arduinoUsb.begin(57600, SerialConfig.SERIAL_8N1); break; } } sensorServer = new SensorServer(xmppClient, provisioningClient, true); sensorServer.OnExecuteReadoutRequest += (Sender, Request) => { DateTime Now = DateTime.Now; LinkedList<Field> Fields = new LinkedList<Field>(); DateTime TP = DateTime.Now; string s; bool ReadMomentary = Request.IsIncluded(FieldType.Momentary); bool ReadStatus = Request.IsIncluded(FieldType.Status); Log.Informational("Readout requested", string.Empty, Request.Actor); foreach (KeyValuePair<GpioPin, KeyValuePair<TextBlock, TextBlock>> Pin in gpioPins.Values) { if (ReadMomentary && Request.IsIncluded(s = "GPIO" + Pin.Key.PinNumber.ToString())) { Fields.AddLast(new EnumField(ThingReference.Empty, TP, s, Pin.Key.Read(), FieldType.Momentary, FieldQoS.AutomaticReadout)); } if (ReadStatus && Request.IsIncluded(s = "GPIO" + Pin.Key.PinNumber.ToString() + ", Mode")) { Fields.AddLast(new EnumField(ThingReference.Empty, TP, s, Pin.Key.GetDriveMode(), FieldType.Status, FieldQoS.AutomaticReadout)); } } if (arduinoPins != null) { foreach (KeyValuePair<string, KeyValuePair<TextBlock, TextBlock>> Pin in arduinoPins) { byte i; if (ReadMomentary && Request.IsIncluded(s = Pin.Key)) { if (s.StartsWith("D") && byte.TryParse(s.Substring(1), out i)) { Fields.AddLast(new EnumField(ThingReference.Empty, TP, s, arduino.digitalRead(i), FieldType.Momentary, FieldQoS.AutomaticReadout)); } else { ushort Raw = arduino.analogRead(s); double Percent = Raw / 10.24; Fields.AddLast(new Int32Field(ThingReference.Empty, TP, s + ", Raw", Raw, FieldType.Momentary, FieldQoS.AutomaticReadout)); Fields.AddLast(new QuantityField(ThingReference.Empty, TP, s, Percent, 2, "%", FieldType.Momentary, FieldQoS.AutomaticReadout)); } } if (ReadStatus && Request.IsIncluded(s = Pin.Key + ", Mode")) { if (s.StartsWith("D") && byte.TryParse(s.Substring(1), out i)) { Fields.AddLast(new EnumField(ThingReference.Empty, TP, s, arduino.getPinMode(i), FieldType.Status, FieldQoS.AutomaticReadout)); } else { Fields.AddLast(new EnumField(ThingReference.Empty, TP, s, arduino.getPinMode(s), FieldType.Status, FieldQoS.AutomaticReadout)); } } } } Request.ReportFields(true, Fields); }; if (arduino == null) this.SetupControlServer(); xmppClient.Connect(); } catch (Exception ex) { Log.Emergency(ex); MessageDialog Dialog = new MessageDialog(ex.Message, "Error"); await Dialog.ShowAsync(); } }
public void SensorData_Test_06_Subscribe_MinInterval() { this.ConnectClients(); try { ManualResetEvent Done = new ManualResetEvent(false); ManualResetEvent Error = new ManualResetEvent(false); IEnumerable <Field> Fields = null; SensorDataSubscriptionRequest Request = this.sensorClient.Subscribe(this.client2.FullJID, FieldType.All, new FieldSubscriptionRule[] { new FieldSubscriptionRule("Temperature", this.temp, 1, null) }, Duration.Parse("PT1S"), Duration.Parse("PT5S"), false); Request.OnStateChanged += (sender, NewState) => { Console.Out.WriteLine(NewState.ToString()); return(Task.CompletedTask); }; Request.OnErrorsReceived += (sender, Errors) => { Error.Set(); return(Task.CompletedTask); }; Request.OnFieldsReceived += (sender, NewFields) => { Fields = NewFields; Done.Set(); return(Task.CompletedTask); }; int Count = 6; DateTime Start = DateTime.Now; while (Count > 0) { this.temp += 1; this.sensorServer.NewMomentaryValues(new QuantityField(ThingReference.Empty, DateTime.Now, "Temperature", this.temp, 1, "C", FieldType.Momentary, FieldQoS.AutomaticReadout)); this.temp -= 1; this.sensorServer.NewMomentaryValues(new QuantityField(ThingReference.Empty, DateTime.Now, "Temperature", this.temp, 1, "C", FieldType.Momentary, FieldQoS.AutomaticReadout)); switch (WaitHandle.WaitAny(new WaitHandle[] { Done, Error }, 100)) { case 0: Done.Reset(); Count--; break; case 1: Assert.Fail("Subscription not performed correctly"); break; } } TimeSpan Elapsed = DateTime.Now - Start; Assert.IsTrue(Elapsed > new TimeSpan(0, 0, 5)); } finally { this.DisposeClients(); } }
public void SensorData_Test_07_Unsubscribe() { this.ConnectClients(); try { ManualResetEvent Done = new ManualResetEvent(false); ManualResetEvent Error = new ManualResetEvent(false); IEnumerable <Field> Fields = null; SensorDataSubscriptionRequest Request = this.sensorClient.Subscribe(this.client2.FullJID, FieldType.All, Duration.Parse("PT1S"), Duration.Parse("PT5S"), false); Request.OnStateChanged += (sender, NewState) => Console.Out.WriteLine(NewState.ToString()); Request.OnErrorsReceived += (sender, Errors) => Error.Set(); Request.OnFieldsReceived += (sender, NewFields) => { Fields = NewFields; Done.Set(); }; this.sensorServer.NewMomentaryValues(new QuantityField(ThingReference.Empty, DateTime.Now, "Temperature", this.temp, 1, "C", FieldType.Momentary, FieldQoS.AutomaticReadout)); Assert.AreEqual(0, WaitHandle.WaitAny(new WaitHandle[] { Done, Error }, 10000), "Subscription not performed correctly"); Done.Reset(); Request.Unsubscribe(); this.sensorServer.NewMomentaryValues(new QuantityField(ThingReference.Empty, DateTime.Now, "Temperature", this.temp, 1, "C", FieldType.Momentary, FieldQoS.AutomaticReadout)); Assert.AreEqual(WaitHandle.WaitTimeout, WaitHandle.WaitAny(new WaitHandle[] { Done, Error }, 10000), "Unsubscription not performed correctly"); } finally { this.DisposeClients(); } }