Exemplo n.º 1
0
        public override void Decode(string timestamp, string device, string topic, byte[] payload)
        {
            if (topic == UplinkPort1Topic)
            {
                ReadOnlySpan <byte> span = payload;

                double millivolts = payload[10];
                IoTHubMessageOrigin originWoPosition = new IoTHubMessageOrigin(device);
                _messageQueue.PostMessage(new SensorStatusMessage(originWoPosition, timestamp, millivolts * 0.025));

                double latitude      = BinaryPrimitives.ReadInt32LittleEndian(span.Slice(start: 0, length: 4));
                double longitude     = BinaryPrimitives.ReadInt32LittleEndian(span.Slice(start: 4, length: 4));
                bool   inTrip        = (payload[8] & 0x80) != 0;
                bool   lastFixFailed = (payload[8] & 0x40) != 0;
                double heading       = (payload[8] & 0x3F); // Maska bort de första två bitarna för att få heading
                double speed         = payload[9];

                // TODO: Bestäm vad som är ett bra filter här egentligen ...
                if (speed > 0)
                {
                    IoTHubMessageOrigin originWoDevice = new IoTHubMessageOrigin(latitude / 10000000.0, longitude / 10000000.0);
                    _messageQueue.PostMessage(new BicycleMovementMessage(originWoDevice, timestamp, heading * 5.625, speed));
                }
            }
        }
Exemplo n.º 2
0
            public SensorStatusMessage ToStatusMessage()
            {
                AVLProperty p = TwoByteIO.Find(x => x.ID == "67");

                if (p != null)
                {
                    double lat, lon;
                    Double.TryParse(Latitude, out lat);
                    Double.TryParse(Longitude, out lon);

                    DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                    dt = dt.AddMilliseconds(long.Parse(TimeStamp));

                    IoTHubMessageOrigin origin = new IoTHubMessageOrigin($"icom-{IMEI}", lat / 10000000.0, lon / 10000000.0);
                    return(new SensorStatusMessage(origin, dt.ToString("yyyy-MM-ddTHH:mm:ssZ"), p.Value / 1000.0));
                }

                return(null);
            }
Exemplo n.º 3
0
            public CarMovementMessage ToCarMovementMessage()
            {
                if (IsIgnitionOn())
                {
                    double lat, lon, heading, velocity;
                    Double.TryParse(Latitude, out lat);
                    Double.TryParse(Longitude, out lon);
                    Double.TryParse(Angle, out heading);
                    Double.TryParse(Speed, out velocity);

                    DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                    dt = dt.AddMilliseconds(long.Parse(TimeStamp));

                    IoTHubMessageOrigin origin = new IoTHubMessageOrigin(lat / 10000000.0, lon / 10000000.0);
                    return(new CarMovementMessage(origin, dt.ToString("yyyy-MM-ddTHH:mm:ssZ"), heading, velocity));
                }

                return(null);
            }
Exemplo n.º 4
0
        public override void Decode(string timestamp, string device, string topic, byte[] payload)
        {
            if (payload.Length != 19 || topic != WeatherTopic)
            {
                return;
            }

            ReadOnlySpan <byte> span = payload;

            // TODO: Denna hårdkodning gäller endast för den väderstation som sitter på MIUN, vi kommer
            //       att behöva hantera sensorposition på ett intelligentare sätt framöver när de blir fler.
            double latitude            = 62.391944;
            double longitude           = 17.285917;
            IoTHubMessageOrigin origin = new IoTHubMessageOrigin(device, latitude, longitude);

            double millivolts = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(start: 17, length: 2));

            _messageQueue.PostMessage(new SensorStatusMessage(origin, timestamp, millivolts / 1000.0));

            double temperature = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(start: 0, length: 2));

            _messageQueue.PostMessage(new TelemetryTemperature(origin, timestamp, (temperature - 4000) / 100.0));

            const double kmphToMpS = 1000.0 / 60.0 / 60.0;
            double       windspeed = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(start: 9, length: 2));

            windspeed = Math.Round(windspeed * kmphToMpS / 100.0, 2);

            int winddirection = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(start: 11, length: 2));

            _messageQueue.PostMessage(new TelemetryWind(origin, timestamp, windspeed, winddirection));

            double lux   = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(start: 13, length: 2));
            double uvidx = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(start: 15, length: 2));

            _messageQueue.PostMessage(new TelemetryLight(origin, timestamp, lux * 10, uvidx / 100.0));
        }
Exemplo n.º 5
0
 public TelemetryLight(IoTHubMessageOrigin origin, string timestamp, double lux, double uvIndex) : base(origin, timestamp, "telemetry.light")
 {
     Lux     = Math.Round(lux, 2);
     UvIndex = Math.Round(uvIndex, 2);
 }
Exemplo n.º 6
0
 public IoTHubMessage(IoTHubMessageOrigin origin, string timestamp, string topic)
 {
     Origin    = origin;
     Timestamp = timestamp;
     Topic     = topic;
 }
Exemplo n.º 7
0
        public override void Decode(string timestamp, string device, string topic, byte[] payload)
        {
            string json = Encoding.UTF8.GetString(payload);
            SnowdepthPayloadData data = JsonConvert.DeserializeObject <SnowdepthPayloadData>(json);

            payload = System.Convert.FromBase64String(data.Data);

            string deviceInHex = device;

            device = Int64.Parse(device, System.Globalization.NumberStyles.HexNumber).ToString();

            ReadOnlySpan <byte> span = payload;

            /*
             *  uint8_t   Battery [%]
             *  uint16_t  raw Distance [mm]
             *  uint16_t  Angle [deg]
             *  unit16_t  Vertical distance [mm]
             *  unit16_t  Snow depth [mm]
             *  unit16_t  Laser signal strength [0-400] (lower is better)
             *  uint8_t   Laser sensor status
             *  int16_t   Temperature [°C]F
             *  unit8_t   Humidity [%]
             *  unit32_t  Pressure [Pa]
             *
             *  DEVEUI:s
             *  1199411787624306471 Stöde 62.4081681,16.5687632
             *  1199411787624306472 Matfors 62.348384, 17.016098
             *  1199411787624306473 Njurunda 62.310288, 17.369975
             *  1199411787624306480 Sundsvall 62.392013, 17.285092
             *  1199411787624306481 Alnö 62.424865, 17.434870
             *  1199411787624306482 Sidsjö 62.374817, 17.269407
             *  1199411787624306483 Granloholm 62.409886, 17.270434
             *  1199411787624306484 Kovland 62.466341, 17.147527
             *  1199411787624306485 Fagerdalsparken 62.381662, 17.282563
             *  1199411787624306486 Finsta 62.461594, 17.345016
             */
            double latitude  = 1.348364;
            double longitude = 1.016056;

            if (device == "1199411787624306471")
            {
                latitude  = 62.4081681;
                longitude = 16.5687632;
            }
            else if (device == "1199411787624306472")
            {
                latitude  = 62.348384;
                longitude = 17.016098;
            }
            else if (device == "1199411787624306473")
            {
                latitude  = 62.310288;
                longitude = 17.369975;
            }
            else if (device == "1199411787624306480")
            {
                latitude  = 62.392013;
                longitude = 17.285092;
            }
            else if (device == "1199411787624306481")
            {
                latitude  = 62.424865;
                longitude = 17.434870;
            }
            else if (device == "1199411787624306483")
            {
                latitude  = 62.409886;
                longitude = 17.270434;
            }
            else if (device == "1199411787624306482")
            {
                latitude  = 62.374817;
                longitude = 17.269407;
            }
            else if (device == "1199411787624306484")
            {
                latitude  = 62.466341;
                longitude = 17.147527;
            }
            else if (device == "1199411787624306485")
            {
                latitude  = 62.381662;
                longitude = 17.282563;
            }
            else if (device == "1199411787624306486")
            {
                latitude  = 62.461594;
                longitude = 17.345016;
            }

            // TODO: We need to decide on the device names. Should we use the name from the LoRa app server?
            device = "snow_" + deviceInHex;

            IoTHubMessageOrigin origin = new IoTHubMessageOrigin(device, latitude, longitude);

            double volts = payload[0];

            volts = Math.Round(3 * ((volts * 0.005) + 1.1), 3);
            _messageQueue.PostMessage(new SensorStatusMessage(origin, timestamp, volts));

            const byte sensorStatusIsOK = 0;

            if (payload[11] == sensorStatusIsOK)
            {
                DateTime dt = DateTime.ParseExact(timestamp, "yyyy-MM-ddTHH:mm:ssZ", null);
                if (dt.Month < 5 || dt.Month > 10)
                {
                    double snowdepth = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(start: 7, length: 2));
                    snowdepth = Math.Round(snowdepth / 10.0, 1);
                    _messageQueue.PostMessage(new TelemetrySnowdepth(origin, timestamp, snowdepth));
                }
                else
                {
                    Console.WriteLine($"Snowdepth readings are disabled.");
                }
            }
            else
            {
                Console.WriteLine($"Ignoring snowdepth reading from {device}. Sensor is not OK.");
            }

            double temperature = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(start: 12, length: 2));

            temperature = Math.Round((temperature / 10.0) - 100.0, 2);
            _messageQueue.PostMessage(new TelemetryTemperature(origin, timestamp, temperature));

            int humidity = payload[14];

            _messageQueue.PostMessage(new TelemetryHumidity(origin, timestamp, humidity));

            double pressure = BinaryPrimitives.ReadUInt32BigEndian(span.Slice(start: 15, length: 4));

            _messageQueue.PostMessage(new TelemetryPressure(origin, timestamp, (int)pressure));
        }
Exemplo n.º 8
0
        public override void Decode(string timestamp, string device, string topic, byte[] payload)
        {
            string  json = Encoding.UTF8.GetString(payload);
            dynamic data = JsonConvert.DeserializeObject <dynamic>(json);

            payload = System.Convert.FromBase64String(Convert.ToString(data.data));

            string deviceInHex = device;

            device = Int64.Parse(device, System.Globalization.NumberStyles.HexNumber).ToString();

            ReadOnlySpan <byte> span = payload;

            /*
             *  uint8_t   Battery [%]
             *  uint16_t  raw Distance [mm]
             *  uint16_t  Angle [deg]
             *  unit16_t  Vertical distance [mm]
             *  unit16_t  Snow depth [mm]
             *  unit16_t  Laser signal strength [0-400] (lower is better)
             *  uint8_t   Laser sensor status
             *  int16_t   Temperature [°C]F
             *  unit8_t   Humidity [%]
             *  unit32_t  Pressure [Pa]
             *
             *  DEVEUI:s
             *  1199411787624306471 Stöde 62.4081681,16.5687632
             *  1199411787624306472 Matfors 62.348384, 17.016098
             *  1199411787624306473 Njurunda 62.310288, 17.369975
             *  1199411787624306480 Sundsvall 62.392013, 17.285092
             *  1199411787624306481 Alnö 62.424865, 17.434870
             *  1199411787624306482 Sidsjö 62.374817, 17.269407
             *  1199411787624306483 Granloholm 62.409886, 17.270434
             *  1199411787624306484 Kovland 62.466341, 17.147527
             *  1199411787624306485 Fagerdalsparken 62.381662, 17.282563
             *  1199411787624306486 Finsta 62.461594, 17.345016
             */
            double latitude  = 1.348364;
            double longitude = 1.016056;

            if (device == "1199411787624306471")
            {
                latitude  = 62.4081681;
                longitude = 16.5687632;
            }
            else if (device == "1199411787624306472")
            {
                latitude  = 62.348384;
                longitude = 17.016098;
            }
            else if (device == "1199411787624306473")
            {
                latitude  = 62.310288;
                longitude = 17.369975;
            }
            else if (device == "1199411787624306480")
            {
                latitude  = 62.392013;
                longitude = 17.285092;
            }
            else if (device == "1199411787624306481")
            {
                latitude  = 62.424865;
                longitude = 17.434870;
            }
            else if (device == "1199411787624306483")
            {
                latitude  = 62.409886;
                longitude = 17.270434;
            }
            else if (device == "1199411787624306482")
            {
                latitude  = 62.374817;
                longitude = 17.269407;
            }
            else if (device == "1199411787624306484")
            {
                latitude  = 62.466341;
                longitude = 17.147527;
            }
            else if (device == "1199411787624306485")
            {
                latitude  = 62.381662;
                longitude = 17.282563;
            }
            else if (device == "1199411787624306486")
            {
                latitude  = 62.461594;
                longitude = 17.345016;
            }

            // TODO: We need to decide on the device names. Should we use the name from the LoRa app server?
            string deviceName = "snow_" + deviceInHex;

            IoTHubMessageOrigin origin = new IoTHubMessageOrigin(deviceName, latitude, longitude);

            double volts = payload[0];

            volts = Math.Round(3 * ((volts * 0.005) + 1.1), 3);
            _messageQueue.PostMessage(new SensorStatusMessage(origin, timestamp, volts));

            const byte sensorStatusIsOK = 0;

            if (payload[11] == sensorStatusIsOK)
            {
                DateTime dt = DateTime.ParseExact(timestamp, "yyyy-MM-ddTHH:mm:ssZ", null);
                if (dt.Month < 5 || dt.Month > 10)
                {
                    double snowdepth = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(start: 7, length: 2));
                    snowdepth = Math.Round(snowdepth / 10.0, 1);
                    _messageQueue.PostMessage(new TelemetrySnowdepth(origin, timestamp, snowdepth));
                }
                else
                {
                    Console.WriteLine($"Snowdepth readings are disabled.");
                }
            }
            else
            {
                Console.WriteLine($"Ignoring snowdepth reading from {deviceName}. Sensor is not OK.");
            }

            double temperature = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(start: 12, length: 2));

            temperature = Math.Round((temperature / 10.0) - 100.0, 2);
            _messageQueue.PostMessage(new TelemetryTemperature(origin, timestamp, temperature));

            int humidity = payload[14];

            _messageQueue.PostMessage(new TelemetryHumidity(origin, timestamp, humidity));

            double pressure = BinaryPrimitives.ReadUInt32BigEndian(span.Slice(start: 15, length: 4));

            _messageQueue.PostMessage(new TelemetryPressure(origin, timestamp, (int)pressure));

            if (data.ContainsKey("rxInfo"))
            {
                dynamic rxInfo = data["rxInfo"];
                if (rxInfo.Count > 0)
                {
                    dynamic gateway = rxInfo[0];
                    int     maxRSSI = gateway.rssi;
                    int     snr     = gateway.loRaSNR;
                    string  name    = gateway.name;

                    for (int i = 1; i < rxInfo.Count; i++)
                    {
                        if (rxInfo[i].rssi > maxRSSI)
                        {
                            maxRSSI = rxInfo[i].rssi;
                            snr     = gateway.loRaSNR;
                            name    = rxInfo[i].name;
                        }
                    }

                    Console.WriteLine($"{deviceName} is connected to gateway {name} with rssi {maxRSSI} and snr {snr}");

                    double rssiLevel = Math.Round((125.0 - Math.Abs(maxRSSI)) / 100.0, 2);
                    rssiLevel = Math.Min(Math.Max(0, rssiLevel), 1.0); // RSSI level should be in range [0 1]

                    double snrLevel = Math.Round((snr + 20.0) / 32.0, 2);
                    snrLevel = Math.Min(Math.Max(0, snrLevel), 1.0);

                    deviceName = "se:servanet:lora:" + deviceName;

                    var msg = new Fiware.DeviceMessage(deviceName).WithRSSI(rssiLevel).WithSNR(snrLevel);
                    msg = msg.WithVoltage(Math.Min(Math.Max(0, volts / 4.925), 1));

                    try
                    {
                        _fiwareContextBroker.PostMessage(msg);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine($"Exception caught attempting to post Device update: {e.Message}");
                    };
                }
            }
        }
Exemplo n.º 9
0
        public override void Decode(string timestamp, string device, string topic, byte[] payload)
        {
            //8121069065192625893   Circle K            62.387146,17.2948968
            //8121069065166743827   Skolhusallen        62.389056,17.2993245
            //8121069065154928350   Storgatan           62.3919559,17.294769
            //8121069065048831975   Universitetsallen   62.394618,17.2894867
            //8121069065164496276   Parkgatan           62.385353,17.3108438
            //8121069065126998713   Köpmangatan         62.38861,17.3083424

            if (topic != AirQualityTopic)
            {
                return;
            }

            ReadOnlySpan <byte> span = payload;
            double latitude          = 0;
            double longitude         = 0;

            if (device == "8121069065192625893")
            {
                latitude  = 62.387146;
                longitude = 17.2948968;
            }
            else if (device == "8121069065166743827")
            {
                latitude  = 62.389056;
                longitude = 17.2993245;
            }
            else if (device == "8121069065154928350")
            {
                latitude  = 62.3919559;
                longitude = 17.294769;
            }
            else if (device == "8121069065048831975")
            {
                latitude  = 62.394618;
                longitude = 17.2894867;
            }
            else if (device == "8121069065164496276")
            {
                latitude  = 62.385353;
                longitude = 17.3108438;
            }
            else if (device == "8121069065126998713")
            {
                latitude  = 62.38861;
                longitude = 17.3083424;
            }
            else
            {
                Console.WriteLine("Unknown air quality sensor " + device + ". Position unknown!");
                return;
            }

            IoTHubMessageOrigin origin = new IoTHubMessageOrigin(device, latitude, longitude);
            //pack('HHhHHH', pm10, pm25, (DTH_temp + 2732), DTH_humi, sensor_error, NO2ppm)

            double pm10 = BinaryPrimitives.ReadUInt16LittleEndian(span.Slice(start: 0, length: 2));

            _messageQueue.PostMessage(new TelemetryPM10(origin, timestamp, pm10 / 10.0));

            double pm25 = BinaryPrimitives.ReadUInt16LittleEndian(span.Slice(start: 2, length: 2));

            _messageQueue.PostMessage(new TelemetryPM25(origin, timestamp, pm25 / 10.0));

            _messageQueue.PostMessage(new TelemetryTemperature(
                                          origin, timestamp,
                                          ConvertTemperature(
                                              BinaryPrimitives.ReadUInt16LittleEndian(span.Slice(start: 4, length: 2)),
                                              device
                                              )));

            int humidity = BinaryPrimitives.ReadUInt16LittleEndian(span.Slice(start: 6, length: 2));

            _messageQueue.PostMessage(new TelemetryHumidity(origin, timestamp, (int)(humidity / 10.0)));

            if (device != "8121069065126998713")
            {
                var    no2StartIndex = (device != "8121069065166743827") ? 10 : 8;
                double no2           = BinaryPrimitives.ReadUInt16LittleEndian(span.Slice(start: no2StartIndex, length: 2));
                _messageQueue.PostMessage(new TelemetryNO2(origin, timestamp, ConvertNO2(no2, device)));
            }
        }