457 lines
17 KiB
C#

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 LocationDatabaseService _LocationDatabaseService;
private UserDatabaseService _UserDatabaseService;
private readonly IMqttClientService _mqttClientService;
//private readonly IMqttOnlineClientService _mqttOnlineClientService;
public DeviceController(DeviceDatabaseService DeviceDatabaseService, ProviderDatabaseService ProviderDatabaseService, LocationDatabaseService LocationDatabaseService, UserDatabaseService UserDatabaseService, MqttClientServiceProvider provider)//, MqttClientOnlineServiceProvider onlineProvider)
{
this._DeviceDatabaseService = DeviceDatabaseService;
this._ProviderDatabaseService = ProviderDatabaseService;
this._LocationDatabaseService = LocationDatabaseService;
this._UserDatabaseService = UserDatabaseService;
this._mqttClientService = provider.MqttClientService;
//this._mqttOnlineClientService = onlineProvider.MqttOnlineClientService;
}
/// <summary>
/// Get all devices summary
/// </summary>
/// <param name="userId">Id of user</param>
[ProducesResponseType(typeof(List<DeviceSummaryDTO>), 200)]
[ProducesResponseType(typeof(string), 500)]
[HttpGet("{userId}")]
public ObjectResult GetAll(string userId)
{
try
{
List<Device> Devices = _DeviceDatabaseService.GetAll(userId);
List<DeviceSummaryDTO> devicesSummaryDTO = Devices.Select(d => d.ToSummaryDTO()).ToList();
foreach (var device in devicesSummaryDTO)
{
device.ProviderName = _ProviderDatabaseService.GetById(userId, device.ProviderId).Name;
}
return new OkObjectResult(devicesSummaryDTO);
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
/// <summary>
/// Get a specific device info
/// </summary>
/// <param name="deviceId">id of device</param>
[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 };
}
}
/// <summary>
/// Get list of devices from a type
/// </summary>
/// <param name="userId">user Id</param>
/// <param name="type">device type</param>
[ProducesResponseType(typeof(List<DeviceDetailDTO>), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 500)]
[HttpGet("{userId}/type/{type}")]
public ObjectResult GetDevicesByType(string userId, DeviceType type)
{
try
{
if (userId == null)
throw new ArgumentNullException("Incorrect parameters");
List<Device> devices = _DeviceDatabaseService.GetByType(userId, 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 };
}
}
/// <summary>
/// Create a device
/// </summary>
/// <param name="deviceDetailDTO">Device to create</param>
[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._LocationDatabaseService, deviceDetailDTO.UserId, 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 };
}
}
/// <summary>
/// Create devices from provider
/// </summary>
/// <param name="userId">User Id</param>
/// <param name="providerId">Id of Provider</param>
[ProducesResponseType(typeof(List<DeviceDetailDTO>), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 401)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 421)]
[ProducesResponseType(typeof(string), 500)]
[HttpPost("{userId}/fromProvider/{providerId}")]
public async Task<ObjectResult> CreateDevicesFromProvider(string userId, string providerId)
{
try
{
if (userId == null)
throw new ArgumentNullException("Invalid paramaters");
if (!UserService.IsExist(_UserDatabaseService, userId))
throw new KeyNotFoundException("User not found");
Provider provider = ProviderService.GetProviderById(this._ProviderDatabaseService, userId, providerId);
if (provider == null)
throw new KeyNotFoundException("Provider not found");
Dictionary<string, List<DeviceDetailDTO>> devices = await DeviceService.CreateFromProvider(this._DeviceDatabaseService, this._ProviderDatabaseService, this._LocationDatabaseService, userId, 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 };
}
}
/// <summary>
/// Get all zigbee2Mqtt devices
/// </summary>
/// <param name="userId">User Id</param>
[ProducesResponseType(typeof(List<DeviceDetailDTO>), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpGet("zigbee2Mqtt/{userId}")]
public ObjectResult GetDevicesFromZigbee2Mqtt(string userId)
{
try
{
if (userId == null)
throw new ArgumentNullException("Invalid paramaters");
if (!UserService.IsExist(_UserDatabaseService, userId))
throw new KeyNotFoundException("User 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 };
}
}
/// <summary>
/// Get devices from provider
/// </summary>
/// <param name="userId">User Id</param>
/// <param name="providerId">Id of Provider</param>
[ProducesResponseType(typeof(List<DeviceDetailDTO>), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpGet("{userId}/fromProvider/{providerId}")]
public ObjectResult GetDevicesFromProvider(string userId, string providerId)
{
try
{
if (userId == null || providerId == null)
throw new ArgumentNullException("Invalid paramaters");
if (!_UserDatabaseService.IsExist(userId))
throw new KeyNotFoundException("User does not exist");
if (!_ProviderDatabaseService.IsExist(providerId))
throw new KeyNotFoundException("Provider does not exist");
List<Device> 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 };
}
}
/// <summary>
/// Update a device
/// </summary>
/// <param name="deviceDetailDTO">Device to update</param>
[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._LocationDatabaseService, deviceDetailDTO.UserId, deviceDetailDTO, false);
return new OkObjectResult(deviceUpdated);
}
catch (KeyNotFoundException ex)
{
return new BadRequestObjectResult(ex.Message) {};
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
/// <summary>
/// Delete a device
/// </summary>
/// <param name="deviceId">Id of device to delete</param>
[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 };
}
}
/// <summary>
/// Delete devices from provider
/// </summary>
/// <param name="userId">User Id</param>
/// <param name="providerId">Id of Provider</param>
[ProducesResponseType(typeof(string), 202)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpDelete("{userId}/fromProvider/{providerId}")]
public ObjectResult DeleteDevicesFromProvider(string userId, string providerId)
{
try
{
if (userId == null || providerId == null)
throw new ArgumentNullException("Invalid paramaters");
if (!_UserDatabaseService.IsExist(userId))
throw new KeyNotFoundException("User 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 };
}
}
/// <summary>
/// Delete all device for a specified user
/// </summary>
/// <param name="userId">Id of user</param>
[ProducesResponseType(typeof(string), 202)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpDelete("user/{userId}")]
public ObjectResult DeleteAllForUser(string userId)
{
try
{
if (userId == null)
throw new ArgumentNullException("Invalid paramaters");
if (!_UserDatabaseService.IsExist(userId))
throw new KeyNotFoundException("User does not exist");
// TODO REMOVE DEVICE ID IN AUTOMATION and delete automation if none device ?
_DeviceDatabaseService.RemoveForUser(userId);
return new ObjectResult("User 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 };
}
}
}
}