mirror of
https://bitbucket.org/myhomie/mycorerepository.git
synced 2025-12-06 09:41:19 +00:00
Add netatmo provider ! + clean code
This commit is contained in:
parent
97fc143865
commit
2ebb1dfd60
@ -157,5 +157,13 @@ namespace MyCore.Interfaces.DTO
|
||||
public bool IsLinkQuality { 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
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,10 +12,13 @@ namespace MyCore.Interfaces.DTO
|
||||
public string Name { get; set; }
|
||||
public ProviderType Type { get; set; }
|
||||
public string HomeId { get; set; }
|
||||
public string ServiceHomeId { get; set; }
|
||||
public string Endpoint { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; } // TODO ENCRYPTED
|
||||
public string ApiKey { get; set; } // TODO ENCRYPTED
|
||||
public bool Active { get; set; }
|
||||
public string Value { get; set; }
|
||||
public string ValueRefresh { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,6 +240,18 @@ namespace MyCore.Interfaces.Models
|
||||
[BsonElement("LinkQuality")]
|
||||
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()
|
||||
{
|
||||
@ -319,6 +331,10 @@ namespace MyCore.Interfaces.Models
|
||||
Voltage = Voltage,
|
||||
IsLinkQuality = IsLinkQuality,
|
||||
LinkQuality = LinkQuality,
|
||||
IsCO2 = IsCO2,
|
||||
CO2 = CO2,
|
||||
IsNoise = IsNoise,
|
||||
Noise = Noise,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,6 +46,12 @@ namespace MyCore.Interfaces.Models
|
||||
[BsonRequired]
|
||||
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")]
|
||||
[BsonRequired]
|
||||
public bool Active { get; set; }
|
||||
@ -58,6 +64,7 @@ namespace MyCore.Interfaces.Models
|
||||
Type = Type,
|
||||
Name = Name,
|
||||
HomeId = HomeId,
|
||||
ServiceHomeId = ServiceHomeId,
|
||||
Endpoint = Endpoint,
|
||||
/*Username = Username,
|
||||
Password = Password,
|
||||
@ -72,6 +79,7 @@ namespace MyCore.Interfaces.Models
|
||||
arlo,
|
||||
meross,
|
||||
yeelight,
|
||||
zigbee2mqtt
|
||||
zigbee2mqtt,
|
||||
netatmo
|
||||
}
|
||||
}
|
||||
|
||||
112
MyCore.Interfaces/Models/Providers/Netatmo/NetatmoDevice.cs
Normal file
112
MyCore.Interfaces/Models/Providers/Netatmo/NetatmoDevice.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
@ -62,7 +62,7 @@ namespace MyCore.Controllers
|
||||
|
||||
foreach (var device in devicesSummaryDTO)
|
||||
{
|
||||
device.ProviderName = _ProviderDatabaseService.GetById(homeId, device.ProviderId).Name;
|
||||
device.ProviderName = _ProviderDatabaseService.GetById(device.ProviderId).Name;
|
||||
}
|
||||
|
||||
return new OkObjectResult(devicesSummaryDTO);
|
||||
|
||||
@ -226,7 +226,7 @@ namespace MyCore.Service.Controllers
|
||||
if (!HomeService.IsExist(_HomeDatabaseService, homeId))
|
||||
throw new KeyNotFoundException("Home not found");
|
||||
|
||||
Provider provider = _ProviderDatabaseService.GetByType(ProviderType.zigbee2mqtt);
|
||||
Provider provider = _ProviderDatabaseService.GetByType(homeId, ProviderType.zigbee2mqtt);
|
||||
if (provider == null)
|
||||
throw new KeyNotFoundException("Zigbee2mqtt provider not found");
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ using MongoDB.Bson;
|
||||
using Mqtt.Client.AspNetCore.Services;
|
||||
using MyCore.Interfaces.DTO;
|
||||
using MyCore.Interfaces.Models;
|
||||
using MyCore.Service.Services.Devices.SupportedDevices;
|
||||
using MyCore.Services;
|
||||
using MyCore.Services.Devices;
|
||||
using MyCore.Services.MyControlPanel;
|
||||
@ -25,17 +26,19 @@ namespace MyCore.Service.Controllers
|
||||
private HomeDatabaseService _HomeDatabaseService;
|
||||
private RoomDatabaseService _RoomDatabaseService;
|
||||
private DeviceDatabaseService _DeviceDatabaseService;
|
||||
private ProviderDatabaseService _ProviderDatabaseService;
|
||||
private RoomService _RoomService;
|
||||
private readonly IMqttClientService _mqttClientService;
|
||||
//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._RoomDatabaseService = roomDatabaseService;
|
||||
this._DeviceDatabaseService = deviceDatabaseService;
|
||||
this._RoomService = roomService;
|
||||
this._mqttClientService = provider.MqttClientService;
|
||||
this._ProviderDatabaseService = providerDatabaseService;
|
||||
//this._mqttOnlineClientService = onlineProvider.MqttOnlineClientService;
|
||||
}
|
||||
|
||||
@ -74,7 +77,20 @@ namespace MyCore.Service.Controllers
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
RoomMainDetailDTO roomMainDetailDTO = room.ToMainDetailsDTO(_DeviceDatabaseService.GetByRoom(room.Id).Select(d => d.ToDTO()).ToList());
|
||||
|
||||
@ -250,7 +250,7 @@ namespace Mqtt.Client.AspNetCore.Services
|
||||
try
|
||||
{
|
||||
var devices = JsonConvert.DeserializeObject<List<Zigbee2MqttDeviceConfig>>(message);
|
||||
var zigbee2mqttProvider = _ProviderDatabaseService.GetByType(ProviderType.zigbee2mqtt);
|
||||
var zigbee2mqttProvider = _ProviderDatabaseService.GetByType(homeId, ProviderType.zigbee2mqtt);
|
||||
|
||||
if (zigbee2mqttProvider != null)
|
||||
{
|
||||
@ -275,7 +275,7 @@ namespace Mqtt.Client.AspNetCore.Services
|
||||
try
|
||||
{
|
||||
var devices = JsonConvert.DeserializeObject<List<Zigbee2MqttDevice>>(message);
|
||||
var zigbee2mqttProvider = _ProviderDatabaseService.GetByType(ProviderType.zigbee2mqtt);
|
||||
var zigbee2mqttProvider = _ProviderDatabaseService.GetByType(homeId, ProviderType.zigbee2mqtt);
|
||||
|
||||
if (zigbee2mqttProvider != null)
|
||||
{
|
||||
@ -301,7 +301,7 @@ namespace Mqtt.Client.AspNetCore.Services
|
||||
{
|
||||
var groupsConvert = JsonConvert.DeserializeObject<List<Zigbee2MqttGroup>>(message);
|
||||
|
||||
var zigbee2mqttProvider = _ProviderDatabaseService.GetByType(ProviderType.zigbee2mqtt);
|
||||
var zigbee2mqttProvider = _ProviderDatabaseService.GetByType(homeId, ProviderType.zigbee2mqtt);
|
||||
|
||||
if (zigbee2mqttProvider != null)
|
||||
{
|
||||
|
||||
@ -192,7 +192,7 @@ namespace MyCore.Service.Services
|
||||
{
|
||||
case ActionType.DEVICE:
|
||||
var deviceAction = _DeviceDatabaseService.GetById(action.DeviceId);
|
||||
var providerActionTest = _ProviderDatabaseService.GetById(home.Id, action.ProviderId);
|
||||
var providerActionTest = _ProviderDatabaseService.GetById(action.ProviderId);
|
||||
|
||||
DeviceNameForAction = deviceAction.Name;
|
||||
actionDeviceToTest = deviceAction;
|
||||
@ -225,7 +225,7 @@ namespace MyCore.Service.Services
|
||||
break;
|
||||
}
|
||||
|
||||
var providerAction = _ProviderDatabaseService.GetById(home.Id, action.ProviderId);
|
||||
var providerAction = _ProviderDatabaseService.GetById(action.ProviderId);
|
||||
|
||||
// Check if device exist
|
||||
if (actionDeviceToTest != null && providerAction != null)
|
||||
|
||||
@ -128,7 +128,7 @@ namespace MyCore.Service.Services
|
||||
{
|
||||
case ActionType.DEVICE:
|
||||
var deviceAction = deviceDatabaseService.GetById(action.DeviceId);
|
||||
var providerActionTest = providerDatabaseService.GetById(homeId, action.ProviderId);
|
||||
var providerActionTest = providerDatabaseService.GetById(action.ProviderId);
|
||||
|
||||
DeviceNameForAction = deviceAction.Name;
|
||||
actionDeviceToTest = deviceAction;
|
||||
@ -161,7 +161,7 @@ namespace MyCore.Service.Services
|
||||
break;
|
||||
}
|
||||
|
||||
var providerAction = providerDatabaseService.GetById(homeId, action.ProviderId);
|
||||
var providerAction = providerDatabaseService.GetById(action.ProviderId);
|
||||
|
||||
// Check if device exist
|
||||
if (actionDeviceToTest != null && providerAction != null)
|
||||
|
||||
@ -37,7 +37,7 @@ namespace MyCore.Services.Devices
|
||||
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)
|
||||
{
|
||||
|
||||
@ -1,17 +1,23 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DevExpress.Data.Mask;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Mqtt.Client.AspNetCore.Services;
|
||||
using MyCore.Interfaces.DTO;
|
||||
using MyCore.Interfaces.Models;
|
||||
using MyCore.Interfaces.Models.MyControlPanel;
|
||||
using MyCore.Service.Services.Devices.SupportedDevices;
|
||||
using MyCore.Services.MyControlPanel;
|
||||
using Newtonsoft.Json;
|
||||
using Swashbuckle.AspNetCore.Swagger;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace MyCore.Services.Devices
|
||||
{
|
||||
@ -125,6 +131,44 @@ namespace MyCore.Services.Devices
|
||||
// Todo structure 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)
|
||||
{
|
||||
foreach (var supportedOperation in deviceDetailDTO.SupportedOperations)
|
||||
@ -159,6 +203,12 @@ namespace MyCore.Services.Devices
|
||||
List<YeelightAPI.Device> yeelightDevices = await YeelightService.GetDevices();
|
||||
devices = CreateYeelightDevices(_DeviceDatabaseService, _ProviderDatabaseService, _RoomDatabaseService, homeId, yeelightDevices, provider);
|
||||
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:
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (zigbee2MqttRequest.state != null)
|
||||
|
||||
267
MyCore/Services/Devices/SupportedDevices/NetatmoService.cs
Normal file
267
MyCore/Services/Devices/SupportedDevices/NetatmoService.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -23,9 +23,9 @@ namespace MyCore.Services
|
||||
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)
|
||||
@ -43,9 +43,9 @@ namespace MyCore.Services
|
||||
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)
|
||||
|
||||
@ -12,7 +12,7 @@ namespace MyCore.Services.MyControlPanel
|
||||
{
|
||||
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)
|
||||
@ -27,7 +27,7 @@ namespace MyCore.Services.MyControlPanel
|
||||
provider = new Provider();
|
||||
else
|
||||
{
|
||||
provider = _ProviderDatabaseService.GetById(homeId, providerDTO.Id);
|
||||
provider = _ProviderDatabaseService.GetById(providerDTO.Id);
|
||||
}
|
||||
|
||||
provider.Type = providerDTO.Type;
|
||||
@ -36,7 +36,10 @@ namespace MyCore.Services.MyControlPanel
|
||||
provider.HomeId = providerDTO.HomeId;
|
||||
provider.Username = providerDTO.Username;
|
||||
provider.Password = providerDTO.Password;
|
||||
provider.Value = providerDTO.Value;
|
||||
provider.ValueRefresh = providerDTO.ValueRefresh;
|
||||
provider.ApiKey = providerDTO.ApiKey;
|
||||
provider.ServiceHomeId = providerDTO.ServiceHomeId;
|
||||
provider.Active = true;
|
||||
|
||||
if (create)
|
||||
@ -47,7 +50,7 @@ namespace MyCore.Services.MyControlPanel
|
||||
|
||||
public static Provider GetProviderById(ProviderDatabaseService _ProviderDatabaseService, string homeId, string providerId)
|
||||
{
|
||||
return _ProviderDatabaseService.GetById(homeId, providerId);
|
||||
return _ProviderDatabaseService.GetById(providerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user