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; using MyCore.Services; using MyCore.Services.Devices; using MyCore.Services.MyControlPanel; namespace MyCore.Service.Controllers { [Authorize] // TODO Add ROLES (Roles = "Admin") [Route("api/group")] [ApiController] public class GroupController : ControllerBase { private HomeDatabaseService _HomeDatabaseService; private GroupDatabaseService _GroupDatabaseService; private DeviceDatabaseService _DeviceDatabaseService; private ProviderDatabaseService _ProviderDatabaseService; private readonly IMqttClientService _mqttClientService; //private readonly IMqttOnlineClientService _mqttOnlineClientService; public GroupController(HomeDatabaseService homeDatabaseService, GroupDatabaseService groupDatabaseService, DeviceDatabaseService deviceDatabaseService, ProviderDatabaseService providerDatabaseService, MqttClientServiceProvider provider)//, MqttClientOnlineServiceProvider onlineProvider) { this._HomeDatabaseService = homeDatabaseService; this._GroupDatabaseService = groupDatabaseService; this._DeviceDatabaseService = deviceDatabaseService; this._ProviderDatabaseService = providerDatabaseService; this._mqttClientService = provider.MqttClientService; //this._mqttOnlineClientService = onlineProvider.MqttOnlineClientService; } /// /// Get all groups for the specified home /// /// Home Id [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 500)] [HttpGet("{homeId}")] public ObjectResult GetAll(string homeId) { try { if (homeId == null) throw new ArgumentNullException("Incorrect parameters"); List Groups = _GroupDatabaseService.GetAll(homeId); List groupsSummaryDTO = Groups.Select(d => d.ToSummaryDTO()).ToList(); return new OkObjectResult(groupsSummaryDTO); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Get detail info of a specified group /// /// groupid [ProducesResponseType(typeof(GroupDetailDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpGet("detail/{groupId}")] public ObjectResult GetDetail(string groupId) { try { if (groupId == null) throw new ArgumentNullException("Incorrect parameters"); Group group = _GroupDatabaseService.GetById(groupId); if (group == null) throw new KeyNotFoundException("Group not found"); List devices = _DeviceDatabaseService.GetByLocation(group.HomeId, groupId); return new OkObjectResult(group.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 }; } } /// /// Get list of group from a type /// /// home Id /// group type [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 500)] [HttpGet("{homeId}/type/{type}")] public ObjectResult GetGroupsByType(string homeId, string type) // Change string type to enum ? Lights etc ? { try { if (homeId == null || type == null) throw new ArgumentNullException("Incorrect parameters"); List groups = _GroupDatabaseService.GetByType(homeId, type); return new OkObjectResult(groups.Select(d => d.ToSummaryDTO())); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Get all zigbee2Mqtt groups /// /// Home Id [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpGet("zigbee2Mqtt/{homeId}")] public ObjectResult GetGroupsFromZigbee2Mqtt(string homeId) { try { if (homeId == null) throw new ArgumentNullException("Incorrect parameters"); if (!HomeService.IsExist(_HomeDatabaseService, homeId)) throw new KeyNotFoundException("Home not found"); // GET ALL LOCAL GROUPS var groups = MqttClientService.groups; // Be carefull, we only got the exact result after each connection return new OkObjectResult(groups); } 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 }; } } /// /// Create a group /// /// Group to create [ProducesResponseType(typeof(GroupDetailDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 500)] [HttpPost] public ObjectResult Create([FromBody] GroupCreateOrUpdateDetailDTO groupCreateOrUpdateDetail) { try { if (groupCreateOrUpdateDetail == null) throw new ArgumentNullException("Incorrect parameters"); GroupDetailDTO groupCreated = GroupService.CreateOrUpdate(this._GroupDatabaseService, this._DeviceDatabaseService, groupCreateOrUpdateDetail.HomeId, groupCreateOrUpdateDetail, true); return new OkObjectResult(groupCreated); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) {}; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Create groups from provider /// /// Home Id [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPost("{homeId}/fromZigbee")] public ObjectResult CreateDevicesFromZigbee2Mqtt(string homeId) { try { if (homeId == null) throw new ArgumentNullException("Incorrect parameters"); if (!HomeService.IsExist(_HomeDatabaseService, homeId)) throw new KeyNotFoundException("Home not found"); Provider provider = _ProviderDatabaseService.GetByType(ProviderType.zigbee2mqtt); if (provider == null) throw new KeyNotFoundException("Zigbee2mqtt provider not found"); // GET ALL LOCAL GROUPS var groups = MqttClientService.groups; // Be carefull, we only got the exact result after each connection List groupsDetail= GroupService.CreateFromZigbeeAsync(_GroupDatabaseService, _DeviceDatabaseService, homeId, groups); return new OkObjectResult(groupsDetail); } 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 group /// /// group to update [ProducesResponseType(typeof(GroupCreateOrUpdateDetailDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPut] public ObjectResult Update([FromBody] GroupCreateOrUpdateDetailDTO groupCreateOrUpdateDetail) { try { if (groupCreateOrUpdateDetail == null) throw new ArgumentNullException("Incorrect parameters"); if (!_GroupDatabaseService.IsExist(groupCreateOrUpdateDetail.Id)) throw new KeyNotFoundException("Group does not exist"); GroupDetailDTO groupUpdated = GroupService.CreateOrUpdate(this._GroupDatabaseService, this._DeviceDatabaseService, groupCreateOrUpdateDetail.HomeId, groupCreateOrUpdateDetail, false); return new OkObjectResult(groupUpdated); } 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 group /// /// Id of device to delete from the group /// Id of group [ProducesResponseType(typeof(string), 202)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpDelete("{groupId}/device/{deviceId}")] public ObjectResult Delete(string deviceId, string groupId) { try { if (groupId == null || deviceId == null) throw new ArgumentNullException("Incorrect parameters"); if (!_GroupDatabaseService.IsExist(groupId)) throw new KeyNotFoundException("Group does not exist"); // Update group Group group = _GroupDatabaseService.GetById(groupId); group.DevicesIds = group.DevicesIds.Where(d => d != deviceId).ToList(); group.UpdatedDate = DateTime.Now; _GroupDatabaseService.Update(group); // Update device Device device = _DeviceDatabaseService.GetById(deviceId); if (device == null) throw new KeyNotFoundException("Device does not exist"); device.GroupIds = device.GroupIds.Where(g => g != groupId).ToList(); device.UpdatedDate = DateTime.Now; _DeviceDatabaseService.Update(device); return new ObjectResult("Device has been successfully removed from specified group") { 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 group /// /// Id of group to delete [ProducesResponseType(typeof(string), 202)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpDelete("{groupId}")] public ObjectResult Delete(string groupId) { try { if (groupId == null) throw new ArgumentNullException("Incorrect parameters"); if (!_GroupDatabaseService.IsExist(groupId)) throw new KeyNotFoundException("Group does not exist"); Group group = _GroupDatabaseService.GetById(groupId); // Delete group from all devices List devices = _DeviceDatabaseService.GetByLocation(group.HomeId, groupId); foreach (var device in devices) { device.GroupIds = device.GroupIds.Where(g => g != groupId).ToList(); device.UpdatedDate = DateTime.Now; _DeviceDatabaseService.Update(device); } // Delete group _GroupDatabaseService.Remove(groupId); return new ObjectResult("The group 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 group 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"); _GroupDatabaseService.RemoveForHome(homeId); return new ObjectResult("All group linked with specified home 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 }; } } } }