public DeviceConnectionEventDTO(DeviceConnectionEvent connectionEvent)
 {
     RowKey           = DateTime.UtcNow.ToInverseTicksRowKey();
     PartitionKey     = connectionEvent.DeviceId;
     DeviceId         = connectionEvent.DeviceId;
     TimeStamp        = connectionEvent.TimeStamp;
     FirmwareSKU      = connectionEvent.FirmwareSKU;
     FirmwareRevision = connectionEvent.FirmwareRevision;
     RSSI             = connectionEvent.RSSI;
 }
Пример #2
0
        void IListener <DeviceConnectionEvent> .Notify(DeviceConnectionEvent value)
        {
            if (_device == null || !ReferenceEquals(_device, value.Device))
            {
                return;
            }

            foreach (var listener in _subscriber.Values)
            {
                listener.Notify(value.Event);
            }
        }
Пример #3
0
 /// <summary>
 /// IoTHubによるデバイス接続/切断EventDataをDeviceConnectionEventに変換する
 /// </summary>
 /// <param name="body">EventDataのBodyプロパティ</param>
 /// <returns>DeviceConnectionEvent配列</returns>
 private DeviceConnectionEvent[] GetDeviceConnectionEvents(string body)
 {
     return(DeviceConnectionEvent.DeserializeIfInvalidThrowEx(body));
 }
Пример #4
0
        private async Task <InvokeResult> HandleSystemMessageAsync(string path, string payload)
        {
            Metrics.MessagesProcessed++;

            PEMBus.InstanceLogger.AddCustomEvent(LagoVista.Core.PlatformSupport.LogLevel.Message, "ListenerMOdule_HandleSystemMessageAsync", "Received System Message", path.ToKVP("topic"), payload.ToKVP("body"));

            var parts = path.Split('/');

            if (parts.Length < 5)
            {
                var errMsg = $"NuvIoT service messages must be at least 5 segments {path} is {parts.Length} segments";
                PEMBus.InstanceLogger.AddError("ListenerModule__HandleSystemMessage", errMsg);
                return(InvokeResult.FromError(errMsg));
            }

            var deviceId = parts[3];

            var device = await PEMBus.DeviceStorage.GetDeviceByDeviceIdAsync(deviceId);

            if (device == null)
            {
                var errMsg = $"Could not find device with device id {deviceId}.";
                PEMBus.InstanceLogger.AddError("ListenerModule__HandleSystemMessage", errMsg);
                return(InvokeResult.FromError(errMsg));
            }

            device.LastContact = DateTime.UtcNow.ToJSONString();

            if (parts[4] == "state")
            {
                device.DeviceTwinDetails.Insert(0, new DeviceManagement.Models.DeviceTwinDetails()
                {
                    Timestamp = DateTime.UtcNow.ToJSONString(),
                    Details   = payload
                });

                var payloadSegements = payload.Split(',');
                foreach (var segement in payloadSegements)
                {
                    var fieldParts = segement.Split('=');
                    if (fieldParts.Length == 2)
                    {
                        var nameParts = fieldParts[0].Split('-');
                        if (nameParts.Length == 2)
                        {
                            var typeName = nameParts[0];
                            var key      = nameParts[1];
                            var value    = fieldParts[1];
                            if (typeName != "readonly")
                            {
                                var prop = device.Properties.FirstOrDefault(prp => prp.Key == key);
                                if (prop != null)
                                {
                                    if (prop.Value != value)
                                    {
                                        prop.Value         = value;
                                        prop.LastUpdated   = DateTime.UtcNow.ToJSONString();
                                        prop.LastUpdatedBy = "Device Twin";
                                    }
                                }
                            }
                            else
                            {
                                if (key == "firmwareSku")
                                {
                                    device.ActualFirmware     = value;
                                    device.ActualFirmwareDate = DateTime.Now.ToJSONString();
                                }
                                if (key == "firmwareVersion")
                                {
                                    device.ActualFirmwareRevision = value;
                                    device.ActualFirmwareDate     = DateTime.Now.ToJSONString();
                                }
                            }
                        }
                    }
                }
            }
            else if (parts[4] == "err")
            {
                var err       = parts[5];
                var action    = parts[6];
                var exception = new DeviceException()
                {
                    ErrorCode          = err,
                    DeviceId           = device.DeviceId,
                    DeviceUniqueId     = device.Id,
                    DeviceRepositoryId = device.DeviceRepository.Id,
                    Timestamp          = DateTime.UtcNow.ToString(),
                };

                exception.AdditionalDetails.Add(payload);

                if (action == "raise")
                {
                    await PEMBus.InstanceConnector.HandleDeviceExceptionAsync(exception);
                }
                else if (action == "clear")
                {
                    await PEMBus.InstanceConnector.ClearDeviceExceptionAsync(exception);
                }
            }
            else if (parts[4] == "iovalues")
            {
                var values = payload.Split(',');
                if (values.Length != 16)
                {
                    throw new InvalidDataException($"IO Configuration from device should consist of 16 comma delimited values, message consists of ${values.Length} items.");
                }

                for (int idx = 0; idx < 8; ++idx)
                {
                    if (!String.IsNullOrEmpty(values[idx + 8]))
                    {
                        var sensor = device.SensorCollection.Where(sns => sns.Technology != null && sns.Technology.Value == DeviceManagement.Models.SensorTechnology.ADC && sns.PortIndex == idx).FirstOrDefault();
                        if (sensor != null)
                        {
                            sensor.Value       = values[idx + 8];
                            sensor.LastUpdated = DateTime.UtcNow.ToJSONString();
                        }
                    }
                }

                for (int idx = 0; idx < 8; ++idx)
                {
                    if (!String.IsNullOrEmpty(values[idx]))
                    {
                        var sensor = device.SensorCollection.Where(sns => sns.Technology != null && sns.Technology.Value == DeviceManagement.Models.SensorTechnology.IO && sns.PortIndex == idx).FirstOrDefault();
                        if (sensor != null)
                        {
                            sensor.Value       = values[idx];
                            sensor.LastUpdated = DateTime.UtcNow.ToJSONString();
                        }
                    }
                }

                await PEMBus.SensorEvaluator.EvaluateAsync(device);
            }
            else if (parts[4] == "geo")
            {
                var values = payload.Split(',');
                if (values.Length < 2)
                {
                    throw new InvalidDataException($"Geo Location Data type must contain a minimum of 2 fields for latitude and longitude, message consists of ${values.Length} items.");
                }

                if (!double.TryParse(values[0], out double lat))
                {
                    throw new InvalidDataException($"Invalid Latitude value [{values[0]}].");
                }

                if (lat > 90 || lat < -90)
                {
                    throw new InvalidDataException($"Invalid Latitude value [{values[0]}], must be between -90 and 90.");
                }

                if (!double.TryParse(values[1], out double lon))
                {
                    throw new InvalidDataException($"Invalid Longitude value [{values[1]}].");
                }

                if (lon > 180 || lon < -180)
                {
                    throw new InvalidDataException($"Invalid Latitude value [{values[1]}], must be between -180 and 180.");
                }

                device.GeoLocation = new LagoVista.Core.Models.Geo.GeoLocation()
                {
                    LastUpdated = DateTime.UtcNow.ToJSONString(),
                    Latitude    = lat,
                    Longitude   = lon,
                };
            }
            else if (parts[4] == "online")
            {
                device.ConnectionTimeStamp = DateTime.UtcNow.ToJSONString();
                var rssi      = -1.0;
                var reconnect = false;

                var payloadSegements = payload.Split(',');
                foreach (var segement in payloadSegements)
                {
                    var fieldParts = segement.Split('=');
                    if (fieldParts.Length == 2)
                    {
                        var nameParts = fieldParts[0].Split('-');
                        if (nameParts.Length == 2)
                        {
                            var typeName = nameParts[0];
                            var key      = nameParts[1];
                            var value    = fieldParts[1];
                            if (typeName != "readonly")
                            {
                                var prop = device.Properties.FirstOrDefault(prp => prp.Key == key);
                                if (prop != null)
                                {
                                    if (prop.Value != value)
                                    {
                                        if (prop.AttributeType.Value == DeviceAdmin.Models.ParameterTypes.TrueFalse)
                                        {
                                            if (value == "1")
                                            {
                                                value = "true";
                                            }
                                            else if (value == "0")
                                            {
                                                value = "false";
                                            }
                                            else
                                            {
                                                value = value.ToLower();
                                            }
                                        }
                                        prop.Value         = value;
                                        prop.LastUpdated   = DateTime.UtcNow.ToJSONString();
                                        prop.LastUpdatedBy = "Device Twin";
                                    }
                                }
                            }
                            else
                            {
                                if (key == "firmwareSku")
                                {
                                    device.ActualFirmware     = value;
                                    device.ActualFirmwareDate = DateTime.Now.ToJSONString();
                                }
                                if (key == "firmwareVersion")
                                {
                                    device.ActualFirmwareRevision = value;
                                    device.ActualFirmwareDate     = DateTime.Now.ToJSONString();
                                }
                                if (key == "rssi")
                                {
                                    double.TryParse(value, out rssi);
                                }
                                if (key == "reconnect")
                                {
                                    reconnect = value != "0";
                                }
                            }
                        }
                    }
                }

                var connectionEvent = new DeviceConnectionEvent()
                {
                    DeviceId         = device.Id,
                    FirmwareRevision = device.ActualFirmwareRevision,
                    FirmwareSKU      = device.ActualFirmware,
                    TimeStamp        = DateTime.UtcNow.ToJSONString(),
                    RSSI             = rssi,
                    Reconnect        = reconnect
                };

                await PEMBus.DeviceConnectionEvent.AddDeviceEventConnectionEvent(connectionEvent);
            }

            await PEMBus.DeviceStorage.UpdateDeviceAsync(device);

            var json         = JsonConvert.SerializeObject(Models.DeviceForNotification.FromDevice(device), _camelCaseSettings);
            var notification = new Notification()
            {
                Payload     = json,
                Channel     = EntityHeader <Channels> .Create(Channels.Device),
                ChannelId   = device.Id,
                PayloadType = "Device",
                DateStamp   = DateTime.UtcNow.ToJSONString(),
                MessageId   = Guid.NewGuid().ToId(),
                Text        = "Device Updated",
                Title       = "Device Updated"
            };

            await PEMBus.NotificationPublisher.PublishAsync(Targets.WebSocket, notification);

            notification = new Notification()
            {
                Payload     = json,
                Channel     = EntityHeader <Channels> .Create(Channels.DeviceRepository),
                ChannelId   = device.DeviceRepository.Id,
                PayloadType = "Device",
                DateStamp   = DateTime.UtcNow.ToJSONString(),
                MessageId   = Guid.NewGuid().ToId(),
                Text        = "Device Updated",
                Title       = "Device Updated"
            };

            await PEMBus.NotificationPublisher.PublishAsync(Targets.WebSocket, notification);

            foreach (var group in device.DeviceGroups)
            {
                notification = new Notification()
                {
                    Payload     = json,
                    Channel     = EntityHeader <Channels> .Create(Channels.DeviceGroup),
                    ChannelId   = group.Id,
                    PayloadType = "Device",
                    DateStamp   = DateTime.UtcNow.ToJSONString(),
                    MessageId   = Guid.NewGuid().ToId(),
                    Text        = "Device Updated",
                    Title       = "Device Updated"
                };

                await PEMBus.NotificationPublisher.PublishAsync(Targets.WebSocket, notification);
            }

            return(InvokeResult.Success);
        }