Beispiel #1
0
        /// <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)");
            }
        }
Beispiel #2
0
        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();
            }
        }
Beispiel #6
0
        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);
            }
        }
Beispiel #8
0
        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();
            }
        }
Beispiel #9
0
        /// <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);
            }
        }
Beispiel #10
0
		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();
            }
        }