using MyCore.Interfaces.DTO; using MyCore.Interfaces.Models; using MyCore.Services.MyControlPanel; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace MyCore.Service.Services { public class GroupService { public static GroupDetailDTO CreateOrUpdate(GroupDatabaseService _GroupDatabaseService, DeviceDatabaseService _DeviceDatabaseService, string userId, GroupCreateOrUpdateDetailDTO groupCreateOrUpdateDetailDTO, bool create) { List devices = new List(); Group group; if (create) { group = new Group(); group.CreatedDate = DateTime.Now; group.DevicesIds = new List(); } else { group = _GroupDatabaseService.GetById(groupCreateOrUpdateDetailDTO.Id); } group.UserId = userId; group.Name = groupCreateOrUpdateDetailDTO.Name; group.Type = group.Type; // TODO group.UpdatedDate = DateTime.Now; group.DevicesIds.AddRange(groupCreateOrUpdateDetailDTO.DeviceIds); if (create) { group = _GroupDatabaseService.Create(group); } else { group = _GroupDatabaseService.Update(group); } foreach (var deviceId in groupCreateOrUpdateDetailDTO.DeviceIds) { Device device = _DeviceDatabaseService.GetById(deviceId); devices.Add(device); device.GroupIds.Add(group.Id); _DeviceDatabaseService.Update(device); } return group.ToDTO(devices.Select(d => d.ToDTO()).ToList()); } public static List CreateFromZigbeeAsync(GroupDatabaseService _GroupDatabaseService, DeviceDatabaseService _DeviceDatabaseService, string userId, List zigbee2MqttGroups) { List groups = new List(); foreach (var zigbee2MqttGroup in zigbee2MqttGroups.Where(z => z.members.Count > 0)) // Only take group with members { List devices = new List(); Group group; group = new Group(); group.CreatedDate = DateTime.Now; group.DevicesIds = new List(); group.ServiceIdentification = zigbee2MqttGroup.id; group.UserId = userId; group.Name = zigbee2MqttGroup.friendly_name; group.Type = "zigbee2mqtt"; group.UpdatedDate = DateTime.Now; foreach (var member in zigbee2MqttGroup.members) { Device device = _DeviceDatabaseService.GetByServiceIdentification(member.ieee_address); if (device != null) { group.DevicesIds.Add(device.Id); } } group = _GroupDatabaseService.Create(group); foreach (var deviceId in group.DevicesIds) { Device device = _DeviceDatabaseService.GetById(deviceId); devices.Add(device); if (device.GroupIds == null) device.GroupIds = new List(); device.GroupIds.Add(group.Id); _DeviceDatabaseService.Update(device); } groups.Add(group.ToDTO(devices.Select(d => d.ToDTO()).ToList())); } return groups; } // We only go in this method if the group config change during operation public static void CompareGroupsFromZigbee2Mqtt(string userId, List groups, List zigbee2MqttGroups, DeviceDatabaseService _DeviceDatabaseService, GroupDatabaseService _GroupDatabaseService) { // We do not refresh all list as we don't want to create plenty of new groupId and have to delete from device param everytime List existingGroups = new List(); foreach (var group in groups) { var devicesFromGroup = _DeviceDatabaseService.GetByGroup(group.Id); // convert existing group to zigbee2mqtt group existingGroups.Add(new Zigbee2MqttGroup { friendly_name = group.Name, id = group.ServiceIdentification, members = devicesFromGroup.Select(d => new Member() { ieee_address = d.ServiceIdentification }).ToList() }); ; } foreach (var zigbee2MqttGroup in zigbee2MqttGroups) { var existingGroupWithThisId = existingGroups.Where(eg => eg.id == zigbee2MqttGroup.id).ToList().FirstOrDefault(); if (existingGroupWithThisId == null) { // New group -> Create it ! CreateFromZigbeeAsync(_GroupDatabaseService, _DeviceDatabaseService, userId, zigbee2MqttGroups.Where(z => z.id == zigbee2MqttGroup.id).ToList()); } else { if (!Enumerable.SequenceEqual(zigbee2MqttGroup.members.Select(m => m.ieee_address).OrderBy(t => t), existingGroupWithThisId.members.Select(m => m.ieee_address).OrderBy(t => t))) { // different ? Update // As user not change everytime.. => Hard refresh. var groupToDelete = groups.Where(eg => eg.ServiceIdentification == existingGroupWithThisId.id).FirstOrDefault(); // Delete in device first var devicesInGroup = _DeviceDatabaseService.GetByGroup(groupToDelete.Id); foreach (var device in devicesInGroup) { device.GroupIds = device.GroupIds.Where(g => g != groupToDelete.Id).ToList(); _DeviceDatabaseService.Update(device); } // Delete group _GroupDatabaseService.Remove(groupToDelete.Id); // Create new group CreateFromZigbeeAsync(_GroupDatabaseService, _DeviceDatabaseService, userId, new List() { zigbee2MqttGroup }); } } // else do nothing } } } }