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.Service.Services.Devices.SupportedDevices;
using MyCore.Services;
using MyCore.Services.Devices;
using MyCore.Services.MyControlPanel;
namespace MyCore.Service.Controllers
{
[Authorize] // TODO Add ROLES (Roles = "Admin")
[Route("api/room")]
[ApiController]
public class RoomController : ControllerBase
{
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, 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;
}
///
/// Get all rooms for the specified home
///
/// Home Id
[ProducesResponseType(typeof(List), 200)]
[ProducesResponseType(typeof(string), 500)]
[HttpGet("{homeId}")]
public ObjectResult GetAll(string homeId)
{
try
{
List Rooms = _RoomDatabaseService.GetAll(homeId);
List roomsSummaryDTO = Rooms.Select(d => d.ToSummaryDTO()).ToList();
return new OkObjectResult(roomsSummaryDTO);
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Get all rooms main details for the specified home
///
/// Home Id
[ProducesResponseType(typeof(List), 200)]
[ProducesResponseType(typeof(string), 500)]
[HttpGet("{homeId}/details")]
public ObjectResult GetAllWithMainDetails(string homeId)
{
try
{
List rooms = _RoomDatabaseService.GetAll(homeId);
List roomMainDetailDTOs = new List();
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 netatmoHomes = netatmoService.GetHomeData();
List 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());
roomMainDetailDTO.Temperature = (string) RoomService.GetValueFromDeviceType(roomMainDetailDTO.EnvironmentalDevices, RoomMainInfo.Temperature); // Todo take the one selected by user as default if more than one
roomMainDetailDTO.IsTemperature = roomMainDetailDTO.Temperature != null;
roomMainDetailDTO.Humidity = (string) RoomService.GetValueFromDeviceType(roomMainDetailDTO.EnvironmentalDevices, RoomMainInfo.Humidity); // Todo take the one selected by user as default if more than one
roomMainDetailDTO.IsHumidity = roomMainDetailDTO.Humidity != null;
roomMainDetailDTO.Pressure = (string)RoomService.GetValueFromDeviceType(roomMainDetailDTO.EnvironmentalDevices, RoomMainInfo.Pressure); // Todo take the one selected by user as default if more than one
roomMainDetailDTO.IsPressure = roomMainDetailDTO.Pressure != null;
roomMainDetailDTO.Illuminance = (string)RoomService.GetValueFromDeviceType(roomMainDetailDTO.EnvironmentalDevices, RoomMainInfo.Illuminance); // Todo take the one selected by user as default if more than one
roomMainDetailDTO.IsIlluminance = roomMainDetailDTO.Illuminance != null;
roomMainDetailDTO.Motion = (bool?) RoomService.GetValueFromDeviceType(roomMainDetailDTO.SecurityDevices, RoomMainInfo.Motion);
roomMainDetailDTO.IsMotion = roomMainDetailDTO.SecurityDevices.Any(sd => sd.Type == DeviceType.Motion) ? roomMainDetailDTO.Motion != null : false;
roomMainDetailDTO.Door = (bool?) RoomService.GetValueFromDeviceType(roomMainDetailDTO.SecurityDevices, RoomMainInfo.Door);
roomMainDetailDTO.IsDoor = roomMainDetailDTO.SecurityDevices.Any(sd => sd.Type == DeviceType.Door) ? roomMainDetailDTO.Door != null : false;
roomMainDetailDTOs.Add(roomMainDetailDTO);
}
return new OkObjectResult(roomMainDetailDTOs);
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Get detail info of a specified room
///
/// room id
[ProducesResponseType(typeof(RoomDetailDTO), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpGet("detail/{roomId}")]
public ObjectResult GetDetail(string roomId)
{
try
{
if (roomId == null)
throw new ArgumentNullException("Incorrect parameters");
Room room = _RoomDatabaseService.GetById(roomId);
if (room == null)
throw new KeyNotFoundException("Room does not exist");
List devices = _DeviceDatabaseService.GetByRoom(roomId);
return new OkObjectResult(room.ToDTO(devices.Select(d => d.ToDTO()).ToList()));
}
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 };
}
}
///
/// Create a room
///
/// Room to create
[ProducesResponseType(typeof(RoomDetailDTO), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 500)]
[HttpPost]
public ObjectResult Create([FromBody] RoomCreateOrUpdateDetailDTO roomCreateOrUpdateDetail) // TODO handle groupdIds
{
try
{
if (roomCreateOrUpdateDetail == null)
throw new ArgumentNullException("Incorrect parameters");
RoomDetailDTO roomCreated = RoomService.CreateOrUpdate(this._RoomDatabaseService, this._DeviceDatabaseService, roomCreateOrUpdateDetail.HomeId, roomCreateOrUpdateDetail, true);
return new OkObjectResult(roomCreated);
}
catch (ArgumentNullException ex)
{
return new BadRequestObjectResult(ex.Message) { };
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Update a room
///
/// room to update
[ProducesResponseType(typeof(RoomCreateOrUpdateDetailDTO), 200)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpPut]
public ObjectResult Update([FromBody] RoomCreateOrUpdateDetailDTO roomCreateOrUpdateDetail)
{
try
{
if (!_RoomDatabaseService.IsExist(roomCreateOrUpdateDetail.Id))
throw new KeyNotFoundException("Room does not exist");
RoomDetailDTO roomUpdated = RoomService.CreateOrUpdate(this._RoomDatabaseService, this._DeviceDatabaseService, roomCreateOrUpdateDetail.HomeId, roomCreateOrUpdateDetail, false);
return new OkObjectResult(roomUpdated);
}
catch (KeyNotFoundException ex)
{
return new NotFoundObjectResult(ex.Message) {};
}
catch (Exception ex)
{
return new ObjectResult(ex.Message) { StatusCode = 500 };
}
}
///
/// Add devices in the specified room
///
/// Room Id
/// Device Ids
[ProducesResponseType(typeof(RoomDetailDTO), 200)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpPut("{roomId}")]
public ObjectResult AddDeviceToRoom(string roomId, [FromBody] List deviceIds) // TODO handle groupdIds
{
try
{
if (roomId == null || deviceIds.Count == 0)
{
throw new ArgumentNullException("Incorrect parameters");
}
if (!_RoomDatabaseService.IsExist(roomId))
throw new KeyNotFoundException("Room does not exist");
Room room = _RoomDatabaseService.GetById(roomId);
List deviceIdsToTake = new List();
foreach (var deviceId in deviceIds) {
if (!_DeviceDatabaseService.IsExist(deviceId))
break;
deviceIdsToTake.Add(deviceId);
}
RoomCreateOrUpdateDetailDTO roomCreateOrUpdateDetailDTO = room.ToCreateOrUpdateDetailDTO();
roomCreateOrUpdateDetailDTO.DeviceIds.AddRange(deviceIdsToTake);
RoomDetailDTO roomUpdated = RoomService.CreateOrUpdate(this._RoomDatabaseService, this._DeviceDatabaseService, room.HomeId, roomCreateOrUpdateDetailDTO, false);
return new OkObjectResult(roomUpdated);
}
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 device from a room
///
/// Id of device to delete from the room
/// Id of room
[ProducesResponseType(typeof(string), 202)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpDelete("{roomId}/device/{deviceId}")]
public ObjectResult Delete(string deviceId, string roomId)
{
try
{
if (roomId == null && deviceId == null)
throw new ArgumentNullException("Incorrect parameters");
if (!_RoomDatabaseService.IsExist(roomId))
throw new KeyNotFoundException("Room does not exist");
// Update room
Room room = _RoomDatabaseService.GetById(roomId);
room.DevicesIds = room.DevicesIds.Where(d => d != deviceId).ToList();
room.UpdatedDate = DateTime.Now;
_RoomDatabaseService.Update(room);
// Update device
Device device = _DeviceDatabaseService.GetById(deviceId);
if (device == null)
throw new KeyNotFoundException("Device does not exist");
device.RoomId = null;
device.UpdatedDate = DateTime.Now;
_DeviceDatabaseService.Update(device);
return new OkObjectResult("Device has been removed from specified room") { 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 a room
///
/// Id of room to delete
[ProducesResponseType(typeof(string), 202)]
[ProducesResponseType(typeof(string), 400)]
[ProducesResponseType(typeof(string), 404)]
[ProducesResponseType(typeof(string), 500)]
[HttpDelete("{roomId}")]
public ObjectResult Delete(string roomId)
{
try
{
if (roomId == null)
throw new ArgumentNullException("Incorrect parameters");
if (!_RoomDatabaseService.IsExist(roomId))
throw new KeyNotFoundException("Room does not exist");
Room room = _RoomDatabaseService.GetById(roomId);
// Delete location from all devices
List devices = _DeviceDatabaseService.GetByRoom(roomId);
foreach (var device in devices)
{
device.RoomId = null;
device.UpdatedDate = DateTime.Now;
_DeviceDatabaseService.Update(device);
}
// Delete room
_RoomDatabaseService.Remove(roomId);
return new OkObjectResult("Room 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 rooms for a specified home
///
/// Home Id
[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("Incorrect parameters");
if (!_HomeDatabaseService.IsExist(homeId))
throw new KeyNotFoundException("Home does not exist");
_RoomDatabaseService.RemoveForHome(homeId);
return new OkObjectResult("All rooms associated to specified home has been removed") { 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 };
}
}
}
}