using Microsoft.AspNetCore.Mvc; using Mqtt.Client.AspNetCore.Services; using MyCore.Interfaces.DTO; using MyCore.Interfaces.Models; using MyCore.Interfaces.Models.MyControlPanel; using MyCore.Services.MyControlPanel; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Security.Authentication; using System.Threading.Tasks; namespace MyCore.Services.Devices { public class DeviceService { static List supportedDevices = new List() { new SupportedDevice { Manufacturer = "Aqara", Model = "RTCGQ11LM", Description = "Aqara human body movement and illuminance sensor", DeviceType = DeviceType.Motion }, new SupportedDevice { Manufacturer = "Aqara", Model = "DJT11LM", Description = "Aqara vibration sensor", DeviceType = DeviceType.Environment }, new SupportedDevice { Manufacturer = "Aqara", Model = "SJCGQ11LM", Description = "Aqara water leak sensor", DeviceType = DeviceType.Environment }, new SupportedDevice { Manufacturer = "Aqara", Model = "WSDCGQ11LM", Description = "Aqara temperature, humidity and pressure sensor", DeviceType = DeviceType.Environment }, new SupportedDevice { Manufacturer = "Xiaomi", Model = "WXKG01LM", Description = "MiJia wireless switch", DeviceType = DeviceType.Switch }, new SupportedDevice { Manufacturer = "Xiaomi", Model = "MFKZQ01LM", Description = "Mi/Aqara smart home cube", DeviceType = DeviceType.Switch }, new SupportedDevice { Manufacturer = "Xiaomi", Model = "MCCGQ01LM", Description = "MiJia door & window contact sensor", DeviceType = DeviceType.Door }, new SupportedDevice { Manufacturer = "Xiaomi", Model = "JTYJ-GD-01LM/BW", Description = "MiJia Honeywell smoke detector", DeviceType = DeviceType.Environment }, new SupportedDevice { Manufacturer = "Xiaomi", Model = "ZNCZ04LM", Description = "Mi power plug ZigBee EU", DeviceType = DeviceType.Plug }, new SupportedDevice { Manufacturer = "Ikea", Model = "E1744", Description = "SYMFONISK Sound Controller", DeviceType = DeviceType.Switch }, new SupportedDevice { Manufacturer = "Ikea", Model = "LED1836G9", Description = "TRADFRI LED bulb E26/E27 806 lumen, dimmable, warm white", DeviceType = DeviceType.Light }, new SupportedDevice { Manufacturer = "Ikea", Model = "LED1842G3", Description = "TRADFRI LED bulb E27 WW clear 250 lumen, dimmable", DeviceType = DeviceType.Light }, new SupportedDevice { Manufacturer = "Ikea", Model = "LED1837R5", Description = "TRADFRI LED bulb GU10 400 lumen, dimmable", DeviceType = DeviceType.Light }, new SupportedDevice { Manufacturer = "Ikea", Model = "E1743", Description = "TRADFRI ON/OFF switch", DeviceType = DeviceType.Switch }, new SupportedDevice { Manufacturer = "Ikea", Model = "E1524/E1810", Description = "TRADFRI remote control", DeviceType = DeviceType.Switch }, new SupportedDevice { Manufacturer = "SONOFF", Model = "BASICZBR3", Description = "Zigbee smart switch", DeviceType = DeviceType.Switch }, new SupportedDevice { Manufacturer = "Philips", Model = "8718696743133", Description = "Hue tap", DeviceType = DeviceType.Switch }, new SupportedDevice { Manufacturer = "Neo", Model = "NAS-AB02B0", Description = "Temperature & humidity sensor and alarm", DeviceType = DeviceType.Sound }, new SupportedDevice { Manufacturer = "TuYa", Model = "TS0201", Description = "Temperature & humidity sensor with display", DeviceType = DeviceType.Environment }, }; public static DeviceDetailDTO CreateOrUpdate(DeviceDatabaseService _DeviceDatabaseService, ProviderDatabaseService _ProviderDatabaseService, RoomDatabaseService _RoomDatabaseService, string homeId, DeviceDetailDTO deviceDetailDTO, bool create, bool isZigbee = false) { Device device; if (isZigbee) { device = _DeviceDatabaseService.GetByServiceIdentification(deviceDetailDTO.ServiceIdentification); if (device == null) device = new Device(); } else { if (create) device = new Device(); else { device = _DeviceDatabaseService.GetById(deviceDetailDTO.Id); } } /*// What's the purpose here ? if (_DeviceDatabaseService.IsAlreadyHere(homeId, deviceDetailDTO.ServiceIdentification, deviceDetailDTO.Model) && create) { return null; }*/ device.HomeId = homeId; device.Name = deviceDetailDTO.Name; device.Description = deviceDetailDTO.Description; device.ManufacturerName = deviceDetailDTO.ManufacturerName; if (_ProviderDatabaseService.IsExist(deviceDetailDTO.ProviderId)) device.ProviderId = deviceDetailDTO.ProviderId; else throw new KeyNotFoundException("Provider does not exist"); if (device.RoomId == null || _RoomDatabaseService.IsExist(deviceDetailDTO.RoomId)) device.RoomId = deviceDetailDTO.RoomId; else throw new KeyNotFoundException("Location does not exist"); device.Port = deviceDetailDTO.Port; device.Model = deviceDetailDTO.Model; device.Type = deviceDetailDTO.Type; device.FirmwareVersion = deviceDetailDTO.FirmwareVersion; device.HardwareVersion = deviceDetailDTO.HardwareVersion; device.Status = deviceDetailDTO.Status; if (create) device.ConnectionStatus = ConnectionStatus.Unknown; else device.ConnectionStatus = deviceDetailDTO.ConnectionStatus; device.RoomId = deviceDetailDTO.RoomId; if (create) { device.CreatedDate = DateTime.Now; } else { device.UpdatedDate = DateTime.Now; device.LastState = deviceDetailDTO.LastState; device.LastStateDate = deviceDetailDTO.LastStateDate; device.Status = deviceDetailDTO.Status; } device.MeansOfCommunications = deviceDetailDTO.MeansOfCommunications; device.IpAddress = deviceDetailDTO.IpAddress; device.ServiceIdentification = deviceDetailDTO.ServiceIdentification; device.Battery = deviceDetailDTO.Battery; device.BatteryStatus = deviceDetailDTO.BatteryStatus; device.GroupIds = deviceDetailDTO.GroupIds; // Todo structure Properties device.Properties = deviceDetailDTO.Properties; // Todo structure SupportedOperations device.SupportedOperations = deviceDetailDTO.SupportedOperations; if (create) return _DeviceDatabaseService.Create(device).ToDTO(); else return _DeviceDatabaseService.Update(device).ToDTO(); } public async static Task>> CreateFromProvider(DeviceDatabaseService _DeviceDatabaseService, ProviderDatabaseService _ProviderDatabaseService, RoomDatabaseService _RoomDatabaseService, string homeId, Provider provider) { Dictionary> devices = new Dictionary>(); try { switch (provider.Type) { case ProviderType.arlo: List arloDevices = new ArloService(provider.Username, provider.Password).GetAllDevices(); devices = CreateArloDevices(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, arloDevices, provider); break; case ProviderType.meross: List merossDevices = MqttClientMerossService.GetMerossDevices(); // TO TEST IF IT WORKS devices = CreateMerossDevices(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, merossDevices, provider); break; case ProviderType.yeelight: List yeelightDevices = await YeelightService.GetDevices(); devices = CreateYeelightDevices(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, yeelightDevices, provider); break; case ProviderType.zigbee2mqtt: if (MqttClientService.devices.Count > 0) { // Simple list mode List zigbee2MqttDevices = MqttClientService.devices; devices = await CreateFromZigbeeAsync(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, zigbee2MqttDevices, provider); } if (MqttClientService.devicesNew.Count > 0) { // Complex list mode List zigbee2MqttDevices = MqttClientService.devicesNew; devices = await UpdateFromZigbeeAsync(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, zigbee2MqttDevices, provider); } break; } } catch (AuthenticationException ex) { throw new AuthenticationException("Bad username or password for service " + provider.Name + " ex: " + ex.Message); } catch (HttpRequestException ex) { throw new HttpRequestException("Error retrieving devices for " + provider.Name + " ex: " + ex.Message); } catch (Exception ex) { } return devices; } // Old way /*public static async Task>> CreateFromZigbeeAsync(DeviceDatabaseService _DeviceDatabaseService, ProviderDatabaseService _ProviderDatabaseService, LocationDatabaseService _LocationDatabaseService, string homeId, List zigbee2MqttDevices, Provider provider) { List createdZigbeeDevices = new List(); List notSupportedZigbeeDevices = new List(); List existingDevices = _DeviceDatabaseService.GetByProviderId(provider.Id); if (zigbee2MqttDevices.Count <= 0) { zigbee2MqttDevices = await MqttClientService.AskDevicesAsync(); } zigbee2MqttDevices = zigbee2MqttDevices.Where(yd => !existingDevices.Select(ed => ed.ServiceIdentification).ToList().Contains(yd.ieeeAddr)).ToList(); foreach (var zigbee2MqttDevice in zigbee2MqttDevices) { DeviceDetailDTO deviceDetailDTO = new DeviceDetailDTO(); deviceDetailDTO.Name = zigbee2MqttDevice.friendly_name; deviceDetailDTO.Description = zigbee2MqttDevice.description; deviceDetailDTO.ServiceIdentification = zigbee2MqttDevice.ieeeAddr; deviceDetailDTO.ProviderId = provider.Id; deviceDetailDTO.ProviderName = provider.Name; deviceDetailDTO.Model = zigbee2MqttDevice.type == "Coordinator" ? "Coordinator" : zigbee2MqttDevice.model; // Is the base to understand incoming messages ! deviceDetailDTO.FirmwareVersion = zigbee2MqttDevice.softwareBuildID; deviceDetailDTO.HardwareVersion = zigbee2MqttDevice.hardwareVersion.ToString(); deviceDetailDTO.Battery = zigbee2MqttDevice.powerSource == null ? false : zigbee2MqttDevice.powerSource.Contains("Battery"); deviceDetailDTO.ManufacturerName = zigbee2MqttDevice.vendor == null ? provider.Type : zigbee2MqttDevice.vendor.ToLower(); deviceDetailDTO.MeansOfCommunications = new List(); deviceDetailDTO.MeansOfCommunications.Add(MeansOfCommunication.Zigbee); deviceDetailDTO.CreatedDate = DateTime.Now; deviceDetailDTO.UpdatedDate = DateTime.Now; deviceDetailDTO.LastStateDate = new DateTime(zigbee2MqttDevice.lastSeen); deviceDetailDTO.Type = zigbee2MqttDevice.type == "Coordinator" ? DeviceType.Gateway : GetDeviceTypeFromZigbeeModel(zigbee2MqttDevice.model); if (deviceDetailDTO.Type != DeviceType.Unknown) { // Supoorted device ! createdZigbeeDevices.Add(CreateOrUpdate(_DeviceDatabaseService, _ProviderDatabaseService, _LocationDatabaseService, homeId, deviceDetailDTO, true)); } else { // Not yet supported ! notSupportedZigbeeDevices.Add(deviceDetailDTO); } } return new Dictionary>() { { "createdDevices", createdZigbeeDevices }, { "notSupportedDevices", notSupportedZigbeeDevices } }; }*/ public static async Task>> CreateFromZigbeeAsync(DeviceDatabaseService _DeviceDatabaseService, ProviderDatabaseService _ProviderDatabaseService, RoomDatabaseService _RoomDatabaseService, string homeId, List zigbee2MqttDevices, Provider provider) { List createdZigbeeDevices = new List(); List notSupportedZigbeeDevices = new List(); List existingDevices = _DeviceDatabaseService.GetByProviderId(provider.Id); // Not necessarry if (zigbee2MqttDevices.Count <= 0) { //zigbee2MqttDevices = await MqttClientService.AskDevicesAsync(); } zigbee2MqttDevices = zigbee2MqttDevices.Where(yd => !existingDevices.Select(ed => ed.ServiceIdentification).ToList().Contains(yd.ieeeAddr)).ToList(); foreach (var zigbee2MqttDevice in zigbee2MqttDevices) { DeviceDetailDTO deviceDetailDTO = new DeviceDetailDTO(); deviceDetailDTO.Name = zigbee2MqttDevice.friendly_name; deviceDetailDTO.ServiceIdentification = zigbee2MqttDevice.ieeeAddr; deviceDetailDTO.ProviderId = provider.Id; deviceDetailDTO.ProviderName = provider.Name; deviceDetailDTO.Description = zigbee2MqttDevice.type == "Coordinator" ? "Coordinator" : zigbee2MqttDevice.description; deviceDetailDTO.Model = zigbee2MqttDevice.type == "Coordinator" ? "Coordinator" : zigbee2MqttDevice.model; // Is the base to understand incoming messages ! //deviceDetailDTO.FirmwareVersion = zigbee2MqttDevice.software_build_id; deviceDetailDTO.Battery = zigbee2MqttDevice.powerSource == null ? false : zigbee2MqttDevice.powerSource.Contains("Battery"); deviceDetailDTO.ManufacturerName = zigbee2MqttDevice.vendor == null ? provider.Type.ToString() : zigbee2MqttDevice.vendor.ToLower(); deviceDetailDTO.MeansOfCommunications = new List(); deviceDetailDTO.MeansOfCommunications.Add(MeansOfCommunication.Zigbee); deviceDetailDTO.CreatedDate = DateTime.Now; deviceDetailDTO.UpdatedDate = DateTime.Now; if (zigbee2MqttDevice.type != "Coordinator") { // EXPOSES ! List supportedOperationsDTO = new List(); /*foreach (var supportedOperation in zigbee2MqttDevice.definition?.exposes) { supportedOperationsDTO.Add(JsonConvert.SerializeObject(supportedOperation)); } deviceDetailDTO.SupportedOperations = supportedOperationsDTO; deviceDetailDTO.Type = GetDeviceTypeFromZigbeeModel(zigbee2MqttDevice.definition.model);*/ } else { deviceDetailDTO.Type = DeviceType.Gateway; } if (true) //zigbee2MqttDevice.supported // TODO QUID { // Supported device ! createdZigbeeDevices.Add(CreateOrUpdate(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, deviceDetailDTO, true)); } else { // Not yet supported ! notSupportedZigbeeDevices.Add(deviceDetailDTO); } } return new Dictionary>() { { "createdDevices", createdZigbeeDevices }, { "notSupportedDevices", notSupportedZigbeeDevices } }; } public static async Task>> UpdateFromZigbeeAsync(DeviceDatabaseService _DeviceDatabaseService, ProviderDatabaseService _ProviderDatabaseService, RoomDatabaseService _RoomDatabaseService, string homeId, List zigbee2MqttDevices, Provider provider) { List updatedZigbeeDevices = new List(); List notSupportedZigbeeDevices = new List(); List existingDevices = _DeviceDatabaseService.GetByProviderId(provider.Id); // Not necessarry if (zigbee2MqttDevices.Count <= 0) { //zigbee2MqttDevices = await MqttClientService.AskDevicesAsync(); } //zigbee2MqttDevices = zigbee2MqttDevices.Where(yd => !existingDevices.Select(ed => ed.ServiceIdentification).ToList().Contains(yd.ieee_address)).ToList(); foreach (var zigbee2MqttDevice in zigbee2MqttDevices) { var existingDevice = _DeviceDatabaseService.GetByServiceIdentification(zigbee2MqttDevice.ieee_address); DeviceDetailDTO deviceDetailDTO = new DeviceDetailDTO(); deviceDetailDTO.Name = zigbee2MqttDevice.friendly_name; deviceDetailDTO.ServiceIdentification = zigbee2MqttDevice.ieee_address; deviceDetailDTO.ProviderId = provider.Id; deviceDetailDTO.ProviderName = provider.Name; deviceDetailDTO.Description = zigbee2MqttDevice.type == "Coordinator" ? "Coordinator" : zigbee2MqttDevice.definition.description; deviceDetailDTO.Model = zigbee2MqttDevice.type == "Coordinator" ? "Coordinator" : zigbee2MqttDevice.definition.model; // Is the base to understand incoming messages ! deviceDetailDTO.FirmwareVersion = zigbee2MqttDevice.software_build_id; deviceDetailDTO.Battery = zigbee2MqttDevice.power_source == null ? false : zigbee2MqttDevice.power_source.Contains("Battery"); deviceDetailDTO.ManufacturerName = zigbee2MqttDevice.definition?.vendor == null ? provider.Type.ToString() : zigbee2MqttDevice.definition?.vendor.ToLower(); deviceDetailDTO.MeansOfCommunications = new List(); deviceDetailDTO.MeansOfCommunications.Add(MeansOfCommunication.Zigbee); deviceDetailDTO.GroupIds = existingDevice != null ? existingDevice.GroupIds : null; deviceDetailDTO.Properties = existingDevice != null ? existingDevice.Properties : null; deviceDetailDTO.RoomId = existingDevice != null ? existingDevice.RoomId : null; deviceDetailDTO.CreatedDate = existingDevice != null ? existingDevice.CreatedDate : DateTime.Now; deviceDetailDTO.UpdatedDate = DateTime.Now; if (zigbee2MqttDevice.type != "Coordinator") { // EXPOSES ! List supportedOperationsDTO = new List(); foreach (var supportedOperation in zigbee2MqttDevice.definition?.exposes) { supportedOperationsDTO.Add(JsonConvert.SerializeObject(supportedOperation)); } deviceDetailDTO.SupportedOperations = supportedOperationsDTO; deviceDetailDTO.Type = GetDeviceTypeFromZigbeeModel(zigbee2MqttDevice.definition.model); } else { deviceDetailDTO.Type = DeviceType.Gateway; } if (zigbee2MqttDevice.supported || deviceDetailDTO.Type == DeviceType.Gateway) { // Supported device ! updatedZigbeeDevices.Add(CreateOrUpdate(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, deviceDetailDTO, false, true)); } else { // Not yet supported ! notSupportedZigbeeDevices.Add(deviceDetailDTO); } } return new Dictionary>() { { "updatedZigbeeDevices", updatedZigbeeDevices }, { "notSupportedDevices", notSupportedZigbeeDevices } }; } private static DeviceType GetDeviceTypeFromZigbeeModel(string zigbeeModel) { return supportedDevices.Any(sd => sd.Model == zigbeeModel) ? // It's supported ! supportedDevices.Where(sd => sd.Model == zigbeeModel).FirstOrDefault().DeviceType : // Not yet supported DeviceType.Unknown; } public static Dictionary> CreateArloDevices(DeviceDatabaseService _DeviceDatabaseService, ProviderDatabaseService _ProviderDatabaseService, RoomDatabaseService _RoomDatabaseService, string homeId, List arloDevices, Provider provider) { List createdArloDevices = new List(); List existingDevices = _DeviceDatabaseService.GetByProviderId(provider.Id); arloDevices = arloDevices.Where(yd => !existingDevices.Select(ed => ed.ServiceIdentification).ToList().Contains(yd.deviceId)).ToList(); foreach (var arlo in arloDevices) { DeviceDetailDTO deviceDetailDTO = new DeviceDetailDTO(); deviceDetailDTO.ManufacturerName = provider.Type.ToString(); deviceDetailDTO.Name = arlo.deviceName; deviceDetailDTO.Description = arlo.deviceName; // As description not exist, put name in description deviceDetailDTO.ServiceIdentification = arlo.deviceId; deviceDetailDTO.ProviderId = provider.Id; deviceDetailDTO.ProviderName = provider.Name; if (arlo.connectivity != null) { deviceDetailDTO.ConnectionStatus = arlo.connectivity.connected ? ConnectionStatus.Connected : ConnectionStatus.Unknown; deviceDetailDTO.Status = arlo.connectivity.connected ? true : false; // TODO STATE } else deviceDetailDTO.ConnectionStatus = ConnectionStatus.Unknown; deviceDetailDTO.Model = arlo.modelId; deviceDetailDTO.FirmwareVersion = arlo.interfaceVersion; // TODO switch (arlo.deviceType) { case "camera": deviceDetailDTO.Type = DeviceType.Camera; Dictionary properties = new Dictionary(); properties.Add("lastImageUploaded", arlo.lastImageUploaded); properties.Add("presignedLastImageUrl", arlo.presignedLastImageUrl); properties.Add("presignedFullFrameSnapshotUrl", arlo.presignedFullFrameSnapshotUrl); properties.Add("presignedSnapshotUrl", arlo.presignedSnapshotUrl); deviceDetailDTO.Properties = JsonConvert.SerializeObject(properties); break; case "siren": deviceDetailDTO.Type = DeviceType.Sound; break; case "basestation": deviceDetailDTO.Type = DeviceType.Gateway; break; } deviceDetailDTO.MeansOfCommunications = new List(); deviceDetailDTO.MeansOfCommunications.Add(MeansOfCommunication.Wifi); // To check deviceDetailDTO.CreatedDate = DateTime.Now; deviceDetailDTO.UpdatedDate = DateTime.Now; createdArloDevices.Add(CreateOrUpdate(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, deviceDetailDTO, true)); } return new Dictionary>() { { "createdDevices", createdArloDevices } }; // TODO Check if exist not supported devices } public static Dictionary> CreateMerossDevices(DeviceDatabaseService _DeviceDatabaseService, ProviderDatabaseService _ProviderDatabaseService, RoomDatabaseService _RoomDatabaseService, string homeId, List merossDevices, Provider provider) { List createdMerossDevices = new List(); List existingDevices = _DeviceDatabaseService.GetByProviderId(provider.Id); merossDevices = merossDevices.Where(yd => !existingDevices.Select(ed => ed.ServiceIdentification).ToList().Contains(yd.uuid)).ToList(); foreach (var meross in merossDevices) { DeviceDetailDTO deviceDetailDTO = new DeviceDetailDTO(); deviceDetailDTO.ManufacturerName = provider.Type.ToString(); deviceDetailDTO.HardwareVersion = meross.hdwareVersion; deviceDetailDTO.Name = meross.devName; deviceDetailDTO.Description = meross.devName; // As description not exist, put name in description deviceDetailDTO.ServiceIdentification = meross.uuid; deviceDetailDTO.ProviderId = provider.Id; deviceDetailDTO.ProviderName = provider.Name; deviceDetailDTO.ConnectionStatus = meross.onlineStatus == 1 ? ConnectionStatus.Connected : ConnectionStatus.Disconnected; // deviceDetailDTO.Status = meross. ? true : false; // TODO STATE deviceDetailDTO.Model = meross.deviceType; switch (deviceDetailDTO.Model) // TODO { case "mss425f": deviceDetailDTO.Type = DeviceType.Multiplug; break; case "mss310": deviceDetailDTO.Type = DeviceType.Plug; break; case "msh300": deviceDetailDTO.Type = DeviceType.Gateway; break; default: deviceDetailDTO.Type = DeviceType.Actuator; break; } deviceDetailDTO.FirmwareVersion = meross.firmwareVersion; // TODO Dictionary properties = new Dictionary(); foreach (var property in meross.channels) { if (property.type != null) properties.Add(property.devName, property.type); } // deviceDetailDTO.SupportedOperations = supportedOperationsDTO; TODO deviceDetailDTO.MeansOfCommunications = new List(); deviceDetailDTO.MeansOfCommunications.Add(MeansOfCommunication.Wifi); // TO CHECK deviceDetailDTO.CreatedDate = DateTime.Now; deviceDetailDTO.UpdatedDate = DateTime.Now; createdMerossDevices.Add(CreateOrUpdate(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, deviceDetailDTO, true)); } return new Dictionary>() { { "createdDevices", createdMerossDevices } }; // TODO Check if exist not supported devices } public static Dictionary> CreateYeelightDevices(DeviceDatabaseService _DeviceDatabaseService, ProviderDatabaseService _ProviderDatabaseService, RoomDatabaseService _RoomDatabaseService, string homeId, List yeelightDevices, Provider provider) { List createdYeelightDevices = new List(); List existingDevices = _DeviceDatabaseService.GetByProviderId(provider.Id); yeelightDevices = yeelightDevices.Where(yd => !existingDevices.Select(ed => ed.ServiceIdentification).ToList().Contains(yd.Id)).ToList(); foreach (var light in yeelightDevices) { DeviceDetailDTO deviceDetailDTO = new DeviceDetailDTO(); deviceDetailDTO.ManufacturerName = provider.Type.ToString(); deviceDetailDTO.Name = light.Name; deviceDetailDTO.Description = light.Name; // As description not exist, put name in description deviceDetailDTO.IpAddress = light.Hostname; deviceDetailDTO.ServiceIdentification = light.Id; deviceDetailDTO.ProviderId = provider.Id; deviceDetailDTO.ProviderName = provider.Name; deviceDetailDTO.ConnectionStatus = ConnectionStatus.Connected; deviceDetailDTO.Status = false; deviceDetailDTO.Model = light.Model.ToString(); deviceDetailDTO.Type = DeviceType.Light; // TO CHECK deviceDetailDTO.Port = light.Port; deviceDetailDTO.FirmwareVersion = light.FirmwareVersion; Dictionary properties = new Dictionary(); foreach (var property in light.Properties) { properties.Add(property.Key, property.Value); } deviceDetailDTO.Properties = JsonConvert.SerializeObject(properties); List supportedOperationsDTO = new List(); foreach (var supportedOperation in light.SupportedOperations) { supportedOperationsDTO.Add(supportedOperation.ToString()); } deviceDetailDTO.SupportedOperations = supportedOperationsDTO; deviceDetailDTO.MeansOfCommunications = new List(); deviceDetailDTO.MeansOfCommunications.Add(MeansOfCommunication.Wifi); deviceDetailDTO.CreatedDate = DateTime.Now; deviceDetailDTO.UpdatedDate = DateTime.Now; createdYeelightDevices.Add(CreateOrUpdate(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, deviceDetailDTO, true)); } return new Dictionary>() { { "createdDevices", createdYeelightDevices } }; // TODO Check if exist not supported devices } } }