public QuestionView(XmppAccountNode Owner, ProvisioningClient ProvisioningClient) { this.owner = Owner; this.provisioningClient = ProvisioningClient; InitializeComponent(); }
public ThingRegistry(TreeNode Parent, string JID, string Name, string Node, Dictionary <string, bool> Features) : base(Parent, JID, Name, Node, Features) { this.supportsProvisioning = Features.ContainsKey(ProvisioningClient.NamespaceProvisioningOwner); this.registryClient = new ThingRegistryClient(this.Account.Client, JID); if (this.supportsProvisioning) { XmppAccountNode Account = this.Account; XmppClient Client = Account.Client; this.provisioningClient = new ProvisioningClient(Client, JID); this.provisioningClient.IsFriendQuestion += this.ProvisioningClient_IsFriendQuestion; this.provisioningClient.CanReadQuestion += this.ProvisioningClient_CanReadQuestion; this.provisioningClient.CanControlQuestion += this.ProvisioningClient_CanControlQuestion; foreach (MessageEventArgs Message in Account.GetUnhandledMessages("isFriend", ProvisioningClient.NamespaceProvisioningOwner)) { try { this.ProvisioningClient_IsFriendQuestion(this, new IsFriendEventArgs(this.provisioningClient, Message)); } catch (Exception ex) { Log.Critical(ex); } } } else { this.provisioningClient = null; } }
public ThingRegistry(TreeNode Parent, string JID, string Name, string Node, Dictionary <string, bool> Features) : base(Parent, JID, Name, Node, Features) { this.supportsProvisioning = Features.ContainsKey(ProvisioningClient.NamespaceProvisioningOwner); this.registryClient = new ThingRegistryClient(this.Account.Client, JID); if (this.supportsProvisioning) { XmppAccountNode Account = this.Account; XmppClient Client = Account.Client; this.provisioningClient = new ProvisioningClient(Client, JID) { ManagePresenceSubscriptionRequests = false }; this.provisioningClient.IsFriendQuestion += this.ProvisioningClient_IsFriendQuestion; this.provisioningClient.CanReadQuestion += this.ProvisioningClient_CanReadQuestion; this.provisioningClient.CanControlQuestion += this.ProvisioningClient_CanControlQuestion; this.ProcessUnhandled(); } else { this.provisioningClient = null; } }
protected void AddJidName(string JID, ProvisioningClient ProvisioningClient, TextBlock TextBlock) { XmppClient Client = ProvisioningClient.Client; RosterItem Item = Client[JID]; if (Item != null && !string.IsNullOrEmpty(Item.Name)) { TextBlock.Inlines.Add(new Run() { FontWeight = FontWeights.Bold, Text = Item.Name }); TextBlock.Inlines.Add(" ("); TextBlock.Inlines.Add(JID); TextBlock.Inlines.Add(")"); } else { TextBlock.Inlines.Add(new Run() { FontWeight = FontWeights.Bold, Text = JID }); } }
/// <summary> /// Adds the extension to the client. /// </summary> /// <param name="Instance">Actor instance.</param> /// <param name="Client">XMPP Client</param> /// <returns>Extension object.</returns> public override Task <object> Add(IActor Instance, Waher.Networking.XMPP.XmppClient Client) { if (Client.ContainsTag("SensorServer")) { throw new Exception("Define provisioning clients before any sensor server extensions."); } if (Client.ContainsTag("ControlServer")) { throw new Exception("Define provisioning clients before any control server extensions."); } if (Client.ContainsTag("ConcentratorServer")) { throw new Exception("Define provisioning clients before any concentrator server extensions."); } ProvisioningClient Extension = new ProvisioningClient(Client, this.componentAddress); Client.SetTag("ProvisioningClient", Extension); Extension.CanControlQuestion += (Sender, e) => { this.Model.ExternalEvent(Instance, "OnExecuteReadoutRequest", new KeyValuePair <string, object>("e", e), new KeyValuePair <string, object>("Client", Client)); return(Task.CompletedTask); }; Extension.CanReadQuestion += (Sender, e) => { this.Model.ExternalEvent(Instance, "CanReadQuestion", new KeyValuePair <string, object>("e", e), new KeyValuePair <string, object>("Client", Client)); return(Task.CompletedTask); }; Extension.IsFriendQuestion += (Sender, e) => { this.Model.ExternalEvent(Instance, "IsFriendQuestion", new KeyValuePair <string, object>("e", e), new KeyValuePair <string, object>("Client", Client)); return(Task.CompletedTask); }; Extension.CacheCleared += (Sender, e) => { this.Model.ExternalEvent(Instance, "CacheCleared", new KeyValuePair <string, object>("e", e), new KeyValuePair <string, object>("Client", Client)); }; return(Task.FromResult <object>(Extension)); }
/// <summary> /// Invoked when application execution is being suspended. Application state is saved /// without knowing whether the application will be terminated or resumed with the contents /// of memory still intact. /// </summary> /// <param name="sender">The source of the suspend request.</param> /// <param name="e">Details about the suspend request.</param> private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); if (this.sampleTimer != null) { this.sampleTimer.Dispose(); this.sampleTimer = null; } if (this.interoperabilityServer != null) { this.interoperabilityServer.Dispose(); this.interoperabilityServer = null; } if (this.chatServer != null) { this.chatServer.Dispose(); this.chatServer = null; } if (this.bobClient != null) { this.bobClient.Dispose(); this.bobClient = null; } if (this.sensorServer != null) { this.sensorServer.Dispose(); this.sensorServer = null; } if (this.provisioningClient != null) { this.provisioningClient.Dispose(); this.provisioningClient = null; } if (this.thingRegistryClient != null) { this.thingRegistryClient.Dispose(); this.thingRegistryClient = null; } if (this.xmppClient != null) { this.xmppClient.Dispose(); this.xmppClient = null; } Log.Terminate(); deferral.Complete(); }
public override void Dispose() { this.registryClient?.Dispose(); this.registryClient = null; this.provisioningClient?.Dispose(); this.provisioningClient = null; base.Dispose(); }
internal void NewQuestion(XmppAccountNode Owner, ProvisioningClient ProvisioningClient, Question Question) { QuestionView QuestionView = this.FindQuestionTab(Owner, ProvisioningClient); if (QuestionView != null && Question != null) { QuestionView.NewQuestion(Question); return; } Task.Run(async() => { try { LinkedList <Question> Questions = new LinkedList <Question>(); bool Found = Question == null; foreach (Question Question2 in await Database.Find <Question>(new FilterAnd(new FilterFieldEqualTo("OwnerJID", Owner?.BareJID), new FilterFieldEqualTo("ProvisioningJID", ProvisioningClient?.ProvisioningServerAddress)), "Created")) { Questions.AddLast(Question2); if (!Found) { Found = Question2.ObjectId == Question.ObjectId; } } if (!Found) { Questions.AddLast(Question); } if (Questions.First != null) { DispatcherOperation Op = MainWindow.currentInstance.Dispatcher.BeginInvoke(new ThreadStart(() => { if (QuestionView == null) { QuestionView = this.CreateQuestionTab(Owner, ProvisioningClient); } foreach (Question Question2 in Questions) { QuestionView.NewQuestion(Question2); } })); } } catch (Exception ex) { Log.Critical(ex); } }); }
private QuestionView CreateQuestionTab(XmppAccountNode Owner, ProvisioningClient ProvisioningClient) { TabItem TabItem = MainWindow.NewTab("Questions (" + Owner.BareJID + ")"); this.Tabs.Items.Add(TabItem); QuestionView QuestionView = new QuestionView(Owner, ProvisioningClient); TabItem.Content = QuestionView; return(QuestionView); }
/// <summary> /// Implements an XMPP control server interface. /// /// The interface is defined in the IEEE XMPP IoT extensions: /// https://gitlab.com/IEEE-SA/XMPPI/IoT /// </summary> /// <param name="Client">XMPP Client</param> /// <param name="ProvisioningClient">Provisioning client, if actuator supports provisioning.</param> /// <param name="Parameters">Default set of control parameters. If set of control parameters vary depending on node, leave this /// field blank, and provide an event handler for the <see cref="OnGetControlParameters"/> event.</param> public ControlServer(XmppClient Client, ProvisioningClient ProvisioningClient, params ControlParameter[] Parameters) : base(Client) { this.provisioningClient = ProvisioningClient; this.controlParameters = Parameters; foreach (ControlParameter P in Parameters) { this.controlParametersByName[P.Name] = P; } this.client.RegisterIqSetHandler("set", ControlClient.NamespaceControl, this.SetHandler, true); this.client.RegisterIqGetHandler("getForm", ControlClient.NamespaceControl, this.GetFormHandler, false); }
private void UseProvisioningServer(string JID, string OwnerJid) { if (this.provisioningClient == null || this.provisioningClient.ProvisioningServerAddress != JID || this.provisioningClient.OwnerJid != OwnerJid) { if (this.provisioningClient != null) { this.provisioningClient.Dispose(); this.provisioningClient = null; } this.provisioningClient = new ProvisioningClient(this.xmppClient, JID, OwnerJid); this.AttachFeatures(); } }
public override void Dispose() { if (this.registryClient != null) { this.registryClient.Dispose(); this.registryClient = null; } if (this.provisioningClient != null) { this.provisioningClient.Dispose(); this.provisioningClient = null; } base.Dispose(); }
private QuestionView FindQuestionTab(XmppAccountNode Owner, ProvisioningClient ProvisioningClient) { QuestionView QuestionView = null; foreach (TabItem TabItem in this.Tabs.Items) { QuestionView = TabItem.Content as QuestionView; if (QuestionView != null && QuestionView.Owner == Owner && QuestionView.ProvisioningJid == ProvisioningClient.ProvisioningServerAddress) { return(QuestionView); } } return(null); }
private void AddTokens(StackPanel Details, ProvisioningClient Client, string[] Tokens, RoutedEventHandler OnYes, RoutedEventHandler OnNo, OperationRange Range) { if (Tokens != null) { X509Certificate2 Certificate; foreach (string Token in Tokens) { lock (this.certificates) { if (!this.certificates.TryGetValue(Token, out Certificate)) { Certificate = null; } } if (Certificate != null) { this.AddToken(Details, Token, Certificate, OnYes, OnNo, Range); } else { Client.GetCertificate(Token, (sender, e) => { if (e.Ok) { string Token2 = (string)e.State; lock (this.certificates) { this.certificates[Token2] = e.Certificate; } MainWindow.UpdateGui(() => { this.AddToken(Details, Token2, e.Certificate, OnYes, OnNo, Range); }); } return(Task.CompletedTask); }, Token); } } } }
private void AddTokens(StackPanel Details, ProvisioningClient Client, string[] Tokens, RoutedEventHandler OnYes, RoutedEventHandler OnNo, OperationRange Range) { if (Tokens != null) { X509Certificate2 Certificate; foreach (string Token in Tokens) { lock (this.certificates) { if (!this.certificates.TryGetValue(Token, out Certificate)) { Certificate = null; } } if (Certificate != null) { this.AddToken(Details, Token, Certificate, OnYes, OnNo, Range); } else { Client.GetCertificate(Token, (sender, e) => { if (e.Ok) { string Token2 = (string)e.State; lock (this.certificates) { this.certificates[Token2] = e.Certificate; } MainWindow.currentInstance.Dispatcher.BeginInvoke(new ThreadStart(() => { this.AddToken(Details, Token2, e.Certificate, OnYes, OnNo, Range); })); } }, Token); } } } }
public WaitHandle Start() { ConcentratorServer ConcentratorServer = null; ProvisioningClient ProvisioningClient = null; if (Types.TryGetModuleParameter("Concentrator", out object Obj)) { ConcentratorServer = Obj as ConcentratorServer; } if (Types.TryGetModuleParameter("Provisioning", out Obj)) { ProvisioningClient = Obj as ProvisioningClient; } this.bobClient = new BobClient(Gateway.XmppClient, Path.Combine(Gateway.AppDataFolder, "BoB")); this.chatServer = new ChatServer(Gateway.XmppClient, this.bobClient, ConcentratorServer, ProvisioningClient); return(null); }
/// <summary> /// Implements an XMPP sensor server interface. /// /// The interface is defined in the IEEE XMPP IoT extensions: /// https://gitlab.com/IEEE-SA/XMPPI/IoT /// /// It also supports the event subscription pattern, documented in the iot-events proto-XEP: /// http://www.xmpp.org/extensions/inbox/iot-events.html /// </summary> /// <param name="Client">XMPP Client</param> /// <param name="ProvisioningClient">Provisioning client, if sensor supports provisioning.</param> /// <param name="SupportsEvents">If events are supported.</param> public SensorServer(XmppClient Client, ProvisioningClient ProvisioningClient, bool SupportsEvents) { this.client = Client; this.provisioningClient = ProvisioningClient; this.client.RegisterIqGetHandler("req", SensorClient.NamespaceSensorData, this.ReqHandler, true); this.client.RegisterIqSetHandler("req", SensorClient.NamespaceSensorData, this.ReqHandler, false); this.client.RegisterIqGetHandler("cancel", SensorClient.NamespaceSensorData, this.CancelHandler, false); this.client.RegisterIqSetHandler("cancel", SensorClient.NamespaceSensorData, this.CancelHandler, false); if (SupportsEvents) { this.client.RegisterIqGetHandler("subscribe", SensorClient.NamespaceSensorEvents, this.SubscribeHandler, true); this.client.RegisterIqSetHandler("subscribe", SensorClient.NamespaceSensorEvents, this.SubscribeHandler, false); this.client.RegisterIqGetHandler("unsubscribe", SensorClient.NamespaceSensorEvents, this.UnsubscribeHandler, false); this.client.RegisterIqSetHandler("unsubscribe", SensorClient.NamespaceSensorEvents, this.UnsubscribeHandler, false); this.client.OnPresenceUnsubscribe += Client_OnPresenceUnsubscribed; this.client.OnPresenceUnsubscribed += Client_OnPresenceUnsubscribed; this.client.OnPresence += Client_OnPresence; } }
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(); } }
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(); } }
public static void Main(string[] _) { try { Console.ForegroundColor = ConsoleColor.White; Console.Out.WriteLine("Welcome to the PC Sensor application."); Console.Out.WriteLine(new string('-', 79)); Console.Out.WriteLine("This application will publish performace couters as sensor values."); Console.Out.WriteLine("Values will be published over XMPP using the interface defined in the IEEE XMPP IoT extensions."); Log.Register(new ConsoleEventSink(false)); Log.RegisterExceptionToUnnest(typeof(System.Runtime.InteropServices.ExternalException)); Log.RegisterExceptionToUnnest(typeof(System.Security.Authentication.AuthenticationException)); credentials = SimpleXmppConfiguration.GetConfigUsingSimpleConsoleDialog("xmpp.config", Environment.MachineName, // Default user name. Guid.NewGuid().ToString().Replace("-", string.Empty), // Default password. typeof(Program).Assembly); using (XmppClient Client = new XmppClient(credentials, "en", typeof(Program).Assembly)) { if (credentials.Sniffer) { Client.Add(new ConsoleOutSniffer(BinaryPresentationMethod.ByteCount, LineEnding.PadWithSpaces)); } if (!string.IsNullOrEmpty(credentials.Events)) { Log.Register(new XmppEventSink("XMPP Event Sink", Client, credentials.Events, false)); } if (!string.IsNullOrEmpty(credentials.ThingRegistry)) { thingRegistryClient = new ThingRegistryClient(Client, credentials.ThingRegistry); thingRegistryClient.Claimed += (sender, e) => { ownerJid = e.JID; Log.Informational("Thing has been claimed.", ownerJid, new KeyValuePair <string, object>("Public", e.IsPublic)); return(Task.CompletedTask); }; thingRegistryClient.Disowned += (sender, e) => { Log.Informational("Thing has been disowned.", ownerJid); ownerJid = string.Empty; Register(); return(Task.CompletedTask); }; thingRegistryClient.Removed += (sender, e) => { Log.Informational("Thing has been removed from the public registry.", ownerJid); return(Task.CompletedTask); }; } ProvisioningClient ProvisioningClient = null; if (!string.IsNullOrEmpty(credentials.Provisioning)) { ProvisioningClient = new ProvisioningClient(Client, credentials.Provisioning); } Timer ConnectionTimer = new Timer((P) => { if (Client.State == XmppState.Offline || Client.State == XmppState.Error || Client.State == XmppState.Authenticating) { try { Client.Reconnect(); } catch (Exception ex) { Log.Critical(ex); } } }, null, 60000, 60000); bool Connected = false; bool ImmediateReconnect; Client.OnStateChanged += (sender, NewState) => { switch (NewState) { case XmppState.Connected: Connected = true; if (!registered && thingRegistryClient != null) { Register(); } break; case XmppState.Offline: ImmediateReconnect = Connected; Connected = false; if (ImmediateReconnect) { Client.Reconnect(); } break; } return(Task.CompletedTask); }; Client.OnPresenceSubscribe += (sender, e) => { e.Accept(); // TODO: Provisioning RosterItem Item = Client.GetRosterItem(e.FromBareJID); if (Item is null || Item.State == SubscriptionState.None || Item.State == SubscriptionState.From) { Client.RequestPresenceSubscription(e.FromBareJID); } Client.SetPresence(Availability.Chat); return(Task.CompletedTask); }; Client.OnPresenceUnsubscribe += (sender, e) => { e.Accept(); return(Task.CompletedTask); }; Client.OnRosterItemUpdated += (sender, e) => { if (e.State == SubscriptionState.None && e.PendingSubscription != PendingSubscription.Subscribe) { Client.RemoveRosterItem(e.BareJid); } return(Task.CompletedTask); }; SortedDictionary <string, string[]> CategoryIncluded = new SortedDictionary <string, string[]>(); List <string> Instances = new List <string>(); XmlDocument Doc = new XmlDocument() { PreserveWhitespace = true }; Doc.Load("categories.xml"); XSL.Validate("categories.xml", Doc, "Categories", "http://waher.se/Schema/PerformanceCounterCategories.xsd", XSL.LoadSchema("Waher.Service.PcSensor.Schema.PerformanceCounterCategories.xsd")); foreach (XmlNode N in Doc.DocumentElement.ChildNodes) { if (N.LocalName == "Category") { XmlElement E = (XmlElement)N; string Name = XML.Attribute(E, "name"); bool Include = XML.Attribute(E, "include", false); if (Include) { Instances.Clear(); foreach (XmlNode N2 in N.ChildNodes) { if (N2.LocalName == "Instance") { E = (XmlElement)N2; Instances.Add(XML.Attribute(E, "name")); } } CategoryIncluded[Name] = Instances.ToArray(); } else { CategoryIncluded[Name] = null; } } } SensorServer SensorServer = new SensorServer(Client, ProvisioningClient, false); SensorServer.OnExecuteReadoutRequest += (Sender, Request) => { Log.Informational("Readout requested", string.Empty, Request.Actor); List <Field> Fields = new List <Field>(); DateTime Now = DateTime.Now; Fields.Add(new StringField(ThingReference.Empty, Now, "Machine Name", Environment.MachineName, FieldType.Identity, FieldQoS.AutomaticReadout)); Fields.Add(new StringField(ThingReference.Empty, Now, "OS Platform", Environment.OSVersion.Platform.ToString(), FieldType.Identity, FieldQoS.AutomaticReadout)); Fields.Add(new StringField(ThingReference.Empty, Now, "OS Service Pack", Environment.OSVersion.ServicePack, FieldType.Identity, FieldQoS.AutomaticReadout)); Fields.Add(new StringField(ThingReference.Empty, Now, "OS Version", Environment.OSVersion.VersionString, FieldType.Identity, FieldQoS.AutomaticReadout)); Fields.Add(new Int32Field(ThingReference.Empty, Now, "Processor Count", Environment.ProcessorCount, FieldType.Status, FieldQoS.AutomaticReadout)); string[] InstanceNames; string FieldName; string Unit; double Value; byte NrDec; bool Updated = false; foreach (PerformanceCounterCategory Category in PerformanceCounterCategory.GetCategories()) { FieldName = Category.CategoryName; lock (CategoryIncluded) { if (CategoryIncluded.TryGetValue(FieldName, out InstanceNames)) { if (InstanceNames is null) { continue; } } else { CategoryIncluded[FieldName] = null; Updated = true; continue; } } if (Category.CategoryType == PerformanceCounterCategoryType.MultiInstance) { foreach (string InstanceName in Category.GetInstanceNames()) { if (InstanceNames.Length > 0 && Array.IndexOf <string>(InstanceNames, InstanceName) < 0) { continue; } foreach (PerformanceCounter Counter in Category.GetCounters(InstanceName)) { FieldName = Category.CategoryName + ", " + InstanceName + ", " + Counter.CounterName; Value = Counter.NextValue(); GetUnitPrecision(ref FieldName, Value, out NrDec, out Unit); if (Fields.Count >= 100) { Request.ReportFields(false, Fields); Fields.Clear(); } Fields.Add(new QuantityField(ThingReference.Empty, Now, FieldName, Value, NrDec, Unit, FieldType.Momentary, FieldQoS.AutomaticReadout)); } } } else { foreach (PerformanceCounter Counter in Category.GetCounters()) { FieldName = Category.CategoryName + ", " + Counter.CounterName; Value = Counter.NextValue(); GetUnitPrecision(ref FieldName, Value, out NrDec, out Unit); if (Fields.Count >= 100) { Request.ReportFields(false, Fields); Fields.Clear(); } Fields.Add(new QuantityField(ThingReference.Empty, Now, FieldName, Value, NrDec, Unit, FieldType.Momentary, FieldQoS.AutomaticReadout)); } } } Request.ReportFields(true, Fields); if (Updated) { using (StreamWriter s = File.CreateText("categories.xml")) { using (XmlWriter w = XmlWriter.Create(s, XML.WriterSettings(true, false))) { w.WriteStartElement("Categories", "http://waher.se/Schema/PerformanceCounterCategories.xsd"); lock (CategoryIncluded) { foreach (KeyValuePair <string, string[]> P in CategoryIncluded) { w.WriteStartElement("Category"); w.WriteAttributeString("name", P.Key); w.WriteAttributeString("include", CommonTypes.Encode(P.Value != null)); if (P.Value != null) { foreach (string InstanceName in P.Value) { w.WriteStartElement("Instance"); w.WriteAttributeString("name", P.Key); w.WriteEndElement(); } } w.WriteEndElement(); } } w.WriteEndElement(); w.Flush(); } } } return(Task.CompletedTask); }; BobClient BobClient = new BobClient(Client, Path.Combine(Path.GetTempPath(), "BitsOfBinary")); ChatServer ChatServer = new ChatServer(Client, BobClient, SensorServer, ProvisioningClient); Client.Connect(); while (true) { Thread.Sleep(1000); } } } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.Out.WriteLine(ex.Message); } finally { Log.Terminate(); } }
public static void Main(string[] args) { try { Console.ForegroundColor = ConsoleColor.White; Console.Out.WriteLine("Welcome to the Mock Temperature sensor application."); Console.Out.WriteLine(new string('-', 79)); Console.Out.WriteLine("This application will simulate an outside temperature sensor."); Console.Out.WriteLine("Values will be published over XMPP using the interface defined in the IEEE XMPP IoT extensions."); Console.Out.WriteLine("You can also chat with the sensor."); Log.Register(new ConsoleEventSink()); Log.RegisterExceptionToUnnest(typeof(System.Runtime.InteropServices.ExternalException)); Log.RegisterExceptionToUnnest(typeof(System.Security.Authentication.AuthenticationException)); 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(Program).Assembly); using (XmppClient Client = xmppConfiguration.GetClient("en", typeof(Program).Assembly, false)) { Client.AllowRegistration(FormSignatureKey, FormSignatureSecret); if (xmppConfiguration.Sniffer) { Client.Add(new ConsoleOutSniffer(BinaryPresentationMethod.ByteCount, LineEnding.PadWithSpaces)); } if (!string.IsNullOrEmpty(xmppConfiguration.Events)) { Log.Register(new XmppEventSink("XMPP Event Sink", Client, xmppConfiguration.Events, false)); } if (!string.IsNullOrEmpty(xmppConfiguration.ThingRegistry)) { thingRegistryClient = new ThingRegistryClient(Client, xmppConfiguration.ThingRegistry); thingRegistryClient.Claimed += (sender, e) => { ownerJid = e.JID; Log.Informational("Thing has been claimed.", ownerJid, new KeyValuePair <string, object>("Public", e.IsPublic)); }; thingRegistryClient.Disowned += (sender, e) => { Log.Informational("Thing has been disowned.", ownerJid); ownerJid = string.Empty; Register(); }; thingRegistryClient.Removed += (sender, e) => { Log.Informational("Thing has been removed from the public registry.", ownerJid); }; } ProvisioningClient ProvisioningClient = null; if (!string.IsNullOrEmpty(xmppConfiguration.Provisioning)) { ProvisioningClient = new ProvisioningClient(Client, xmppConfiguration.Provisioning); } Timer ConnectionTimer = new Timer((P) => { if (Client.State == XmppState.Offline || Client.State == XmppState.Error || Client.State == XmppState.Authenticating) { try { Client.Reconnect(); } catch (Exception ex) { Log.Critical(ex); } } }, null, 60000, 60000); bool Connected = false; bool ImmediateReconnect; Client.OnStateChanged += (sender, NewState) => { switch (NewState) { case XmppState.Connected: Connected = true; if (!registered && thingRegistryClient != null) { Register(); } break; case XmppState.Offline: ImmediateReconnect = Connected; Connected = false; if (ImmediateReconnect) { Client.Reconnect(); } break; } }; Client.OnPresenceSubscribe += (sender, e) => { e.Accept(); // TODO: Provisioning RosterItem Item = Client.GetRosterItem(e.FromBareJID); if (Item == null || Item.State == SubscriptionState.None || Item.State == SubscriptionState.From) { Client.RequestPresenceSubscription(e.FromBareJID); } Client.SetPresence(Availability.Chat); }; Client.OnPresenceUnsubscribe += (sender, e) => { e.Accept(); }; Client.OnRosterItemUpdated += (sender, e) => { if (e.State == SubscriptionState.None && e.PendingSubscription != PendingSubscription.Subscribe) { Client.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 = ReadTemp(); double MinTemp = CurrentTemperature; double MaxTemp = CurrentTemperature; double SumTemp = CurrentTemperature; int NrTemp = 1; int NrDayRecords = 0; int NrMinuteRecords = 0; object SampleSynch = new object(); SensorServer SensorServer = new SensorServer(Client, ProvisioningClient, true); SensorServer.OnExecuteReadoutRequest += (Sender, Request) => { Log.Informational("Readout requested", 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); }; Timer 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 = 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 (SensorServer.HasSubscriptions(ThingReference.Empty)) { SensorServer.NewMomentaryValues(new QuantityField(ThingReference.Empty, SampleTime, "Temperature", CurrentTemperature, 1, "°C", FieldType.Momentary, FieldQoS.AutomaticReadout)); } }, null, 1000 - PeriodStart.Millisecond, 1000); BobClient BobClient = new BobClient(Client, Path.Combine(Path.GetTempPath(), "BitsOfBinary")); ChatServer ChatServer = new ChatServer(Client, BobClient, SensorServer); InteroperabilityServer InteroperabilityServer = new InteroperabilityServer(Client); 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"); }; Client.Connect(); while (true) { Thread.Sleep(1000); } } } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.Out.WriteLine(ex.Message); } finally { Log.Terminate(); } }
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(); } }
public override void PopulateDetailsDialog(QuestionView QuestionView, ProvisioningClient ProvisioningClient) { StackPanel Details = QuestionView.Details; TextBlock TextBlock; ListBox ListBox; Button Button; this.client = ProvisioningClient; this.questionView = QuestionView; Details.Children.Add(new TextBlock() { FontSize = 18, FontWeight = FontWeights.Bold, Text = "Allowed to control?" }); Details.Children.Add(TextBlock = new TextBlock() { TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 6, 0, 6) }); TextBlock.Inlines.Add("Device: "); this.AddJidName(this.JID, ProvisioningClient, TextBlock); this.AddNodeInfo(Details); Details.Children.Add(TextBlock = new TextBlock() { TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 6, 0, 6) }); TextBlock.Inlines.Add("Caller: "); this.AddJidName(this.RemoteJID, ProvisioningClient, TextBlock); Details.Children.Add(new Label() { Content = "Parameter restriction:", Margin = new Thickness(0, 6, 0, 0) }); Details.Children.Add(ListBox = new ListBox() { MaxHeight = 150, SelectionMode = SelectionMode.Multiple, Margin = new Thickness(0, 0, 0, 6) }); this.parametersListBox = ListBox; if (this.availableParameterNames == null) { if (this.parameterNames != null) { foreach (string ParameterName in this.parameterNames) { ListBox.Items.Add(new ListBoxItem() { Content = ParameterName, IsSelected = true, Tag = ParameterName }); } } } else { foreach (string ParameterName in this.availableParameterNames) { ListBox.Items.Add(new ListBoxItem() { Content = ParameterName, IsSelected = (this.parameterNames == null || Array.IndexOf <string>(this.parameterNames, ParameterName) >= 0), Tag = ParameterName }); } } StackPanel StackPanel = CanReadQuestion.AddAllClearButtons(Details, ListBox); if (this.availableParameterNames == null) { StackPanel.Children.Add(Button = new Button() { Margin = new Thickness(6, 6, 6, 6), Padding = new Thickness(20, 0, 20, 0), Content = "Get List", Tag = ListBox }); Button.Click += GetListButton_Click; } Details.Children.Add(TextBlock = new TextBlock() { TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 6, 0, 6), Text = "Is the caller allowed to control your device?" }); Details.Children.Add(Button = new Button() { Margin = new Thickness(0, 6, 0, 6), Content = "Yes" }); Button.Click += YesButton_Click; Details.Children.Add(Button = new Button() { Margin = new Thickness(0, 6, 0, 6), Content = "No" }); Button.Click += NoButton_Click; string s = this.RemoteJID; int i = s.IndexOf('@'); if (i >= 0) { s = s.Substring(i + 1); Details.Children.Add(Button = new Button() { Margin = new Thickness(0, 6, 0, 6), Content = "Yes, to anyone from " + s }); Button.Click += YesDomainButton_Click; Details.Children.Add(Button = new Button() { Margin = new Thickness(0, 6, 0, 6), Content = "No, to no one from " + s }); Button.Click += NoDomainButton_Click; } Details.Children.Add(Button = new Button() { Margin = new Thickness(0, 6, 0, 6), Content = "Yes, to anyone" }); Button.Click += YesAllButton_Click; Details.Children.Add(Button = new Button() { Margin = new Thickness(0, 6, 0, 6), Content = "No, to no one" }); Button.Click += NoAllButton_Click; this.AddTokens(Details, this.client, this.YesTokenButton_Click, this.NoTokenButton_Click); }
public override void PopulateDetailsDialog(QuestionView QuestionView, ProvisioningClient ProvisioningClient) { StackPanel Details = QuestionView.Details; TextBlock TextBlock; ListBox ListBox; Button Button; this.client = ProvisioningClient; this.questionView = QuestionView; Details.Children.Add(new TextBlock() { FontSize = 18, FontWeight = FontWeights.Bold, Text = "Allowed to read?" }); Details.Children.Add(TextBlock = new TextBlock() { TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 6, 0, 6) }); TextBlock.Inlines.Add("Device: "); this.AddJidName(this.JID, ProvisioningClient, TextBlock); this.AddNodeInfo(Details); Details.Children.Add(TextBlock = new TextBlock() { TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 6, 0, 6) }); TextBlock.Inlines.Add("Caller: "); this.AddJidName(this.RemoteJID, ProvisioningClient, TextBlock); Details.Children.Add(new Label() { Content = "Categories:", Margin = new Thickness(0, 6, 0, 0) }); Details.Children.Add(ListBox = new ListBox() { SelectionMode = SelectionMode.Multiple, Margin = new Thickness(0, 0, 0, 6) }); this.typesListBox = ListBox; ListBox.Items.Add(new ListBoxItem() { Content = "Momentary values", IsSelected = (this.categories & FieldType.Momentary) != 0, Tag = FieldType.Momentary }); ListBox.Items.Add(new ListBoxItem() { Content = "Identity values", IsSelected = (this.categories & FieldType.Identity) != 0, Tag = FieldType.Identity }); ListBox.Items.Add(new ListBoxItem() { Content = "Status values", IsSelected = (this.categories & FieldType.Status) != 0, Tag = FieldType.Status }); ListBox.Items.Add(new ListBoxItem() { Content = "Computed values", IsSelected = (this.categories & FieldType.Computed) != 0, Tag = FieldType.Computed }); ListBox.Items.Add(new ListBoxItem() { Content = "Peak values", IsSelected = (this.categories & FieldType.Peak) != 0, Tag = FieldType.Peak }); ListBox.Items.Add(new ListBoxItem() { Content = "Historical values", IsSelected = (this.categories & FieldType.Historical) != 0, Tag = FieldType.Historical }); AddAllClearButtons(Details, ListBox); Details.Children.Add(new Label() { Content = "Field restriction:", Margin = new Thickness(0, 6, 0, 0) }); Details.Children.Add(ListBox = new ListBox() { MaxHeight = 150, SelectionMode = SelectionMode.Multiple, Margin = new Thickness(0, 0, 0, 6) }); this.fieldsListBox = ListBox; if (this.availableFieldNames is null) { if (this.fieldNames != null) { foreach (string FieldName in this.fieldNames) { ListBox.Items.Add(new ListBoxItem() { Content = FieldName, IsSelected = true, Tag = FieldName }); } } } else { foreach (string FieldName in this.availableFieldNames) { ListBox.Items.Add(new ListBoxItem() { Content = FieldName, IsSelected = (this.fieldNames is null || Array.IndexOf <string>(this.fieldNames, FieldName) >= 0), Tag = FieldName });
/// <summary> /// Stops the gateway. /// </summary> public static void Stop() { IDisposable Disposable; Log.Informational("Server shutting down."); /* * if (databaseProvider != null) * File.WriteAllText(appDataFolder + "Stop.xml", databaseProvider.ExportXml(true).Result); */ if (gatewayRunning != null) { gatewayRunning.Release(); gatewayRunning.Dispose(); gatewayRunning = null; } if (ibbClient != null) { ibbClient.Dispose(); ibbClient = null; } if (httpxServer != null) { httpxServer.Dispose(); httpxServer = null; } if (provisioningClient != null) { provisioningClient.Dispose(); provisioningClient = null; } if (thingRegistryClient != null) { thingRegistryClient.Dispose(); thingRegistryClient = null; } if (concentratorServer != null) { concentratorServer.Dispose(); concentratorServer = null; } if (xmppClient != null) { using (ManualResetEvent OfflineSent = new ManualResetEvent(false)) { xmppClient.SetPresence(Availability.Offline, string.Empty, (sender, e) => OfflineSent.Set()); OfflineSent.WaitOne(1000); } foreach (ISniffer Sniffer in xmppClient.Sniffers) { XmppClient.Remove(Sniffer); Disposable = Sniffer as IDisposable; if (Disposable != null) { Disposable.Dispose(); } } xmppClient.Dispose(); xmppClient = null; } if (connectionTimer != null) { connectionTimer.Dispose(); connectionTimer = null; } if (coapEndpoint != null) { coapEndpoint.Dispose(); coapEndpoint = null; } if (webServer != null) { foreach (ISniffer Sniffer in webServer.Sniffers) { webServer.Remove(Sniffer); Disposable = Sniffer as IDisposable; if (Disposable != null) { Disposable.Dispose(); } } webServer.Dispose(); webServer = null; } clientEvents = null; }
/// <summary> /// Starts the gateway. /// </summary> /// <param name="ConsoleOutput">If console output is permitted.</param> public static bool Start(bool ConsoleOutput) { gatewayRunning = new Semaphore(1, 1, "Waher.IoTGateway.Running"); if (!gatewayRunning.WaitOne(1000)) { return(false); // Is running in another process. } Semaphore StartingServer = new Semaphore(1, 1, "Waher.IoTGateway.Starting"); if (!StartingServer.WaitOne(1000)) { gatewayRunning.Release(); gatewayRunning.Dispose(); gatewayRunning = null; StartingServer.Dispose(); return(false); // Being started in another process. } try { Initialize(); appDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); if (!appDataFolder.EndsWith(new string(Path.DirectorySeparatorChar, 1))) { appDataFolder += Path.DirectorySeparatorChar; } appDataFolder += "IoT Gateway" + Path.DirectorySeparatorChar; Log.Register(new XmlFileEventSink("XML File Event Sink", appDataFolder + "Events" + Path.DirectorySeparatorChar + "Event Log %YEAR%-%MONTH%-%DAY%T%HOUR%.xml", appDataFolder + "Transforms" + Path.DirectorySeparatorChar + "EventXmlToHtml.xslt", 7)); Log.Informational("Server starting up."); beforeUninstallCommandNr = Gateway.RegisterServiceCommand(BeforeUninstall); rootFolder = appDataFolder + "Root" + Path.DirectorySeparatorChar; if (!Directory.Exists(rootFolder)) { appDataFolder = string.Empty; rootFolder = "Root" + Path.DirectorySeparatorChar; } Types.SetModuleParameter("AppData", appDataFolder); Types.SetModuleParameter("Root", rootFolder); scheduler = new Scheduler(); rnd = RandomNumberGenerator.Create(); Task.Run(() => CodeContent.GraphViz.Init()); XmlDocument Config = new XmlDocument(); string GatewayConfigFileName = appDataFolder + "Gateway.config"; if (!File.Exists(GatewayConfigFileName)) { GatewayConfigFileName = "Gateway.config"; } Config.Load(GatewayConfigFileName); XSL.Validate("Gateway.config", Config, "GatewayConfiguration", "http://waher.se/Schema/GatewayConfiguration.xsd", XSL.LoadSchema(typeof(Gateway).Namespace + ".Schema.GatewayConfiguration.xsd", typeof(Gateway).Assembly)); domain = Config.DocumentElement["Domain"].InnerText; XmlElement DatabaseConfig = Config.DocumentElement["Database"]; if (!CommonTypes.TryParse(DatabaseConfig.Attributes["encrypted"].Value, out bool Encrypted)) { Encrypted = true; } databaseProvider = new FilesProvider(appDataFolder + DatabaseConfig.Attributes["folder"].Value, DatabaseConfig.Attributes["defaultCollectionName"].Value, int.Parse(DatabaseConfig.Attributes["blockSize"].Value), int.Parse(DatabaseConfig.Attributes["blocksInCache"].Value), int.Parse(DatabaseConfig.Attributes["blobBlockSize"].Value), Encoding.UTF8, int.Parse(DatabaseConfig.Attributes["timeoutMs"].Value), Encrypted, false); Database.Register(databaseProvider); PersistedEventLog PersistedEventLog = new PersistedEventLog(7, new TimeSpan(4, 15, 0)); Log.Register(PersistedEventLog); PersistedEventLog.Queue(new Event(EventType.Informational, "Server starting up.", string.Empty, string.Empty, string.Empty, EventLevel.Minor, string.Empty, string.Empty, string.Empty)); xmppConfigFileName = Config.DocumentElement["XmppClient"].Attributes["configFileName"].Value; if (!File.Exists(xmppConfigFileName)) { xmppConfigFileName = appDataFolder + xmppConfigFileName; } if (ConsoleOutput) { xmppConfiguration = SimpleXmppConfiguration.GetConfigUsingSimpleConsoleDialog(xmppConfigFileName, Guid.NewGuid().ToString().Replace("-", string.Empty), // Default user name. Guid.NewGuid().ToString().Replace("-", string.Empty), // Default password. FormSignatureKey, FormSignatureSecret, typeof(Gateway).Assembly); } else if (File.Exists(xmppConfigFileName)) { xmppConfiguration = new SimpleXmppConfiguration(xmppConfigFileName); RuntimeSettings.Set("XMPP.CONFIG", xmppConfiguration.ExportSimpleXmppConfiguration()); } else { string XmppConfig = RuntimeSettings.Get("XMPP.CONFIG", string.Empty); XmlDocument Doc = new XmlDocument(); Doc.LoadXml(XmppConfig); xmppConfiguration = new SimpleXmppConfiguration(Doc); } xmppClient = xmppConfiguration.GetClient("en", typeof(Gateway).Assembly, false); xmppClient.AllowRegistration(FormSignatureKey, FormSignatureSecret); xmppClient.OnValidateSender += XmppClient_OnValidateSender; Types.SetModuleParameter("XMPP", xmppClient); if (xmppConfiguration.Sniffer) { ISniffer Sniffer; if (ConsoleOutput) { Sniffer = new ConsoleOutSniffer(BinaryPresentationMethod.ByteCount, LineEnding.PadWithSpaces); xmppClient.Add(Sniffer); } Sniffer = new XmlFileSniffer(appDataFolder + "XMPP" + Path.DirectorySeparatorChar + "XMPP Log %YEAR%-%MONTH%-%DAY%T%HOUR%.xml", appDataFolder + "Transforms" + Path.DirectorySeparatorChar + "SnifferXmlToHtml.xslt", 7, BinaryPresentationMethod.ByteCount); xmppClient.Add(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 += ThingRegistryClient_Claimed; thingRegistryClient.Disowned += ThingRegistryClient_Disowned; thingRegistryClient.Removed += ThingRegistryClient_Removed; } if (!string.IsNullOrEmpty(xmppConfiguration.Provisioning)) { provisioningClient = new ProvisioningClient(xmppClient, xmppConfiguration.Provisioning); } DateTime Now = DateTime.Now; int MsToNext = 60000 - (Now.Second * 1000 + Now.Millisecond); connectionTimer = new Timer(CheckConnection, null, MsToNext, 60000); xmppClient.OnStateChanged += XmppClient_OnStateChanged; xmppClient.OnPresenceSubscribe += XmppClient_OnPresenceSubscribe; xmppClient.OnPresenceUnsubscribe += XmppClient_OnPresenceUnsubscribe; xmppClient.OnRosterItemUpdated += XmppClient_OnRosterItemUpdated; ibbClient = new Networking.XMPP.InBandBytestreams.IbbClient(xmppClient, MaxChunkSize); Types.SetModuleParameter("IBB", ibbClient); socksProxy = new Networking.XMPP.P2P.SOCKS5.Socks5Proxy(xmppClient); Types.SetModuleParameter("SOCKS5", socksProxy); string CertificateLocalFileName = Config.DocumentElement["Certificate"].Attributes["configFileName"].Value; string CertificateFileName; string CertificateXml; string CertificatePassword; byte[] CertificateRaw; try { CertificateRaw = Convert.FromBase64String(RuntimeSettings.Get("CERTIFICATE.BASE64", string.Empty)); CertificatePassword = RuntimeSettings.Get("CERTIFICATE.PWD", string.Empty); certificate = new X509Certificate2(CertificateRaw, CertificatePassword); } catch (Exception) { certificate = null; } if (File.Exists(CertificateFileName = appDataFolder + CertificateLocalFileName)) { CertificateXml = File.ReadAllText(CertificateFileName); } else if (File.Exists(CertificateFileName = CertificateLocalFileName) && certificate == null) { CertificateXml = File.ReadAllText(CertificateFileName); } else { CertificateFileName = null; CertificateXml = null; } if (CertificateXml != null) { XmlDocument CertificateConfig = new XmlDocument(); CertificateConfig.LoadXml(CertificateXml); XSL.Validate(CertificateLocalFileName, CertificateConfig, "CertificateConfiguration", "http://waher.se/Schema/CertificateConfiguration.xsd", XSL.LoadSchema(typeof(Gateway).Namespace + ".Schema.CertificateConfiguration.xsd", typeof(Gateway).Assembly)); CertificateLocalFileName = CertificateConfig.DocumentElement["FileName"].InnerText; if (File.Exists(appDataFolder + CertificateLocalFileName)) { CertificateLocalFileName = appDataFolder + CertificateLocalFileName; } CertificateRaw = File.ReadAllBytes(CertificateLocalFileName); CertificatePassword = CertificateConfig.DocumentElement["Password"].InnerText; certificate = new X509Certificate2(CertificateRaw, CertificatePassword); RuntimeSettings.Set("CERTIFICATE.BASE64", Convert.ToBase64String(CertificateRaw)); RuntimeSettings.Set("CERTIFICATE.PWD", CertificatePassword); if (CertificateLocalFileName != "certificate.pfx" || CertificatePassword != "testexamplecom") { try { File.Delete(CertificateLocalFileName); } catch (Exception) { Log.Warning("Unable to delete " + CertificateLocalFileName + " after importing it into the encrypted database."); } try { File.Delete(CertificateFileName); } catch (Exception) { Log.Warning("Unable to delete " + CertificateFileName + " after importing it into the encrypted database."); } } } foreach (XmlNode N in Config.DocumentElement["Ports"].ChildNodes) { if (N.LocalName == "Port") { XmlElement E = (XmlElement)N; string Protocol = XML.Attribute(E, "protocol"); if (!string.IsNullOrEmpty(Protocol) && int.TryParse(E.InnerText, out int Port)) { ports.AddLast(new KeyValuePair <string, int>(Protocol, Port)); } } } webServer = new HttpServer(GetConfigPorts("HTTP"), GetConfigPorts("HTTPS"), certificate); Types.SetModuleParameter("HTTP", webServer); StringBuilder sb = new StringBuilder(); foreach (int Port in webServer.OpenPorts) { sb.AppendLine(Port.ToString()); } try { File.WriteAllText(appDataFolder + "Ports.txt", sb.ToString()); } catch (Exception ex) { Log.Critical(ex); } HttpFolderResource HttpFolderResource; HttpxProxy HttpxProxy; webServer.Register(new HttpFolderResource("/Graphics", "Graphics", false, false, true, false)); // TODO: Add authentication mechanisms for PUT & DELETE. webServer.Register(new HttpFolderResource("/highlight", "Highlight", false, false, true, false)); // Syntax highlighting library, provided by http://highlightjs.org webServer.Register(HttpFolderResource = new HttpFolderResource(string.Empty, rootFolder, false, false, true, true)); // TODO: Add authentication mechanisms for PUT & DELETE. webServer.Register(HttpxProxy = new HttpxProxy("/HttpxProxy", xmppClient, MaxChunkSize)); webServer.Register("/", (req, resp) => { throw new TemporaryRedirectException(Config.DocumentElement["DefaultPage"].InnerText); }); webServer.Register(clientEvents = new ClientEvents()); HttpFolderResource.AllowTypeConversion(); MarkdownToHtmlConverter.EmojiSource = Emoji1_24x24; XmlElement FileFolders = Config.DocumentElement["FileFolders"]; if (FileFolders != null) { foreach (XmlNode N in FileFolders.ChildNodes) { if (N is XmlElement E && E.LocalName == "FileFolder") { string WebFolder = XML.Attribute(E, "webFolder"); string FolderPath = XML.Attribute(E, "folderPath"); webServer.Register(new HttpFolderResource(WebFolder, FolderPath, false, false, true, true)); } } } httpxServer = new HttpxServer(xmppClient, webServer, MaxChunkSize); Types.SetModuleParameter("HTTPX", HttpxProxy); Types.SetModuleParameter("HTTPXS", httpxServer); HttpxProxy.IbbClient = ibbClient; httpxServer.IbbClient = ibbClient; HttpxProxy.Socks5Proxy = socksProxy; httpxServer.Socks5Proxy = socksProxy; if (xmppConfiguration.Sniffer) { ISniffer Sniffer; Sniffer = new XmlFileSniffer(appDataFolder + "HTTP" + Path.DirectorySeparatorChar + "HTTP Log %YEAR%-%MONTH%-%DAY%T%HOUR%.xml", appDataFolder + "Transforms" + Path.DirectorySeparatorChar + "SnifferXmlToHtml.xslt", 7, BinaryPresentationMethod.ByteCount); webServer.Add(Sniffer); } coapEndpoint = new CoapEndpoint(); Types.SetModuleParameter("CoAP", coapEndpoint); concentratorServer = new ConcentratorServer(xmppClient, provisioningClient, new MeteringTopology()); Types.SetModuleParameter("Concentrator", concentratorServer); Types.SetModuleParameter("Sensor", concentratorServer.SensorServer); Types.SetModuleParameter("Control", concentratorServer.ControlServer); } catch (Exception ex) { Log.Critical(ex); gatewayRunning.Release(); gatewayRunning.Dispose(); gatewayRunning = null; StartingServer.Release(); StartingServer.Dispose(); ExceptionDispatchInfo.Capture(ex).Throw(); } Task.Run(async() => { try { try { string BinaryFolder = AppDomain.CurrentDomain.BaseDirectory; string[] LanguageFiles = Directory.GetFiles(BinaryFolder, "*.lng", SearchOption.AllDirectories); string FileName; if (LanguageFiles.Length > 0) { XmlSchema Schema = XSL.LoadSchema(Translator.SchemaResource, typeof(Translator).Assembly); foreach (string LanguageFile in LanguageFiles) { try { FileName = LanguageFile; if (FileName.StartsWith(BinaryFolder)) { FileName = FileName.Substring(BinaryFolder.Length); } DateTime LastWriteTime = File.GetLastWriteTime(LanguageFile); DateTime LastImportedTime = await RuntimeSettings.GetAsync(FileName, DateTime.MinValue); if (LastWriteTime > LastImportedTime) { Log.Informational("Importing language file.", FileName); string Xml = File.ReadAllText(LanguageFile); XmlDocument Doc = new XmlDocument(); Doc.LoadXml(Xml); XSL.Validate(FileName, Doc, Translator.SchemaRoot, Translator.SchemaNamespace, Schema); using (XmlReader r = new XmlNodeReader(Doc)) { await Translator.ImportAsync(r); } RuntimeSettings.Set(FileName, LastWriteTime); } } catch (Exception ex) { Log.Critical(ex, LanguageFile); } } } Types.StartAllModules(int.MaxValue); } finally { StartingServer.Release(); StartingServer.Dispose(); } } catch (Exception ex) { Log.Critical(ex); } finally { xmppClient.Connect(); } }); return(true); }
static void Main(string[] args) { try { Console.ForegroundColor = ConsoleColor.White; Console.Out.WriteLine("Welcome to the Mock Temperature sensor application."); Console.Out.WriteLine(new string('-', 79)); Console.Out.WriteLine("This application will simulate an outside temperature sensor."); Console.Out.WriteLine("Values will be published over XMPP using the interface defined in the IEEE XMPP IoT extensions."); Console.Out.WriteLine("You can also chat with the sensor."); Log.Register(new ConsoleEventSink()); Log.RegisterExceptionToUnnest(typeof(System.Runtime.InteropServices.ExternalException)); Log.RegisterExceptionToUnnest(typeof(System.Security.Authentication.AuthenticationException)); credentials = SimpleXmppConfiguration.GetConfigUsingSimpleConsoleDialog("xmpp.config", Guid.NewGuid().ToString().Replace("-", string.Empty), // Default user name. Guid.NewGuid().ToString().Replace("-", string.Empty), // Default password. typeof(Program).Assembly); using (XmppClient Client = new XmppClient(credentials, "en", typeof(Program).Assembly)) { if (credentials.Sniffer) { Client.Add(new ConsoleOutSniffer(BinaryPresentationMethod.ByteCount, LineEnding.PadWithSpaces)); } if (!string.IsNullOrEmpty(credentials.Events)) { Log.Register(new XmppEventSink("XMPP Event Sink", Client, credentials.Events, false)); } if (!string.IsNullOrEmpty(credentials.ThingRegistry)) { thingRegistryClient = new ThingRegistryClient(Client, credentials.ThingRegistry); thingRegistryClient.Claimed += (sender, e) => { ownerJid = e.JID; Log.Informational("Thing has been claimed.", ownerJid, new KeyValuePair <string, object>("Public", e.IsPublic)); }; thingRegistryClient.Disowned += (sender, e) => { Log.Informational("Thing has been disowned.", ownerJid); ownerJid = string.Empty; Register(); }; thingRegistryClient.Removed += (sender, e) => { Log.Informational("Thing has been removed from the public registry.", ownerJid); }; } ProvisioningClient ProvisioningClient = null; if (!string.IsNullOrEmpty(credentials.Provisioning)) { ProvisioningClient = new ProvisioningClient(Client, credentials.Provisioning); } Timer ConnectionTimer = new Timer((P) => { if (Client.State == XmppState.Offline || Client.State == XmppState.Error || Client.State == XmppState.Authenticating) { try { Client.Reconnect(); } catch (Exception ex) { Log.Critical(ex); } } }, null, 60000, 60000); bool Connected = false; bool ImmediateReconnect; Client.OnStateChanged += (sender, NewState) => { switch (NewState) { case XmppState.Connected: Connected = true; if (!registered && thingRegistryClient != null) { Register(); } break; case XmppState.Offline: ImmediateReconnect = Connected; Connected = false; if (ImmediateReconnect) { Client.Reconnect(); } break; } }; Client.OnPresenceSubscribe += (sender, e) => { e.Accept(); // TODO: Provisioning RosterItem Item = Client.GetRosterItem(e.FromBareJID); if (Item is null || Item.State == SubscriptionState.None || Item.State == SubscriptionState.From) { Client.RequestPresenceSubscription(e.FromBareJID); } Client.SetPresence(Availability.Chat); }; Client.OnPresenceUnsubscribe += (sender, e) => { e.Accept(); }; Client.OnRosterItemUpdated += (sender, e) => { if (e.State == SubscriptionState.None && e.PendingSubscription != PendingSubscription.Subscribe) { Client.RemoveRosterItem(e.BareJid); } }; bool SwitchOn = false; SensorServer SensorServer = new SensorServer(Client, 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 ControlServer = new ControlServer(Client, new BooleanControlParameter("Lamp", "Control", "Lamp switch on.", "If checked, lamp is turned on.", (Node) => SwitchOn, (Node, Value) => { SwitchOn = Value; Log.Informational(Environment.NewLine + Environment.NewLine + "Lamp turned " + (SwitchOn ? "ON" : "OFF") + Environment.NewLine + Environment.NewLine); })); BobClient BobClient = new BobClient(Client, Path.Combine(Path.GetTempPath(), "BitsOfBinary")); ChatServer ChatServer = new ChatServer(Client, BobClient, SensorServer, ControlServer, ProvisioningClient); InteroperabilityServer InteroperabilityServer = new InteroperabilityServer(Client); InteroperabilityServer.OnGetInterfaces += (sender, e) => { e.Add("XMPP.IoT.Actuator.Lamp"); }; Client.Connect(); while (true) { Thread.Sleep(1000); } } } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.Out.WriteLine(ex.Message); } finally { Log.Terminate(); } }
/// <summary> /// Invoked when application execution is being suspended. Application state is saved /// without knowing whether the application will be terminated or resumed with the contents /// of memory still intact. /// </summary> /// <param name="sender">The source of the suspend request.</param> /// <param name="e">Details about the suspend request.</param> private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); if (arduino != null) { arduino.digitalWrite(13, PinState.LOW); arduino.pinMode(13, PinMode.INPUT); // Onboard LED. arduino.Dispose(); arduino = null; } if (arduinoUsb != null) { arduinoUsb.end(); arduinoUsb.Dispose(); arduinoUsb = null; } if (gpioPins != null) { foreach (KeyValuePair<GpioPin, KeyValuePair<TextBlock, TextBlock>> Pin in gpioPins.Values) Pin.Key.Dispose(); gpioPins = null; } if (this.sampleTimer != null) { this.sampleTimer.Dispose(); this.sampleTimer = null; } if (this.chatServer != null) { this.chatServer.Dispose(); this.chatServer = null; } if (this.bobClient != null) { this.bobClient.Dispose(); this.bobClient = null; } if (this.controlServer != null) { this.controlServer.Dispose(); this.controlServer = null; } if (this.sensorServer != null) { this.sensorServer.Dispose(); this.sensorServer = null; } if (this.provisioningClient != null) { this.provisioningClient.Dispose(); this.provisioningClient = null; } if (this.thingRegistryClient != null) { this.thingRegistryClient.Dispose(); this.thingRegistryClient = null; } if (this.xmppClient != null) { this.xmppClient.Dispose(); this.xmppClient = null; } Log.Terminate(); deferral.Complete(); }
public override void PopulateDetailsDialog(QuestionView QuestionView, ProvisioningClient ProvisioningClient) { StackPanel Details = QuestionView.Details; TextBlock TextBlock; Button Button; this.client = ProvisioningClient; this.questionView = QuestionView; Details.Children.Add(new TextBlock() { FontSize = 18, FontWeight = FontWeights.Bold, Text = "Allowed to connect?" }); Details.Children.Add(TextBlock = new TextBlock() { TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 6, 0, 6) }); TextBlock.Inlines.Add("Device: "); this.AddJidName(this.JID, ProvisioningClient, TextBlock); Details.Children.Add(TextBlock = new TextBlock() { TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 6, 0, 6) }); TextBlock.Inlines.Add("Caller: "); this.AddJidName(this.RemoteJID, ProvisioningClient, TextBlock); Details.Children.Add(TextBlock = new TextBlock() { TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 6, 0, 6), Text = "Is the caller allowed to connect to your device?" }); Details.Children.Add(Button = new Button() { Margin = new Thickness(0, 6, 0, 6), Content = "Yes" }); Button.Click += YesButton_Click; Details.Children.Add(Button = new Button() { Margin = new Thickness(0, 6, 0, 6), Content = "No" }); Button.Click += NoButton_Click; string s = this.RemoteJID; int i = s.IndexOf('@'); if (i >= 0) { s = s.Substring(i + 1); Details.Children.Add(Button = new Button() { Margin = new Thickness(0, 6, 0, 6), Content = "Yes, to anyone from " + s }); Button.Click += YesDomainButton_Click; Details.Children.Add(Button = new Button() { Margin = new Thickness(0, 6, 0, 6), Content = "No, to no one from " + s }); Button.Click += NoDomainButton_Click; } Details.Children.Add(Button = new Button() { Margin = new Thickness(0, 6, 0, 6), Content = "Yes, to anyone" }); Button.Click += YesAllButton_Click; Details.Children.Add(Button = new Button() { Margin = new Thickness(0, 6, 0, 6), Content = "No, to no one" }); Button.Click += NoAllButton_Click; }
public abstract void PopulateDetailsDialog(QuestionView QuestionView, ProvisioningClient ProvisioningClient);