using Evergreen.Health.Application.Health.Devices.Contracts; using Evergreen.Health.Application.Health.Integrations.HomeAssistant; using Evergreen.Health.Application.Health.Models; using Evergreen.Health.Application.Health.Scenes; using Microsoft.Extensions.Options; namespace Evergreen.Health.Application.Health.Devices.Fragrance; public sealed class FragranceModule : HealthDeviceModule { private readonly HomeAssistantEntityOptions _entities; private readonly bool _wakeDevice; public FragranceModule(DeviceActionRunner runner, IOptions options) : this(runner, options, wakeDevice: false) { } internal FragranceModule(DeviceActionRunner runner, IOptions options, bool wakeDevice) : base(runner) { _entities = options.Value.Entities; _wakeDevice = wakeDevice; var duration = wakeDevice ? _entities.WakeFragranceDuration : _entities.FragranceDuration; var intervalEntity = wakeDevice ? _entities.WakeFragranceInterval : _entities.FragranceInterval; var light = wakeDevice ? _entities.WakeFragranceLight : _entities.FragranceLight; var quickRelease = wakeDevice ? _entities.WakeFragranceQuickRelease : _entities.FragranceQuickRelease; var autoRelease = wakeDevice ? _entities.WakeFragranceAutoRelease : _entities.FragranceAutoRelease; var autoLight = wakeDevice ? _entities.WakeFragranceAutoLight : _entities.FragranceAutoLight; var lightAutoOff = wakeDevice ? _entities.WakeFragranceLightAutoOff : _entities.FragranceLightAutoOff; DeviceParameterDefinition[] parameters = [ DeviceValues.Number("fragrance_duration", duration, 2, 6, "出香时长"), new("fragrance_interval", intervalEntity, value => { var interval = DeviceValues.Integer(value, 10, 20, "出香间隔"); if (interval % 5 != 0) throw new InvalidOperationException("出香间隔仅支持 10、15 或 20 分钟"); return new("设置出香间隔", intervalEntity, "number", "set_value", new Dictionary { ["value"] = interval }); }, "出香间隔", 10, 20), DeviceValues.Switch("fragrance_light", light, "light", "香氛灯"), new("fragrance_quick_release", quickRelease, _ => BuildQuickRelease(quickRelease), "快速出香"), DeviceValues.Switch("fragrance_auto_release", autoRelease, "switch", "人来增香"), DeviceValues.Switch("fragrance_auto_light", autoLight, "switch", "感应夜灯"), DeviceValues.Switch("fragrance_light_auto_off", lightAutoOff, "switch", "夜灯自动关闭") ]; Parameters = wakeDevice ? parameters.Select(parameter => parameter with { Key = $"wake_{parameter.Key}" }).ToArray() : parameters; } public override string Key => _wakeDevice ? "wake-fragrance" : "fragrance"; public override string Category => nameof(HealthDeviceCategory.Fragrance); public override string DisplayName => _wakeDevice ? "香氛机 唤醒" : "智能香氛机"; public override string PrimaryEntityId => _wakeDevice ? _entities.WakeFragranceSwitch : _entities.FragranceSwitch; public override IReadOnlyList Parameters { get; } internal static DeviceCommand BuildQuickRelease(string entityId) => new("快速出香", entityId, "button", "press"); public override async Task ExecuteSleepAsync(DeviceSceneContext context, PersonalizedSceneConfig config, string constitutionCode, CancellationToken cancellationToken) { if (_wakeDevice) return; await context.RunAsync(new(config.EnableFragrance ? "开启香氛机" : "关闭香氛机", PrimaryEntityId, "switch", config.EnableFragrance ? "turn_on" : "turn_off"), cancellationToken); if (config.EnableFragrance) { var level = Math.Clamp(config.FragranceLevel, 1, 3); await context.RunAsync(BuildParameterCommand("fragrance_duration", level * 2), cancellationToken); await context.RunAsync(BuildParameterCommand("fragrance_interval", 25 - level * 5), cancellationToken); } await context.RunAsync(new(config.EnableFragrance ? "开启香氛灯" : "关闭香氛灯", _entities.FragranceLight, "light", config.EnableFragrance ? "turn_on" : "turn_off", config.EnableFragrance ? new Dictionary { ["brightness_pct"] = config.LightBrightnessPercent } : null), cancellationToken); } public override IEnumerable GetShutdownCommands() => _wakeDevice ? [] : [ new("关闭香氛机", PrimaryEntityId, "switch", "turn_off", ExpectedState: "off"), new("关闭香氛灯", _entities.FragranceLight, "light", "turn_off", ExpectedState: "off"), new("关闭感应夜灯", _entities.FragranceAutoLight, "switch", "turn_off", ExpectedState: "off"), new("关闭人来增香", _entities.FragranceAutoRelease, "switch", "turn_off", ExpectedState: "off") ]; public override HomeAssistantScenePresetItem? BuildPreview(PersonalizedSceneConfig config, string constitutionCode) => _wakeDevice || string.IsNullOrWhiteSpace(PrimaryEntityId) ? null : Preview(config.EnableFragrance ? "开启香氛释放" : "关闭香氛释放", config.EnableFragrance ? "开启香氛机;香氛灯可用时同步开启柔光" : "当前体质预设不启动香氛", new() { ["power"] = config.EnableFragrance ? "开启" : "关闭" }); }