diff --git a/MyCore.Interfaces/DTO/MyControlPanel/RoomDTO.cs b/MyCore.Interfaces/DTO/MyControlPanel/RoomDTO.cs index f6e7a37..d7986f3 100644 --- a/MyCore.Interfaces/DTO/MyControlPanel/RoomDTO.cs +++ b/MyCore.Interfaces/DTO/MyControlPanel/RoomDTO.cs @@ -23,8 +23,31 @@ namespace MyCore.Interfaces.DTO public List Devices { get; set; } } + public class RoomMainDetailDTO : RoomSummaryDTO + { + public DateTime CreatedDate { get; set; } + + public DateTime UpdatedDate { get; set; } + + public bool IsTemperature { get; set; } + public string Temperature { get; set; } + + public bool IsHumidity { get; set; } + public string Humidity { get; set; } + + public bool IsMotion { get; set; } + public bool? Motion { get; set; } + + public bool IsDoor { get; set; } + public bool? Door { get; set; } + + public List EnvironmentalDevices { get; set; } // for temp and humidity + + public List SecurityDevices { get; set; } // for motion + } + public class RoomCreateOrUpdateDetailDTO : RoomSummaryDTO { - public List DeviceIds { get; set; } + public List DeviceIds { get; set; } // TODO handle groupdIds } } diff --git a/MyCore.Interfaces/DTO/UserInfoDetailDTO.cs b/MyCore.Interfaces/DTO/UserInfoDetailDTO.cs index 3d8272d..317e9c2 100644 --- a/MyCore.Interfaces/DTO/UserInfoDetailDTO.cs +++ b/MyCore.Interfaces/DTO/UserInfoDetailDTO.cs @@ -10,6 +10,8 @@ namespace MyCore.Interfaces.DTO public string Email { get; set; } public string FirstName { get; set; } public string LastName { get; set; } + public string Language { get; set; } + public List HomeIds { get; set; } // TODO diff --git a/MyCore.Interfaces/Models/MyControlPanel/Database/Room.cs b/MyCore.Interfaces/Models/MyControlPanel/Database/Room.cs index d546af3..b6a7f97 100644 --- a/MyCore.Interfaces/Models/MyControlPanel/Database/Room.cs +++ b/MyCore.Interfaces/Models/MyControlPanel/Database/Room.cs @@ -56,5 +56,30 @@ namespace MyCore.Interfaces.Models Devices = devicesDetail }; } + + public RoomCreateOrUpdateDetailDTO ToCreateOrUpdateDetailDTO() + { + return new RoomCreateOrUpdateDetailDTO() + { + Id = Id, + HomeId = HomeId, + Name = Name, + DeviceIds = DevicesIds, + }; + } + + public RoomMainDetailDTO ToMainDetailsDTO(List devicesDetail) + { + return new RoomMainDetailDTO() + { + Id = Id, + HomeId = HomeId, + Name = Name, + CreatedDate = CreatedDate, + UpdatedDate = UpdatedDate, + EnvironmentalDevices = devicesDetail.Where(d => d.Type == DeviceType.Environment).ToList(), + SecurityDevices = devicesDetail.Where(d => d.Type == DeviceType.Motion || d.Type == DeviceType.Door).ToList(), + }; + } } } diff --git a/MyCore.Interfaces/Models/MyControlPanel/Database/UserInfo.cs b/MyCore.Interfaces/Models/MyControlPanel/Database/UserInfo.cs index 575f38d..d586df0 100644 --- a/MyCore.Interfaces/Models/MyControlPanel/Database/UserInfo.cs +++ b/MyCore.Interfaces/Models/MyControlPanel/Database/UserInfo.cs @@ -80,6 +80,8 @@ namespace MyCore.Interfaces.Models Email = Email, FirstName = FirstName, LastName = LastName, + Language = Language, + HomeIds = HomeIds, }; } diff --git a/MyCore/Controllers/GroupController.cs b/MyCore/Controllers/GroupController.cs index 8966c90..a87134b 100644 --- a/MyCore/Controllers/GroupController.cs +++ b/MyCore/Controllers/GroupController.cs @@ -91,7 +91,7 @@ namespace MyCore.Service.Controllers if (group == null) throw new KeyNotFoundException("Group not found"); - List devices = _DeviceDatabaseService.GetByRoom(group.HomeId, groupId); + List devices = _DeviceDatabaseService.GetByGroup(groupId); return new OkObjectResult(group.ToDTO(devices.Select(d => d.ToDTO()).ToList())); @@ -360,7 +360,7 @@ namespace MyCore.Service.Controllers Group group = _GroupDatabaseService.GetById(groupId); // Delete group from all devices - List devices = _DeviceDatabaseService.GetByRoom(group.HomeId, groupId); + List devices = _DeviceDatabaseService.GetByGroup(groupId); foreach (var device in devices) { device.GroupIds = device.GroupIds.Where(g => g != groupId).ToList(); diff --git a/MyCore/Controllers/MyControlPanel/UserController.cs b/MyCore/Controllers/MyControlPanel/UserController.cs index 49a8f1a..2578c3b 100644 --- a/MyCore/Controllers/MyControlPanel/UserController.cs +++ b/MyCore/Controllers/MyControlPanel/UserController.cs @@ -48,7 +48,6 @@ namespace MyCore.Controllers return new ObjectResult(ex.Message) { StatusCode = 500 }; } } - /// /// Get a specific user @@ -79,6 +78,35 @@ namespace MyCore.Controllers } } + /// + /// Get a specific user by email + /// + /// user email + [ProducesResponseType(typeof(UserInfoDetailDTO), 200)] + [ProducesResponseType(typeof(string), 404)] + [ProducesResponseType(typeof(string), 500)] + [HttpGet("email/{email}")] + public ObjectResult GetByEmail(string email) + { + try + { + UserInfo user = _userService.GetByEmail(email); + + if (user == null) + throw new KeyNotFoundException("This user was not found"); + + return new OkObjectResult(user.ToDTO()); + } + catch (KeyNotFoundException ex) + { + return new NotFoundObjectResult(ex.Message) { }; + } + catch (Exception ex) + { + return new ObjectResult(ex.Message) { StatusCode = 500 }; + } + } + /// /// Create an user /// diff --git a/MyCore/Controllers/RoomController.cs b/MyCore/Controllers/RoomController.cs index 74404bb..5af141e 100644 --- a/MyCore/Controllers/RoomController.cs +++ b/MyCore/Controllers/RoomController.cs @@ -25,14 +25,16 @@ namespace MyCore.Service.Controllers private HomeDatabaseService _HomeDatabaseService; private RoomDatabaseService _RoomDatabaseService; private DeviceDatabaseService _DeviceDatabaseService; + private RoomService _RoomService; private readonly IMqttClientService _mqttClientService; //private readonly IMqttOnlineClientService _mqttOnlineClientService; - public RoomController(HomeDatabaseService homeDatabaseService, RoomDatabaseService roomDatabaseService, DeviceDatabaseService deviceDatabaseService, MqttClientServiceProvider provider)//, MqttClientOnlineServiceProvider onlineProvider) + public RoomController(HomeDatabaseService homeDatabaseService, RoomDatabaseService roomDatabaseService, DeviceDatabaseService deviceDatabaseService, RoomService roomService, MqttClientServiceProvider provider)//, MqttClientOnlineServiceProvider onlineProvider) { this._HomeDatabaseService = homeDatabaseService; this._RoomDatabaseService = roomDatabaseService; this._DeviceDatabaseService = deviceDatabaseService; + this._RoomService = roomService; this._mqttClientService = provider.MqttClientService; //this._mqttOnlineClientService = onlineProvider.MqttOnlineClientService; } @@ -60,6 +62,41 @@ namespace MyCore.Service.Controllers } } + /// + /// 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(); + foreach (var room in rooms) + { + RoomMainDetailDTO roomMainDetailDTO = room.ToMainDetailsDTO(_DeviceDatabaseService.GetByRoom(room.Id).Select(d => d.ToDTO()).ToList()); + roomMainDetailDTO.Temperature = (string) RoomService.GetValueFromJson(roomMainDetailDTO.EnvironmentalDevices, DeviceType.Environment, "temperature", false); // Todo take the one selected by user as default if more than one + roomMainDetailDTO.IsTemperature = roomMainDetailDTO.Temperature != null; + roomMainDetailDTO.Humidity = (string) RoomService.GetValueFromJson(roomMainDetailDTO.EnvironmentalDevices, DeviceType.Environment, "humidity", false); // Todo take the one selected by user as default if more than one + roomMainDetailDTO.IsHumidity = roomMainDetailDTO.Humidity != null; + roomMainDetailDTO.Motion = (bool?) RoomService.GetValueFromJson(roomMainDetailDTO.SecurityDevices, DeviceType.Motion, "motion", true); + roomMainDetailDTO.IsMotion = roomMainDetailDTO.SecurityDevices.Any(sd => sd.Type == DeviceType.Motion) ? roomMainDetailDTO.Motion != null : false; + roomMainDetailDTO.Door = (bool?) RoomService.GetValueFromJson(roomMainDetailDTO.SecurityDevices, DeviceType.Door, "contact", true); // Todo handle more than just by string + 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 /// @@ -79,10 +116,9 @@ namespace MyCore.Service.Controllers Room room = _RoomDatabaseService.GetById(roomId); if (room == null) throw new KeyNotFoundException("Room does not exist"); - List devices = _DeviceDatabaseService.GetByRoom(room.HomeId, roomId); + List devices = _DeviceDatabaseService.GetByRoom(roomId); return new OkObjectResult(room.ToDTO(devices.Select(d => d.ToDTO()).ToList())); - } catch (ArgumentNullException ex) { @@ -106,7 +142,7 @@ namespace MyCore.Service.Controllers [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 500)] [HttpPost] - public ObjectResult Create([FromBody] RoomCreateOrUpdateDetailDTO roomCreateOrUpdateDetail) + public ObjectResult Create([FromBody] RoomCreateOrUpdateDetailDTO roomCreateOrUpdateDetail) // TODO handle groupdIds { try { @@ -156,6 +192,58 @@ namespace MyCore.Service.Controllers } } + /// + /// 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 /// @@ -230,7 +318,7 @@ namespace MyCore.Service.Controllers Room room = _RoomDatabaseService.GetById(roomId); // Delete location from all devices - List devices = _DeviceDatabaseService.GetByRoom(room.HomeId, roomId); + List devices = _DeviceDatabaseService.GetByRoom(roomId); foreach (var device in devices) { device.RoomId = null; diff --git a/MyCore/MyCore.csproj b/MyCore/MyCore.csproj index 24be06f..90b0aee 100644 --- a/MyCore/MyCore.csproj +++ b/MyCore/MyCore.csproj @@ -20,7 +20,6 @@ - diff --git a/MyCore/Services/Devices/ActionService.cs b/MyCore/Services/Devices/ActionService.cs index 255d90e..810547b 100644 --- a/MyCore/Services/Devices/ActionService.cs +++ b/MyCore/Services/Devices/ActionService.cs @@ -46,7 +46,6 @@ namespace MyCore.Services.Devices if (currentProvider != null) { - deviceTrigger = _DeviceDatabaseService.GetByName(deviceServiceName).FirstOrDefault(); if (deviceTrigger != null) diff --git a/MyCore/Services/Devices/DeviceService.cs b/MyCore/Services/Devices/DeviceService.cs index a7fc790..6bbe0d5 100644 --- a/MyCore/Services/Devices/DeviceService.cs +++ b/MyCore/Services/Devices/DeviceService.cs @@ -94,12 +94,17 @@ namespace MyCore.Services.Devices device.ConnectionStatus = ConnectionStatus.Unknown; else device.ConnectionStatus = deviceDetailDTO.ConnectionStatus; - device.Status = deviceDetailDTO.Status; device.RoomId = deviceDetailDTO.RoomId; - device.CreatedDate = DateTime.Now; - device.UpdatedDate = DateTime.Now; - device.LastState = deviceDetailDTO.LastState; - device.LastStateDate = deviceDetailDTO.LastStateDate; + if (create) + { + device.CreatedDate = DateTime.Now; + } + else { + device.UpdatedDate = DateTime.Now; + device.LastState = deviceDetailDTO.LastState; + device.LastStateDate = deviceDetailDTO.LastStateDate; + device.Status = deviceDetailDTO.Status; + } device.MeansOfCommunications = deviceDetailDTO.MeansOfCommunications; device.IpAddress = deviceDetailDTO.IpAddress; diff --git a/MyCore/Services/MyControlPanel/Database/DeviceDatabaseService.cs b/MyCore/Services/MyControlPanel/Database/DeviceDatabaseService.cs index aac4292..2ac226d 100644 --- a/MyCore/Services/MyControlPanel/Database/DeviceDatabaseService.cs +++ b/MyCore/Services/MyControlPanel/Database/DeviceDatabaseService.cs @@ -44,9 +44,9 @@ namespace MyCore.Services return _Devices.Find(h => h.HomeId == homeId).ToList(); } - public List GetByRoom(string homeId, string roomId) + public List GetByRoom(string roomId) { - return _Devices.Find(d => d.HomeId == homeId && d.RoomId == roomId).ToList(); + return _Devices.Find(d => d.RoomId == roomId).ToList(); } public List GetByType(string homeId, DeviceType type) diff --git a/MyCore/Services/RoomService.cs b/MyCore/Services/RoomService.cs index 134c6b2..93b3441 100644 --- a/MyCore/Services/RoomService.cs +++ b/MyCore/Services/RoomService.cs @@ -2,6 +2,8 @@ using MyCore.Interfaces.Models; using MyCore.Services; using MyCore.Services.MyControlPanel; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; @@ -29,7 +31,7 @@ namespace MyCore.Service room.Name = roomCreateOrUpdateDetailDTO.Name; room.UpdatedDate = DateTime.Now; - List currentDevices = _DeviceDatabaseService.GetByIds(roomCreateOrUpdateDetailDTO.DeviceIds); // A device cannot have multiple rooms. Filter list + List currentDevices = _DeviceDatabaseService.GetByIds(roomCreateOrUpdateDetailDTO.DeviceIds.Distinct().ToList()); // A device cannot have multiple rooms. Filter list currentDevices = currentDevices.Where(c => c.RoomId == null).ToList(); // TODO add exception or something if (create) @@ -53,5 +55,32 @@ namespace MyCore.Service return room.ToDTO(devices.Select(d => d.ToDTO()).ToList()); } + + public static dynamic GetValueFromJson(List devicesDetail, DeviceType deviceType, string field, bool ifAny) + { + var isAny = false; + foreach (var device in devicesDetail) + { + if (device.LastState != null) + { + var lastState = JsonConvert.DeserializeObject(device.LastState); + if (lastState[field] != null && deviceType == device.Type) + { + if (ifAny) + { + isAny = (bool) lastState[field] ? true : isAny; + } + else + { + return lastState[field]; + } + } + } + } + if (ifAny) + return isAny; + else + return null; + } } } diff --git a/MyCore/Startup.cs b/MyCore/Startup.cs index c0c0335..db56ac7 100644 --- a/MyCore/Startup.cs +++ b/MyCore/Startup.cs @@ -144,7 +144,7 @@ namespace MyCore //services.AddMqttClientOnlineHostedService(); // Comment this line when dev - //services.AddMerossClientHostedService(); // Todo client files (a lot are useless) + services.AddMerossClientHostedService(); // Todo client files (a lot are useless) services.AddScoped(); // To clarify if needed.. ? @@ -161,6 +161,7 @@ namespace MyCore services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped();