Esempio n. 1
0
        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();
            }
        }
Esempio n. 2
0
        public void DataReported(MqttContent Content)
        {
            int Len = Content.Data.Length;

            if (Len == 0)
            {
                this.data = null;
                return;
            }

            this.dataCount += Len;

            try
            {
                if (this.data == null)
                {
                    this.data = this.FindDataType(Content);
                }
                else
                {
                    this.data.DataReported(Content);
                }

                this.SetOk();
            }
            catch (Exception)
            {
                try
                {
                    this.data = this.FindDataType(Content);
                }
                catch (Exception ex2)
                {
                    this.Exception(ex2);
                    return;
                }
            }

            if (this.broker.Client?.HasSniffers ?? false)
            {
                this.data.SnifferOutput(this.broker.Client);
            }

            if (Types.TryGetModuleParameter("Sensor", out object Obj) && Obj is SensorServer SensorServer)
            {
                try
                {
                    InternalReadoutRequest Request = new InternalReadoutRequest(string.Empty,
                                                                                new ThingReference[] { this.node }, FieldType.All, null, DateTime.MinValue, DateTime.MaxValue,
                                                                                (sender, e) =>
                    {
                        SensorServer.NewMomentaryValues(this.node, e.Fields);

                        MqttTopic Current = this;
                        MqttTopic Parent  = this.parent;

                        while (Parent != null)
                        {
                            foreach (Field F in e.Fields)
                            {
                                if (F.Name == "Value")
                                {
                                    F.Name = Current.localTopic;
                                }
                                else
                                {
                                    F.Name = Current.localTopic + ", " + F.Name;
                                }

                                SensorServer.NewMomentaryValues(Parent.node, F);
                            }

                            Current = Parent;
                            Parent  = Parent.parent;
                        }

                        return(Task.CompletedTask);
                    },
                                                                                (sender, e) =>
                    {
                        return(Task.CompletedTask);
                    }, null);

                    this.StartReadout(Request);
                }
                catch (Exception ex)
                {
                    this.Exception(ex);
                }
            }
        }