using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Authentication;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Bson;
using Mqtt.Client.AspNetCore.Services;
using MyCore.Interfaces.DTO;
using MyCore.Interfaces.Models;
using MyCore.Services;
using MyCore.Services.Devices;
using MyCore.Services.MyControlPanel;
namespace MyCore.Controllers
{
[Authorize] // TODO Add ROLES (Roles = "Admin")
[Route("api/device")]
[ApiController]
public class DeviceController : ControllerBase
{
private DeviceDatabaseService _DeviceDatabaseService;
private ProviderDatabaseService _ProviderDatabaseService;
private RoomDatabaseService _RoomDatabaseService;
private HomeDatabaseService _HomeDatabaseService;
private readonly IMqttClientService _mqttClientService;
//private readonly IMqttOnlineClientService _mqttOnlineClientService;
public DeviceController(DeviceDatabaseService DeviceDatabaseService, ProviderDatabaseService ProviderDatabaseService, RoomDatabaseService RoomDatabaseService, HomeDatabaseService HomeDatabaseService, MqttClientServiceProvider provider)//, MqttClientOnlineServiceProvider onlineProvider)
{
this._DeviceDatabaseService = DeviceDatabaseService;
this._ProviderDatabaseService = ProviderDatabaseService;
this._RoomDatabaseService = RoomDatabaseService;
this._HomeDatabaseService = HomeDatabaseService;
this._mqttClientService = provider.MqttClientService;
//this._mqttOnlineClientService = onlineProvider.MqttOnlineClientService;
}
///
/// Get all devices summary
///
/// Home Id
[ProducesResponseType(typeof(List), 200)]
[ProducesResponseType(typeof(string), 500)]
[HttpGet("{homeId}")]
public ObjectResult GetAll(string homeId)
{
try
{
List Devices = _DeviceDatabaseService.GetAll(homeId);
List devicesSummaryDTO = Devices.Select(d => d.ToSummaryDTO()).ToList();
foreach (var device in devicesSummaryDTO)
{
device.ProviderName = _ProviderDatabaseService.GetById(homeId, device.ProviderId).Name;
}
return new OkObjectResult(devicesSummaryDTO);
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Get a specific device info
///
/// id of device
[ProducesResponseType(typeof(DeviceDetailDTO), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpGet("detail/{deviceId}")]
public ObjectResult GetDetail(string deviceId)
{
try
{
if (deviceId == null)
throw new ArgumentNullException("Incorrect parameters");
Device device = _DeviceDatabaseService.GetById(deviceId);
if (device == null)
throw new KeyNotFoundException("Device does not exist");
return new OkObjectResult(device.ToDTO());
}
catch (ArgumentNullException ex)
{
return new BadRequestObjectResult(ex.Message) { };
}
catch (KeyNotFoundException ex)
{
return new NotFoundObjectResult(ex.Message) { };
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Get list of devices from a type
///
/// Home Id
/// device type
[ProducesResponseType(typeof(List), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 500)]
[HttpGet("{homeId}/type/{type}")]
public ObjectResult GetDevicesByType(string homeId, DeviceType type)
{
try
{
if (homeId == null)
throw new ArgumentNullException("Incorrect parameters");
List devices = _DeviceDatabaseService.GetByType(homeId, type);
return new OkObjectResult(devices.Select(d => d.ToDTO()));
}
catch (ArgumentNullException ex)
{
return new BadRequestObjectResult(ex.Message) { };
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Create a device
///
/// Device to create
[ProducesResponseType(typeof(DeviceDetailDTO), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 409)]
[ProducesResponseType(typeof(string), 500)]
[HttpPost]
public ObjectResult Create([FromBody] DeviceDetailDTO deviceDetailDTO)
{
try
{
if (deviceDetailDTO == null)
throw new ArgumentNullException("Incorrect parameters");
DeviceDetailDTO deviceCreated = DeviceService.CreateOrUpdate(this._DeviceDatabaseService, this._ProviderDatabaseService, this._RoomDatabaseService, deviceDetailDTO.HomeId, deviceDetailDTO, true);
return new OkObjectResult(deviceCreated);
}
catch (ArgumentNullException ex)
{
return new BadRequestObjectResult(ex.Message) { };
}
catch (DuplicateWaitObjectException ex)
{
return new ConflictObjectResult(ex.Message) { };
}
catch (KeyNotFoundException ex)
{
return new NotFoundObjectResult(ex.Message) { };
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Create devices from provider
///
/// Home Id
/// Id of Provider
[ProducesResponseType(typeof(List), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 401)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 421)]
[ProducesResponseType(typeof(string), 500)]
[HttpPost("{homeId}/fromProvider/{providerId}")]
public async Task CreateDevicesFromProvider(string homeId, string providerId)
{
try
{
if (homeId == null)
throw new ArgumentNullException("Invalid paramaters");
if (!HomeService.IsExist(_HomeDatabaseService, homeId))
throw new KeyNotFoundException("Home not found");
Provider provider = ProviderService.GetProviderById(this._ProviderDatabaseService, homeId, providerId);
if (provider == null)
throw new KeyNotFoundException("Provider not found");
Dictionary> devices = await DeviceService.CreateFromProvider(this._DeviceDatabaseService, this._ProviderDatabaseService, this._RoomDatabaseService, homeId, provider);
return new OkObjectResult(devices);
}
catch (ArgumentNullException ex)
{
return new BadRequestObjectResult(ex.Message) {};
}
catch (KeyNotFoundException ex)
{
return new NotFoundObjectResult(ex.Message) {};
}
catch (AuthenticationException ex)
{
return new UnauthorizedObjectResult(ex.Message) {};
}
catch (HttpRequestException ex) // Not ok if not http request..
{
return new BadRequestObjectResult(ex.Message) { StatusCode = 421 };
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Get all zigbee2Mqtt devices
///
/// Home Id
[ProducesResponseType(typeof(List), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpGet("zigbee2Mqtt/{homeId}")]
public ObjectResult GetDevicesFromZigbee2Mqtt(string homeId)
{
try
{
if (homeId == null)
throw new ArgumentNullException("Invalid paramaters");
if (!HomeService.IsExist(_HomeDatabaseService, homeId))
throw new KeyNotFoundException("Home not found");
// GET ALL LOCAL DEVICES
var devices = MqttClientService.devices; // Be carefull, we only got the exact result after each connection
return new OkObjectResult(devices);
}
catch (ArgumentNullException ex)
{
return new BadRequestObjectResult(ex.Message) {};
}
catch (KeyNotFoundException ex)
{
return new NotFoundObjectResult(ex.Message) {};
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Get devices from provider
///
/// Home Id
/// Id of Provider
[ProducesResponseType(typeof(List), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpGet("{homeId}/fromProvider/{providerId}")]
public ObjectResult GetDevicesFromProvider(string homeId, string providerId)
{
try
{
if (homeId == null || providerId == null)
throw new ArgumentNullException("Invalid paramaters");
if (!_HomeDatabaseService.IsExist(homeId))
throw new KeyNotFoundException("Home does not exist");
if (!_ProviderDatabaseService.IsExist(providerId))
throw new KeyNotFoundException("Provider does not exist");
List devices = _DeviceDatabaseService.GetByProviderId(providerId);
return new OkObjectResult(devices.Select(d => d.ToDTO()));
}
catch (ArgumentNullException ex)
{
return new BadRequestObjectResult(ex.Message) {};
}
catch (KeyNotFoundException ex)
{
return new BadRequestObjectResult(ex.Message) {};
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Update a device
///
/// Device to update
[ProducesResponseType(typeof(DeviceDetailDTO), 200)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpPut("{deviceId}")]
public ObjectResult Update([FromBody] DeviceDetailDTO deviceDetailDTO)
{
try
{
if (!_DeviceDatabaseService.IsExist(deviceDetailDTO.Id))
throw new KeyNotFoundException("Device does not exist");
DeviceDetailDTO deviceUpdated = DeviceService.CreateOrUpdate(this._DeviceDatabaseService, this._ProviderDatabaseService, this._RoomDatabaseService, deviceDetailDTO.HomeId, deviceDetailDTO, false);
return new OkObjectResult(deviceUpdated);
}
catch (KeyNotFoundException ex)
{
return new BadRequestObjectResult(ex.Message) {};
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Delete a device
///
/// Id of device to delete
[ProducesResponseType(typeof(string), 202)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpDelete("{deviceId}")]
public ObjectResult Delete(string deviceId)
{
try
{
if (deviceId == null)
throw new ArgumentNullException("Invalid paramaters");
if (!_DeviceDatabaseService.IsExist(deviceId))
throw new KeyNotFoundException("Device does not exist");
// TODO REMOVE DEVICE ID IN AUTOMATION and delete automation if none device ?
_DeviceDatabaseService.Remove(deviceId);
return new ObjectResult("Device has been deleted") { StatusCode = 202 };
}
catch (ArgumentNullException ex)
{
return new BadRequestObjectResult(ex.Message) {};
}
catch (KeyNotFoundException ex)
{
return new NotFoundObjectResult(ex.Message) {};
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Delete devices from provider
///
/// Home Id
/// Id of Provider
[ProducesResponseType(typeof(string), 202)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpDelete("{homeId}/fromProvider/{providerId}")]
public ObjectResult DeleteDevicesFromProvider(string homeId, string providerId)
{
try
{
if (homeId == null || providerId == null)
throw new ArgumentNullException("Invalid paramaters");
if (!_HomeDatabaseService.IsExist(homeId))
throw new KeyNotFoundException("Home does not exist");
if (!_ProviderDatabaseService.IsExist(providerId))
throw new KeyNotFoundException("Provider does not exist");
// TODO REMOVE DEVICE ID IN AUTOMATION and delete automation if none device ?
_DeviceDatabaseService.RemoveForProvider(providerId);
return new ObjectResult("Provider devices has been successfully deleted") { StatusCode = 202 };
}
catch (ArgumentNullException ex)
{
return new BadRequestObjectResult(ex.Message) {};
}
catch (KeyNotFoundException ex)
{
return new NotFoundObjectResult(ex.Message) {};
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Delete all device for a specified home
///
/// Id of home
[ProducesResponseType(typeof(string), 202)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpDelete("home/{homeId}")]
public ObjectResult DeleteAllForHome(string homeId)
{
try
{
if (homeId == null)
throw new ArgumentNullException("Invalid paramaters");
if (!_HomeDatabaseService.IsExist(homeId))
throw new KeyNotFoundException("Home does not exist");
// TODO REMOVE DEVICE ID IN AUTOMATION and delete automation if none device ?
_DeviceDatabaseService.RemoveForHome(homeId);
return new ObjectResult("Home devices has been successfully deleted") { StatusCode = 202 };
}
catch (ArgumentNullException ex)
{
return new BadRequestObjectResult(ex.Message) {};
}
catch (KeyNotFoundException ex)
{
return new NotFoundObjectResult(ex.Message) {};
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
}
}