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 }; } } } }