using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TeamAAS_VP.Core.Lights; using TeamAAS_VP.Interfaces; using TeamAAS_VP.Models; using TeamAAS_VP.Models.Lights; namespace TeamAAS_VP.Services { /// /// 管理多个灯光控制器及其全局通道的服务。 /// 提供控制器注册/注销、全局通道的亮度与开关控制以及批量连接/断开功能。 /// public class LightManagerService : ILightManagerService { /// /// 本地按控制器ID索引的控制器集合。 /// 键:控制器ID,值:实现 的实例。 /// private readonly Dictionary _controllers; /// /// 全局通道映射。键为全局通道ID,值为具体的通道实例。 /// private readonly Dictionary _globalChannels; /// /// 不同灯具型号对应的工厂方法字典。 /// 键:灯具型号,值:创建控制器的工厂函数 (id, config) => ILightController /// private readonly Dictionary> _controllerFactories; /// /// 下一个可分配的全局通道ID(用于冲突时自动分配)。 /// private int _nextGlobalChannelId = 0; /// /// 只读访问已注册的控制器集合。 /// public IReadOnlyDictionary Controllers => _controllers; /// /// 只读访问全局通道映射。 /// public IReadOnlyDictionary GlobalChannels => _globalChannels; /// /// 当控制器被添加时触发的事件。 /// public event EventHandler ControllerAdded; /// /// 当控制器被移除时触发的事件。 /// public event EventHandler ControllerRemoved; /// /// 当某个全局通道状态(开/关/亮度)变化时触发的事件。 /// public event EventHandler ChannelStatusChanged; /// /// 构造函数,初始化内部字典并注册默认的控制器工厂。 /// public LightManagerService() { _controllers = new Dictionary(); _globalChannels = new Dictionary(); _controllerFactories = new Dictionary>(); RegisterDefaultFactories(); } /// /// 注册默认的控制器工厂(当前含 KCS 型号)。 /// private void RegisterDefaultFactories() { // 注册KCS控制器工厂 RegisterControllerFactory(LightModel.KCS_KDC_12V60W_4T, (id, config) => { if (config == null) throw new ArgumentNullException(nameof(config)); // 使用配置里的串口配置创建协议实现,再创建控制器实例 var protocol = new SerialPortProtocol(config.SerialPortConfig); return new KCSLightController(id, protocol, config.ChannelCount,config); }); // 注册KCS控制器工厂 RegisterControllerFactory(LightModel.KCS_KDC3_24V300W_8T, (id, config) => { if (config == null) throw new ArgumentNullException(nameof(config)); // 使用配置里的串口配置创建协议实现,再创建控制器实例 var protocol = new SerialPortProtocol(config.SerialPortConfig); return new KCSLightController(id, protocol, config.ChannelCount, config); }); } /// /// 手动注册一个控制器工厂,用于扩展支持更多型号。 /// /// 灯具模型 /// 工厂函数:根据 id 和配置返回 实例 public void RegisterControllerFactory(LightModel model, Func factory) { _controllerFactories[model] = factory; } /// /// 异步注册控制器并建立其通道到全局通道ID的映射。 /// /// 控制器ID(局部) /// 控制器配置 /// 已创建的控制器实例 /// 当配置为 null 时抛出 /// 当同ID已存在或未注册工厂时抛出 /// 当工厂返回 null 时抛出 public async Task RegisterControllerAsync(int id, TeamAAS_VP.Models.Lights.LightControllerConfig configuration) { if (configuration == null) throw new ArgumentNullException(nameof(configuration)); if (_controllers.ContainsKey(id)) throw new ArgumentException($"Controller with id '{id}' already exists"); if (!_controllerFactories.TryGetValue(configuration.LightModel, out var factory)) throw new ArgumentException($"No factory registered for model '{configuration.LightModel}'"); var controller = factory(id, configuration); if (controller == null) throw new InvalidOperationException("Factory returned null controller"); // 将控制器加入管理集合 _controllers[id] = controller; // 映射控制器内部通道到全局通道ID for (int i = 0; i < controller.Channels.Count; i++) { var channelConfig = configuration.ChannelConfigs[i]; int globalIndex = channelConfig.GlobalIndex; // 若指定的全局ID已被占用,则自动分配下一个可用ID if (_globalChannels.ContainsKey(globalIndex)) { // 自动重新分配全局ID globalIndex = _nextGlobalChannelId++; } else if (globalIndex >= _nextGlobalChannelId) { // 若指定ID大于等于当前_nextGlobalChannelId,则推进_nextGlobalChannelId以避免重复 _nextGlobalChannelId = globalIndex + 1; } // 如果配置中的GlobalIndex与最终分配不一致,则更新配置(保持配置与运行时一致) if (channelConfig.GlobalIndex != globalIndex) { channelConfig.GlobalIndex = globalIndex; } // 在全局映射表中建立映射:全局ID -> 控制器通道实例 _globalChannels[globalIndex] = controller.Channels[i]; } // 通知订阅方有新控制器添加 ControllerAdded?.Invoke(this, new LightControllerEventArgs(controller)); return controller; } /// /// 注销指定ID的控制器,断开并释放资源,同时移除其全局通道映射。 /// /// 要注销的控制器ID /// 如果存在并成功注销返回 true,否则 false public async Task UnregisterControllerAsync(int controllerId) { if (!_controllers.TryGetValue(controllerId, out var controller)) return false; // 找到属于该控制器的全局通道键并移除 var channelsToRemove = _globalChannels .Where(kvp => controller.Channels.Contains(kvp.Value)) .Select(kvp => kvp.Key) .ToList(); foreach (var channelId in channelsToRemove) { _globalChannels.Remove(channelId); } // 从管理集合中移除控制器并断开连接、释放资源 _controllers.Remove(controllerId); await controller.DisconnectAsync(); controller.Dispose(); // 通知订阅方控制器已移除 ControllerRemoved?.Invoke(this, new LightControllerEventArgs(controller)); return true; } /// /// 设置指定全局通道的亮度值。 /// /// 全局通道ID /// 亮度(由具体实现定义的范围) /// 操作是否成功 public async Task SetGlobalChannelBrightnessAsync(int globalChannelId, int brightness) { if (!_globalChannels.TryGetValue(globalChannelId, out var channel)) return false; var result = await channel.SetBrightnessAsync(brightness); // 触发状态变化事件,通知外部当前通道的开关与亮度状态 ChannelStatusChanged?.Invoke(this, new LightChannelEventArgs(channel, channel.IsOn, channel.Brightness)); return result; } /// /// 获取指定全局通道的亮度值。 /// /// 全局通道ID /// 操作是否成功 public async Task GetGlobalChannelBrightnessAsync(int globalChannelId) { if (!_globalChannels.TryGetValue(globalChannelId, out var channel)) return -1; var result = await channel.GetBrightnessAsync(); // 触发状态变化事件,通知外部当前通道的开关与亮度状态 ChannelStatusChanged?.Invoke(this, new LightChannelEventArgs(channel, channel.IsOn, channel.Brightness)); return result; } /// /// 打开指定的全局通道。 /// /// 全局通道ID /// 操作是否成功 public async Task TurnOnGlobalChannelAsync(int globalChannelId) { if (!_globalChannels.TryGetValue(globalChannelId, out var channel)) return false; var result = await channel.TurnOnAsync(); ChannelStatusChanged?.Invoke(this, new LightChannelEventArgs(channel, channel.IsOn, channel.Brightness)); return result; } /// /// 关闭指定的全局通道。 /// /// 全局通道ID /// 操作是否成功 public async Task TurnOffGlobalChannelAsync(int globalChannelId) { if (!_globalChannels.TryGetValue(globalChannelId, out var channel)) return false; var result = await channel.TurnOffAsync(); ChannelStatusChanged?.Invoke(this, new LightChannelEventArgs(channel, channel.IsOn, channel.Brightness)); return result; } /// /// 异步连接所有已注册的控制器。 /// /// 当所有控制器连接成功返回 true;任一失败返回 false。 public async Task ConnectAllAsync() { var tasks = _controllers.Values.Select(c => c.ConnectAsync()); var results = await Task.WhenAll(tasks); return results.All(r => r); } /// /// 异步断开所有已注册的控制器(不会销毁控制器实例)。 /// /// 操作完成后返回 true。 public async Task DisconnectAllAsync() { foreach (var controller in _controllers.Values) { await controller.DisconnectAsync(); } return true; } /// /// 将当前配置保存到指定文件(未实现)。 /// /// 目标文件路径 /// 完成任务 public Task SaveConfigurationAsync(string filePath) { // TODO: 实现配置保存逻辑(序列化控制器与通道映射) return Task.CompletedTask; } /// /// 从指定文件加载配置(未实现)。 /// /// 配置文件路径 /// 完成任务 public Task LoadConfigurationAsync(string filePath) { // TODO: 实现配置加载逻辑(反序列化并调用 RegisterControllerAsync) return Task.CompletedTask; } } }