Add netatmo provider ! + clean code

This commit is contained in:
Thomas Fransolet 2023-08-11 16:50:41 +02:00
parent 97fc143865
commit 2ebb1dfd60
16 changed files with 623 additions and 21 deletions

View File

@ -157,5 +157,13 @@ namespace MyCore.Interfaces.DTO
public bool IsLinkQuality { get; set; } // Example: 84 LQI public bool IsLinkQuality { get; set; } // Example: 84 LQI
public int LinkQuality { get; set; } // Example: 84 LQI public int LinkQuality { get; set; } // Example: 84 LQI
public bool IsCO2 { get; set; }
public int CO2 { get; set; }
public bool IsNoise { get; set; }
public int Noise { get; set; } // decibel
} }
} }

View File

@ -12,10 +12,13 @@ namespace MyCore.Interfaces.DTO
public string Name { get; set; } public string Name { get; set; }
public ProviderType Type { get; set; } public ProviderType Type { get; set; }
public string HomeId { get; set; } public string HomeId { get; set; }
public string ServiceHomeId { get; set; }
public string Endpoint { get; set; } public string Endpoint { get; set; }
public string Username { get; set; } public string Username { get; set; }
public string Password { get; set; } // TODO ENCRYPTED public string Password { get; set; } // TODO ENCRYPTED
public string ApiKey { get; set; } // TODO ENCRYPTED public string ApiKey { get; set; } // TODO ENCRYPTED
public bool Active { get; set; } public bool Active { get; set; }
public string Value { get; set; }
public string ValueRefresh { get; set; }
} }
} }

View File

@ -240,6 +240,18 @@ namespace MyCore.Interfaces.Models
[BsonElement("LinkQuality")] [BsonElement("LinkQuality")]
public int LinkQuality { get; set; } // Example: 84 LQI public int LinkQuality { get; set; } // Example: 84 LQI
[BsonElement("IsCO2")]
public bool IsCO2 { get; set; }
[BsonElement("CO2")]
public int CO2 { get; set; }
[BsonElement("IsNoise")]
public bool IsNoise { get; set; }
[BsonElement("Noise")]
public int Noise { get; set; } // decibel
public DeviceSummaryDTO ToSummaryDTO() public DeviceSummaryDTO ToSummaryDTO()
{ {
@ -319,6 +331,10 @@ namespace MyCore.Interfaces.Models
Voltage = Voltage, Voltage = Voltage,
IsLinkQuality = IsLinkQuality, IsLinkQuality = IsLinkQuality,
LinkQuality = LinkQuality, LinkQuality = LinkQuality,
IsCO2 = IsCO2,
CO2 = CO2,
IsNoise = IsNoise,
Noise = Noise,
}; };
} }
} }

View File

@ -46,6 +46,12 @@ namespace MyCore.Interfaces.Models
[BsonRequired] [BsonRequired]
public string Value { get; set; } // AS in kiwix => Access Token, Code, etc // TODO ENCRYPTED Hash with peper from appSettings etc public string Value { get; set; } // AS in kiwix => Access Token, Code, etc // TODO ENCRYPTED Hash with peper from appSettings etc
[BsonElement("ValueRefresh")]
public string ValueRefresh { get; set; } // TODO Refresh token
[BsonElement("ServiceHomeId")]
public string ServiceHomeId { get; set; }
[BsonElement("Active")] [BsonElement("Active")]
[BsonRequired] [BsonRequired]
public bool Active { get; set; } public bool Active { get; set; }
@ -58,6 +64,7 @@ namespace MyCore.Interfaces.Models
Type = Type, Type = Type,
Name = Name, Name = Name,
HomeId = HomeId, HomeId = HomeId,
ServiceHomeId = ServiceHomeId,
Endpoint = Endpoint, Endpoint = Endpoint,
/*Username = Username, /*Username = Username,
Password = Password, Password = Password,
@ -72,6 +79,7 @@ namespace MyCore.Interfaces.Models
arlo, arlo,
meross, meross,
yeelight, yeelight,
zigbee2mqtt zigbee2mqtt,
netatmo
} }
} }

View File

@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MyCore.Interfaces.Models
{
public class NetatmoDevice
{
public string id { get; set; }
public string type { get; set; }
public string name { get; set; }
public int setup_date { get; set; }
public string room_id { get; set; }
public string bridge { get; set; }
}
public class NetatmoRoom
{
public string id { get; set; }
public string name { get; set; }
public string type { get; set; }
public List<string> module_ids { get; set; }
}
public class NetatmoUser
{
public string id { get; set; }
public string email { get; set; }
public string language { get; set; }
public string locale { get; set; }
public int feel_like_algorithm { get; set; }
public int unit_pressure { get; set; }
public int unit_system { get; set; }
public int unit_wind { get; set; }
}
public class NetatmoPerson
{
public string id { get; set; }
public string pseudo { get; set; }
public string url { get; set; }
}
public class NetatmoHome
{
public string id { get; set; }
public string name { get; set; }
public int altitude { get; set; }
public List<decimal> coordinates { get; set; }
public string country { get; set; }
public string timezone { get; set; }
public List<NetatmoRoom> rooms { get; set; }
public List<NetatmoDevice> modules { get; set; }
public string temperature_control_mode { get; set; }
public string therm_mode { get; set; }
public int therm_setpoint_default_duration { get; set; }
public List<NetatmoPerson> persons { get; set; }
}
public class NetatmoCoachDevice
{
public string _id { get; set; }
public string station_name { get; set; }
public int date_setup { get; set; }
public int last_setup { get; set; }
public string type { get; set; }
public int last_status_store { get; set; }
public string module_name { get; set; }
public int firmware { get; set; }
public int wifi_status { get; set; }
public bool reachable { get; set; }
public bool co2_calibrating { get; set; }
public List<string> data_type { get; set; }
public NetatmoPlace place { get; set; }
public NetatmoDashboardData dashboard_data { get; set; }
}
public class NetatmoPlace
{
public int altitude { get; set; }
public string city { get; set; }
public string country { get; set; }
public string timezone { get; set; }
public List<decimal> location { get; set; }
}
public class NetatmoDashboardData
{
public int time_utc { get; set; }
public decimal Temperature { get; set; }
public int CO2 { get; set; }
public decimal Humidity { get; set; }
public int Noise { get; set; }
public decimal Pressure { get; set; }
public decimal AbsolutePressure { get; set; }
public int health_idx { get; set; }
public decimal min_temp { get; set; }
public decimal max_temp { get; set; }
public int date_max_temp { get; set; }
public int date_min_temp { get; set; }
}
public class NetatmoTokenResponse
{
public List<string> scope { get; set; }
public string access_token { get; set; }
public string refresh_token { get; set; }
public int expires_in { get; set; }
public int expire_in { get; set; }
}
}

View File

@ -62,7 +62,7 @@ namespace MyCore.Controllers
foreach (var device in devicesSummaryDTO) foreach (var device in devicesSummaryDTO)
{ {
device.ProviderName = _ProviderDatabaseService.GetById(homeId, device.ProviderId).Name; device.ProviderName = _ProviderDatabaseService.GetById(device.ProviderId).Name;
} }
return new OkObjectResult(devicesSummaryDTO); return new OkObjectResult(devicesSummaryDTO);

View File

@ -226,7 +226,7 @@ namespace MyCore.Service.Controllers
if (!HomeService.IsExist(_HomeDatabaseService, homeId)) if (!HomeService.IsExist(_HomeDatabaseService, homeId))
throw new KeyNotFoundException("Home not found"); throw new KeyNotFoundException("Home not found");
Provider provider = _ProviderDatabaseService.GetByType(ProviderType.zigbee2mqtt); Provider provider = _ProviderDatabaseService.GetByType(homeId, ProviderType.zigbee2mqtt);
if (provider == null) if (provider == null)
throw new KeyNotFoundException("Zigbee2mqtt provider not found"); throw new KeyNotFoundException("Zigbee2mqtt provider not found");

View File

@ -11,6 +11,7 @@ using MongoDB.Bson;
using Mqtt.Client.AspNetCore.Services; using Mqtt.Client.AspNetCore.Services;
using MyCore.Interfaces.DTO; using MyCore.Interfaces.DTO;
using MyCore.Interfaces.Models; using MyCore.Interfaces.Models;
using MyCore.Service.Services.Devices.SupportedDevices;
using MyCore.Services; using MyCore.Services;
using MyCore.Services.Devices; using MyCore.Services.Devices;
using MyCore.Services.MyControlPanel; using MyCore.Services.MyControlPanel;
@ -25,17 +26,19 @@ namespace MyCore.Service.Controllers
private HomeDatabaseService _HomeDatabaseService; private HomeDatabaseService _HomeDatabaseService;
private RoomDatabaseService _RoomDatabaseService; private RoomDatabaseService _RoomDatabaseService;
private DeviceDatabaseService _DeviceDatabaseService; private DeviceDatabaseService _DeviceDatabaseService;
private ProviderDatabaseService _ProviderDatabaseService;
private RoomService _RoomService; private RoomService _RoomService;
private readonly IMqttClientService _mqttClientService; private readonly IMqttClientService _mqttClientService;
//private readonly IMqttOnlineClientService _mqttOnlineClientService; //private readonly IMqttOnlineClientService _mqttOnlineClientService;
public RoomController(HomeDatabaseService homeDatabaseService, RoomDatabaseService roomDatabaseService, DeviceDatabaseService deviceDatabaseService, RoomService roomService, MqttClientServiceProvider provider)//, MqttClientOnlineServiceProvider onlineProvider) public RoomController(HomeDatabaseService homeDatabaseService, RoomDatabaseService roomDatabaseService, DeviceDatabaseService deviceDatabaseService, RoomService roomService, MqttClientServiceProvider provider, ProviderDatabaseService providerDatabaseService)//, MqttClientOnlineServiceProvider onlineProvider)
{ {
this._HomeDatabaseService = homeDatabaseService; this._HomeDatabaseService = homeDatabaseService;
this._RoomDatabaseService = roomDatabaseService; this._RoomDatabaseService = roomDatabaseService;
this._DeviceDatabaseService = deviceDatabaseService; this._DeviceDatabaseService = deviceDatabaseService;
this._RoomService = roomService; this._RoomService = roomService;
this._mqttClientService = provider.MqttClientService; this._mqttClientService = provider.MqttClientService;
this._ProviderDatabaseService = providerDatabaseService;
//this._mqttOnlineClientService = onlineProvider.MqttOnlineClientService; //this._mqttOnlineClientService = onlineProvider.MqttOnlineClientService;
} }
@ -74,7 +77,20 @@ namespace MyCore.Service.Controllers
try try
{ {
List<Room> rooms = _RoomDatabaseService.GetAll(homeId); List<Room> rooms = _RoomDatabaseService.GetAll(homeId);
List<RoomMainDetailDTO> roomMainDetailDTOs = new List<RoomMainDetailDTO>(); List<RoomMainDetailDTO> roomMainDetailDTOs = new List<RoomMainDetailDTO>();
Provider provider = _ProviderDatabaseService.GetByType(homeId, ProviderType.netatmo);
// refresh netatmo data
if (provider != null)
{
NetatmoService netatmoService = new NetatmoService(null, null, provider.Value, provider.ValueRefresh, provider, _ProviderDatabaseService);
List<NetatmoHome> netatmoHomes = netatmoService.GetHomeData();
List<NetatmoCoachDevice> netatmoCoachDevices = netatmoService.GetHomeCoachsData();
// Update local data
DeviceService.CreateOrUpdateNetatmoDevices(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, netatmoHomes, netatmoCoachDevices, provider);
}
foreach (var room in rooms) foreach (var room in rooms)
{ {
RoomMainDetailDTO roomMainDetailDTO = room.ToMainDetailsDTO(_DeviceDatabaseService.GetByRoom(room.Id).Select(d => d.ToDTO()).ToList()); RoomMainDetailDTO roomMainDetailDTO = room.ToMainDetailsDTO(_DeviceDatabaseService.GetByRoom(room.Id).Select(d => d.ToDTO()).ToList());

View File

@ -250,7 +250,7 @@ namespace Mqtt.Client.AspNetCore.Services
try try
{ {
var devices = JsonConvert.DeserializeObject<List<Zigbee2MqttDeviceConfig>>(message); var devices = JsonConvert.DeserializeObject<List<Zigbee2MqttDeviceConfig>>(message);
var zigbee2mqttProvider = _ProviderDatabaseService.GetByType(ProviderType.zigbee2mqtt); var zigbee2mqttProvider = _ProviderDatabaseService.GetByType(homeId, ProviderType.zigbee2mqtt);
if (zigbee2mqttProvider != null) if (zigbee2mqttProvider != null)
{ {
@ -275,7 +275,7 @@ namespace Mqtt.Client.AspNetCore.Services
try try
{ {
var devices = JsonConvert.DeserializeObject<List<Zigbee2MqttDevice>>(message); var devices = JsonConvert.DeserializeObject<List<Zigbee2MqttDevice>>(message);
var zigbee2mqttProvider = _ProviderDatabaseService.GetByType(ProviderType.zigbee2mqtt); var zigbee2mqttProvider = _ProviderDatabaseService.GetByType(homeId, ProviderType.zigbee2mqtt);
if (zigbee2mqttProvider != null) if (zigbee2mqttProvider != null)
{ {
@ -301,7 +301,7 @@ namespace Mqtt.Client.AspNetCore.Services
{ {
var groupsConvert = JsonConvert.DeserializeObject<List<Zigbee2MqttGroup>>(message); var groupsConvert = JsonConvert.DeserializeObject<List<Zigbee2MqttGroup>>(message);
var zigbee2mqttProvider = _ProviderDatabaseService.GetByType(ProviderType.zigbee2mqtt); var zigbee2mqttProvider = _ProviderDatabaseService.GetByType(homeId, ProviderType.zigbee2mqtt);
if (zigbee2mqttProvider != null) if (zigbee2mqttProvider != null)
{ {

View File

@ -192,7 +192,7 @@ namespace MyCore.Service.Services
{ {
case ActionType.DEVICE: case ActionType.DEVICE:
var deviceAction = _DeviceDatabaseService.GetById(action.DeviceId); var deviceAction = _DeviceDatabaseService.GetById(action.DeviceId);
var providerActionTest = _ProviderDatabaseService.GetById(home.Id, action.ProviderId); var providerActionTest = _ProviderDatabaseService.GetById(action.ProviderId);
DeviceNameForAction = deviceAction.Name; DeviceNameForAction = deviceAction.Name;
actionDeviceToTest = deviceAction; actionDeviceToTest = deviceAction;
@ -225,7 +225,7 @@ namespace MyCore.Service.Services
break; break;
} }
var providerAction = _ProviderDatabaseService.GetById(home.Id, action.ProviderId); var providerAction = _ProviderDatabaseService.GetById(action.ProviderId);
// Check if device exist // Check if device exist
if (actionDeviceToTest != null && providerAction != null) if (actionDeviceToTest != null && providerAction != null)

View File

@ -128,7 +128,7 @@ namespace MyCore.Service.Services
{ {
case ActionType.DEVICE: case ActionType.DEVICE:
var deviceAction = deviceDatabaseService.GetById(action.DeviceId); var deviceAction = deviceDatabaseService.GetById(action.DeviceId);
var providerActionTest = providerDatabaseService.GetById(homeId, action.ProviderId); var providerActionTest = providerDatabaseService.GetById(action.ProviderId);
DeviceNameForAction = deviceAction.Name; DeviceNameForAction = deviceAction.Name;
actionDeviceToTest = deviceAction; actionDeviceToTest = deviceAction;
@ -161,7 +161,7 @@ namespace MyCore.Service.Services
break; break;
} }
var providerAction = providerDatabaseService.GetById(homeId, action.ProviderId); var providerAction = providerDatabaseService.GetById(action.ProviderId);
// Check if device exist // Check if device exist
if (actionDeviceToTest != null && providerAction != null) if (actionDeviceToTest != null && providerAction != null)

View File

@ -37,7 +37,7 @@ namespace MyCore.Services.Devices
break; break;
} }
currentProvider = Enum.IsDefined(typeof(ProviderType), providerFromTopic) ? _ProviderDatabaseService.GetByType((ProviderType) Enum.Parse(typeof(ProviderType), providerFromTopic.ToLower())) : null; currentProvider = Enum.IsDefined(typeof(ProviderType), providerFromTopic) ? _ProviderDatabaseService.GetByType(home.Id, (ProviderType) Enum.Parse(typeof(ProviderType), providerFromTopic.ToLower())) : null;
if (currentProvider != null) if (currentProvider != null)
{ {

View File

@ -1,17 +1,23 @@
using Microsoft.AspNetCore.Mvc; using DevExpress.Data.Mask;
using Microsoft.AspNetCore.Mvc;
using Mqtt.Client.AspNetCore.Services; using Mqtt.Client.AspNetCore.Services;
using MyCore.Interfaces.DTO; using MyCore.Interfaces.DTO;
using MyCore.Interfaces.Models; using MyCore.Interfaces.Models;
using MyCore.Interfaces.Models.MyControlPanel; using MyCore.Interfaces.Models.MyControlPanel;
using MyCore.Service.Services.Devices.SupportedDevices;
using MyCore.Services.MyControlPanel; using MyCore.Services.MyControlPanel;
using Newtonsoft.Json; using Newtonsoft.Json;
using Swashbuckle.AspNetCore.Swagger;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Security.Authentication; using System.Security.Authentication;
using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Linq;
namespace MyCore.Services.Devices namespace MyCore.Services.Devices
{ {
@ -125,6 +131,44 @@ namespace MyCore.Services.Devices
// Todo structure SupportedOperations // Todo structure SupportedOperations
device.SupportedOperations = deviceDetailDTO.SupportedOperations; device.SupportedOperations = deviceDetailDTO.SupportedOperations;
// TODO CHECK HERE IF NOT ERASING DATA .. on zigbee connection
device.IsContact = deviceDetailDTO.IsContact;
device.Contact = deviceDetailDTO.Contact;
device.IsIlluminance = deviceDetailDTO.IsIlluminance;
device.Illuminance = deviceDetailDTO.Illuminance != null ? deviceDetailDTO.Illuminance.Value : 0;
device.IsBrightness = deviceDetailDTO.IsBrightness;
device.Brightness = deviceDetailDTO.Brightness;
device.IsState = deviceDetailDTO.IsState;
device.State = deviceDetailDTO.State;
device.IsColorTemp = deviceDetailDTO.IsColorTemp;
device.ColorTemp = deviceDetailDTO.ColorTemp;
device.IsColorXY = deviceDetailDTO.IsColorXY;
device.ColorX = deviceDetailDTO.ColorX;
device.ColorY = deviceDetailDTO.ColorY;
device.IsOccupation = deviceDetailDTO.IsOccupation;
device.Occupation = deviceDetailDTO.Occupation;
device.IsAlarm = deviceDetailDTO.IsAlarm;
device.Alarm = deviceDetailDTO.Alarm;
device.IsTemperature = deviceDetailDTO.IsTemperature;
device.Temperature = deviceDetailDTO.Temperature != null ? deviceDetailDTO.Temperature.Value : 0;
device.IsHumidity = deviceDetailDTO.IsHumidity;
device.Humidity = deviceDetailDTO.Humidity != null ? deviceDetailDTO.Humidity.Value : 0;
device.IsPressure = deviceDetailDTO.IsPressure;
device.Pressure = deviceDetailDTO.Pressure != null ? deviceDetailDTO.Pressure.Value : 0;
device.IsConsumption = deviceDetailDTO.IsConsumption;
device.Consumption = deviceDetailDTO.Consumption;
device.IsCurrentPower = deviceDetailDTO.IsCurrentPower;
device.CurrentPower = deviceDetailDTO.CurrentPower;
device.IsVoltage = deviceDetailDTO.IsVoltage;
device.Voltage = deviceDetailDTO.Voltage;
device.IsLinkQuality = deviceDetailDTO.IsLinkQuality;
device.LinkQuality = deviceDetailDTO.LinkQuality;
device.IsCO2 = deviceDetailDTO.IsCO2;
device.CO2 = deviceDetailDTO.CO2;
device.IsNoise = deviceDetailDTO.IsNoise;
device.Noise = deviceDetailDTO.Noise;
if (deviceDetailDTO.SupportedOperations != null) if (deviceDetailDTO.SupportedOperations != null)
{ {
foreach (var supportedOperation in deviceDetailDTO.SupportedOperations) foreach (var supportedOperation in deviceDetailDTO.SupportedOperations)
@ -159,6 +203,12 @@ namespace MyCore.Services.Devices
List<YeelightAPI.Device> yeelightDevices = await YeelightService.GetDevices(); List<YeelightAPI.Device> yeelightDevices = await YeelightService.GetDevices();
devices = CreateYeelightDevices(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, yeelightDevices, provider); devices = CreateYeelightDevices(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, yeelightDevices, provider);
break; break;
case ProviderType.netatmo:
NetatmoService netatmoService = new NetatmoService(provider.Username, provider.Password, provider.Value, provider.ValueRefresh, provider, _ProviderDatabaseService);
List<NetatmoHome> netatmoHomes = netatmoService.GetHomeData();
List<NetatmoCoachDevice> netatmoCoachDevices = netatmoService.GetHomeCoachsData();
devices = CreateOrUpdateNetatmoDevices(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, netatmoHomes, netatmoCoachDevices, provider);
break;
case ProviderType.zigbee2mqtt: case ProviderType.zigbee2mqtt:
if (MqttClientService.devices.Count > 0) if (MqttClientService.devices.Count > 0)
{ {
@ -570,6 +620,125 @@ namespace MyCore.Services.Devices
return new Dictionary<string, List<DeviceDetailDTO>>() { { "createdDevices", createdYeelightDevices } }; // TODO Check if exist not supported devices return new Dictionary<string, List<DeviceDetailDTO>>() { { "createdDevices", createdYeelightDevices } }; // TODO Check if exist not supported devices
} }
public static Dictionary<string, List<DeviceDetailDTO>> CreateOrUpdateNetatmoDevices(DeviceDatabaseService _DeviceDatabaseService, ProviderDatabaseService _ProviderDatabaseService, RoomDatabaseService _RoomDatabaseService, string homeId, List<NetatmoHome> netatmoHomes, List<NetatmoCoachDevice> netatmoCoachDevices, Provider provider)
{
List<DeviceDetailDTO> createdNetatmoDevices = new List<DeviceDetailDTO>();
List<Device> existingDevices = _DeviceDatabaseService.GetByProviderId(provider.Id);
List<NetatmoDevice> netatmoDevices = new List<NetatmoDevice>();
foreach (var netatmoHome in netatmoHomes)
{
netatmoDevices.AddRange(netatmoHome.modules);
}
//netatmoDevices = netatmoDevices.Where(yd => !existingDevices.Select(ed => ed.ServiceIdentification).ToList().Contains(yd.id)).ToList();
foreach (var netatmoDevice in netatmoDevices)
{
bool isExist = existingDevices.Select(ed => ed.ServiceIdentification).ToList().Contains(netatmoDevice.id);
var device = existingDevices.FirstOrDefault(ed => ed.ProviderId == provider.Id && ed.ServiceIdentification == netatmoDevice.id);
DeviceDetailDTO deviceDetailDTO = isExist && device != null ? device.ToDTO() : new DeviceDetailDTO();
if (!isExist)
{
deviceDetailDTO.CreatedDate = DateTime.Now;
deviceDetailDTO.ServiceIdentification = netatmoDevice.id;
deviceDetailDTO.ProviderId = provider.Id;
deviceDetailDTO.ProviderName = provider.Name;
deviceDetailDTO.Name = netatmoDevice.name;
deviceDetailDTO.Description = netatmoDevice.name; // As description not exist, put name in description
deviceDetailDTO.Model = netatmoDevice.type;
deviceDetailDTO.IpAddress = netatmoDevice.bridge;
deviceDetailDTO.ManufacturerName = provider.Type.ToString();
deviceDetailDTO.Model = netatmoDevice.type;
}
deviceDetailDTO.ConnectionStatus = ConnectionStatus.Connected;
switch (netatmoDevice.type)
{
case "NCO": //Détecteur de Monoxyde de Carbone Intelligent
deviceDetailDTO.Type = DeviceType.Environment;
deviceDetailDTO.Battery = true;
break;
case "NACamera":
deviceDetailDTO.Type = DeviceType.Camera;
break;
case "NAPlug":
deviceDetailDTO.Type = DeviceType.Gateway;
break;
case "NATherm1":
deviceDetailDTO.Type = DeviceType.Thermostat;
deviceDetailDTO.IsTemperature = true;
break;
case "NRV":
deviceDetailDTO.Type = DeviceType.Valve;
deviceDetailDTO.IsTemperature = true;
break;
}
deviceDetailDTO.MeansOfCommunications = new List<MeansOfCommunication>
{
MeansOfCommunication.Wifi
};
deviceDetailDTO.UpdatedDate = DateTime.Now;
createdNetatmoDevices.Add(CreateOrUpdate(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, deviceDetailDTO, !isExist));
}
//netatmoCoachDevices = netatmoCoachDevices.Where(yd => !existingDevices.Select(ed => ed.ServiceIdentification).ToList().Contains(yd._id)).ToList();
foreach (var netatmoCoachDevice in netatmoCoachDevices)
{
bool isExist = existingDevices.Select(ed => ed.ServiceIdentification).ToList().Contains(netatmoCoachDevice._id);
var device = existingDevices.FirstOrDefault(ed => ed.ProviderId == provider.Id && ed.ServiceIdentification == netatmoCoachDevice._id);
DeviceDetailDTO deviceDetailDTO = isExist && device != null ? device.ToDTO() : new DeviceDetailDTO();
if (!isExist)
{
deviceDetailDTO.CreatedDate = DateTime.Now;
deviceDetailDTO.ServiceIdentification = netatmoCoachDevice._id;
deviceDetailDTO.ProviderId = provider.Id;
deviceDetailDTO.ProviderName = provider.Name;
deviceDetailDTO.Name = netatmoCoachDevice.station_name;
deviceDetailDTO.Description = netatmoCoachDevice.module_name;
deviceDetailDTO.Model = netatmoCoachDevice.type;
deviceDetailDTO.ManufacturerName = provider.Type.ToString();
}
deviceDetailDTO.ConnectionStatus = netatmoCoachDevice.reachable ? ConnectionStatus.Connected : ConnectionStatus.Unknown;
switch (netatmoCoachDevice.type)
{
case "NHC": //Home coach classique (?)
deviceDetailDTO.Type = DeviceType.Environment;
deviceDetailDTO.Battery = false;
deviceDetailDTO.FirmwareVersion = netatmoCoachDevice.firmware.ToString();
//deviceDetailDTO.SupportedOperations = netatmoCoachDevice.data_type;
deviceDetailDTO.IsTemperature = true;
deviceDetailDTO.Temperature = netatmoCoachDevice.dashboard_data.Temperature;
deviceDetailDTO.IsHumidity = true;
deviceDetailDTO.Humidity = netatmoCoachDevice.dashboard_data.Humidity;
deviceDetailDTO.IsPressure = true;
deviceDetailDTO.Pressure = netatmoCoachDevice.dashboard_data.Pressure;
deviceDetailDTO.IsCO2 = true;
deviceDetailDTO.CO2 = netatmoCoachDevice.dashboard_data.CO2;
deviceDetailDTO.IsNoise = true;
deviceDetailDTO.Noise = netatmoCoachDevice.dashboard_data.Noise;
//TODO healthy index !
break;
}
deviceDetailDTO.MeansOfCommunications = new List<MeansOfCommunication>
{
MeansOfCommunication.Wifi
};
deviceDetailDTO.UpdatedDate = DateTime.Now;
createdNetatmoDevices.Add(CreateOrUpdate(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, deviceDetailDTO, !isExist));
}
return new Dictionary<string, List<DeviceDetailDTO>>() { { "createdDevices", createdNetatmoDevices } };
}
public static Device UpdateDeviceFromZigbeeEvent(Device device, Zigbee2MqttRequest zigbee2MqttRequest) public static Device UpdateDeviceFromZigbeeEvent(Device device, Zigbee2MqttRequest zigbee2MqttRequest)
{ {
if (zigbee2MqttRequest.state != null) if (zigbee2MqttRequest.state != null)

View File

@ -0,0 +1,267 @@
using EvtSource;
using MyCore.Interfaces.Models;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System;
using static MyCore.Services.ArloService;
using Newtonsoft.Json;
using System.Security.Authentication;
using MyCore.Interfaces.Models.Providers.Zigbee.Zigbee2Mqtt;
using DevExpress.Utils.OAuth;
using MyCore.Interfaces.DTO;
using System.Net;
using MyCore.Services;
using System.Linq;
namespace MyCore.Service.Services.Devices.SupportedDevices
{
public class NetatmoService
{
private const string _netatmoUrl = "https://api.netatmo.net";
private string _refreshTokenUrl = $"{_netatmoUrl}/oauth2/token";
private string _userUrl = $"{_netatmoUrl}/api/getuser";
private string _thermostatUrl = $"{_netatmoUrl}/api/getthermostatsdata";
private string _homeCoachUrl = $"{_netatmoUrl}/api/gethomecoachsdata";
private string _homeDataUrl = $"{_netatmoUrl}/api/homesdata";
private string _homeStatusUrl = $"{_netatmoUrl}/api/homestatus";
private static string _token;
private static string _refreshToken;
private static int _expiresIn;
private static string _clientId = "5d2c232d3693590011438281";
private static string _clientSecret = "qNyKemRyFa73qgUdV3QnEn295TNa88ZX6";
private List<NetatmoHome> netatmoHomes;
private List<NetatmoCoachDevice> netatmoCoachDevices;
private List<NetatmoDevice> netatmoDevices;
private NetatmoUser netatmoUser;
private Provider _provider;
private ProviderDatabaseService _ProviderDatabaseService;
public NetatmoService(string username, string password, string token, string refreshToken, Provider provider, ProviderDatabaseService providerDatabaseService) // TODO
{
try
{
/*_email = username;
_password = password;*/
_ProviderDatabaseService = providerDatabaseService;
_provider = provider;
if (token == null || refreshToken == null) {
// TODO get access token todo
} else {
_token = token;
_refreshToken = refreshToken;
}
// LOGIN
/*var loginTask = Task.Run(() => RequestURI(new Uri(_refreshTokenUrl), RequestType.Post));
loginTask.Wait();
if (loginTask.Result != "")
{
//RESULT TOKEN
var data = ((JObject)JsonConvert.DeserializeObject(loginTask.Result))["data"];
//_token = JsonConvert.DeserializeObject<LoginResult>(data.ToString());
}/*/
}
catch (Exception e)
{
_token = null;
_refreshToken = null;
throw new AuthenticationException("Bad service username or password");
}
}
public void RefreshToken()
{
var refreskTokentask = Task.Run(() => RequestURI(new Uri(_refreshTokenUrl), RequestType.Post, Request.Refresh, new List<dynamic>()));
refreskTokentask.Wait();
if (refreskTokentask.Result != "")
{
var result = ((JObject)JsonConvert.DeserializeObject(refreskTokentask.Result));
NetatmoTokenResponse netatmoTokenResponse = JsonConvert.DeserializeObject<NetatmoTokenResponse>(result.ToString());
_token = netatmoTokenResponse.access_token;
_refreshToken = netatmoTokenResponse.refresh_token;
_expiresIn = netatmoTokenResponse.expires_in;
//UPDATE provider
var providerToUpdate = _ProviderDatabaseService.GetById(_provider.Id);
providerToUpdate.Value = _token;
providerToUpdate.ValueRefresh = _refreshToken;
_ProviderDatabaseService.Update(_provider.Id, providerToUpdate);
}
else
throw new HttpRequestException("Error refreshing the access token");
}
public List<NetatmoHome> GetHomeData()
{
// GET Home data
var homeTask = Task.Run(() => RequestURI(new Uri(_homeDataUrl), RequestType.Get, Request.HomeData, new List<dynamic>()));
homeTask.Wait();
if (homeTask.Result != "")
{
var users = ((JObject)JsonConvert.DeserializeObject(homeTask.Result))["body"]["user"];
netatmoUser = JsonConvert.DeserializeObject<NetatmoUser>(users.ToString());
var homes = ((JObject)JsonConvert.DeserializeObject(homeTask.Result))["body"]["homes"];
netatmoHomes = JsonConvert.DeserializeObject<List<NetatmoHome>>(homes.ToString());
if (netatmoHomes.Count > 0)
{
var home = netatmoHomes.FirstOrDefault();
//UPDATE provider
var providerToUpdate = _ProviderDatabaseService.GetById(_provider.Id);
providerToUpdate.ServiceHomeId = home.id;
_ProviderDatabaseService.Update(_provider.Id, providerToUpdate);
}
}
else
throw new HttpRequestException("Error retrieving netatmo home data");
return netatmoHomes;
}
public List<NetatmoCoachDevice> GetHomeCoachsData()
{
// GET Home data
var homeCoachTask = Task.Run(() => RequestURI(new Uri(_homeCoachUrl), RequestType.Get, Request.HomeData, new List<dynamic>()));
homeCoachTask.Wait();
if (homeCoachTask.Result != "")
{
var user = ((JObject)JsonConvert.DeserializeObject(homeCoachTask.Result))["body"]["user"];
netatmoUser = JsonConvert.DeserializeObject<NetatmoUser>(user.ToString());
var devices = ((JObject)JsonConvert.DeserializeObject(homeCoachTask.Result))["body"]["devices"];
netatmoCoachDevices = JsonConvert.DeserializeObject<List<NetatmoCoachDevice>>(devices.ToString());
}
else
throw new HttpRequestException("Error retrieving netatmo home data");
return netatmoCoachDevices;
}
public List<dynamic> GetHomeStatus(string type)
{
// GET Home status
var homeStatusTask = Task.Run(() => RequestURI(new Uri(_homeStatusUrl), RequestType.Get, Request.HomeStatus, new List<dynamic>()));
homeStatusTask.Wait();
if (homeStatusTask.Result != "")
{
var homes = ((JObject)JsonConvert.DeserializeObject(homeStatusTask.Result))["body"]["homes"];
netatmoHomes = JsonConvert.DeserializeObject<List<NetatmoHome>>(homes.ToString());
}
else
throw new HttpRequestException("Error retrieving netatmo home status");
return null;
}
public enum Request
{
Refresh,
HomeData,
HomeStatus
}
async Task<string> RequestURI(Uri u, RequestType requestType, Request request, List<dynamic> parames) // TODO dictonnary for params
{
try
{
var response = string.Empty;
var body = "";
HttpContent c = null;
var attempsLeft = request == Request.Refresh ? 1 : 2;
while (attempsLeft > 0)
{
attempsLeft -= 1;
using (var client = new HttpClient())
{
switch (request)
{
case Request.Refresh:
body = $"grant_type=refresh_token&client_id={_clientId}&client_secret={_clientSecret}&refresh_token={_refreshToken}";
c = new StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded");
break;
case Request.HomeData:
body = $"home_id={_provider.ServiceHomeId}"; //{ _refreshToken} TODO
c = new StringContent(body, Encoding.UTF8, "multipart/form-data"); // TO TEST
break;
case Request.HomeStatus:
body = $"home_id={_provider.ServiceHomeId}&device_types=NAPlug"; //{ _refreshToken} TODO
c = new StringContent(body, Encoding.UTF8, "multipart/form-data"); // TO TEST
break;
}
client.DefaultRequestHeaders.Add("User-Agent", "okhttp/3.6.0");
if (_token != null && request != Request.Refresh)
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {_token}");
if (requestType == RequestType.Get)
{
HttpResponseMessage result = await client.GetAsync(u);
if (result.StatusCode == HttpStatusCode.Forbidden)
{
RefreshToken();
}
if (result.IsSuccessStatusCode)
{
attempsLeft = 0; // ok !
response = await result.Content.ReadAsStringAsync();
}
}
if (requestType == RequestType.Post)
{
if (request == Request.Refresh)
{
//c.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
}
else
{
c.Headers.Add("Content-Type", "application/json");
}
HttpResponseMessage result = await client.PostAsync(u, c);
if (result.StatusCode == HttpStatusCode.Forbidden)
{
RefreshToken();
}
if (result.IsSuccessStatusCode)
{
attempsLeft = 0; // ok !
response = await result.Content.ReadAsStringAsync();
}
}
}
}
return response;
}
catch (Exception e)
{
Console.WriteLine("NetatmoService - An error occured in RequestURI");
return null;
}
}
}
}

View File

@ -23,9 +23,9 @@ namespace MyCore.Services
return _Providers.Find(p => p.HomeId == homeId).ToList(); return _Providers.Find(p => p.HomeId == homeId).ToList();
} }
public Provider GetById(string homeId, string id) public Provider GetById(string id)
{ {
return _Providers.Find<Provider>(p => p.Id == id && p.HomeId == homeId).FirstOrDefault(); return _Providers.Find<Provider>(p => p.Id == id).FirstOrDefault();
} }
public List<Provider> GetByHomeId(string homeId) public List<Provider> GetByHomeId(string homeId)
@ -43,9 +43,9 @@ namespace MyCore.Services
return _Providers.Find<Provider>(p => p.Name == name).FirstOrDefault(); return _Providers.Find<Provider>(p => p.Name == name).FirstOrDefault();
} }
public Provider GetByType(ProviderType type) public Provider GetByType(string homeId, ProviderType type)
{ {
return _Providers.Find<Provider>(p => p.Type == type).FirstOrDefault(); return _Providers.Find<Provider>(p => p.Type == type && p.HomeId == homeId).FirstOrDefault();
} }
public bool IsExist(string id) public bool IsExist(string id)

View File

@ -12,7 +12,7 @@ namespace MyCore.Services.MyControlPanel
{ {
public static bool IsExist(ProviderDatabaseService _ProviderDatabaseService, string homeId, string providerId) public static bool IsExist(ProviderDatabaseService _ProviderDatabaseService, string homeId, string providerId)
{ {
return _ProviderDatabaseService.GetById(homeId, providerId) != null ? true : false; return _ProviderDatabaseService.GetById(providerId) != null ? true : false;
} }
public static List<Provider> GetAll(ProviderDatabaseService _ProviderDatabaseService, string homeId) public static List<Provider> GetAll(ProviderDatabaseService _ProviderDatabaseService, string homeId)
@ -27,7 +27,7 @@ namespace MyCore.Services.MyControlPanel
provider = new Provider(); provider = new Provider();
else else
{ {
provider = _ProviderDatabaseService.GetById(homeId, providerDTO.Id); provider = _ProviderDatabaseService.GetById(providerDTO.Id);
} }
provider.Type = providerDTO.Type; provider.Type = providerDTO.Type;
@ -36,7 +36,10 @@ namespace MyCore.Services.MyControlPanel
provider.HomeId = providerDTO.HomeId; provider.HomeId = providerDTO.HomeId;
provider.Username = providerDTO.Username; provider.Username = providerDTO.Username;
provider.Password = providerDTO.Password; provider.Password = providerDTO.Password;
provider.Value = providerDTO.Value;
provider.ValueRefresh = providerDTO.ValueRefresh;
provider.ApiKey = providerDTO.ApiKey; provider.ApiKey = providerDTO.ApiKey;
provider.ServiceHomeId = providerDTO.ServiceHomeId;
provider.Active = true; provider.Active = true;
if (create) if (create)
@ -47,7 +50,7 @@ namespace MyCore.Services.MyControlPanel
public static Provider GetProviderById(ProviderDatabaseService _ProviderDatabaseService, string homeId, string providerId) public static Provider GetProviderById(ProviderDatabaseService _ProviderDatabaseService, string homeId, string providerId)
{ {
return _ProviderDatabaseService.GetById(homeId, providerId); return _ProviderDatabaseService.GetById(providerId);
} }
} }
} }