81 lines
4.7 KiB
C#
81 lines
4.7 KiB
C#
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.Lighting;
|
|
|
|
public sealed class LightingModule : HealthDeviceModule
|
|
{
|
|
private readonly HomeAssistantEntityOptions _entities;
|
|
private readonly ILightTransitionRuntime _transition;
|
|
private readonly LightOffDispatcher _lightOff;
|
|
public LightingModule(DeviceActionRunner runner, IOptions<HomeAssistantOptions> options,
|
|
ILightTransitionRuntime transition, LightOffDispatcher lightOff) : base(runner)
|
|
{
|
|
_entities = options.Value.Entities; _transition = transition; _lightOff = lightOff;
|
|
Parameters =
|
|
[
|
|
new("brightness", PrimaryEntityId, value =>
|
|
{
|
|
var brightness = DeviceValues.Integer(value, 0, 100, "灯光亮度");
|
|
return new("设置灯光亮度", PrimaryEntityId, "light", brightness == 0 ? "turn_off" : "turn_on",
|
|
brightness == 0 ? null : new Dictionary<string, object?> { ["brightness_pct"] = brightness })
|
|
{ Intent = brightness == 0 ? DeviceCommandIntent.TurnRelaxationLightOff : DeviceCommandIntent.TurnRelaxationLightOn };
|
|
}, "灯光亮度", 0, 100),
|
|
new("color_temp", PrimaryEntityId, value => new("设置灯光色温", PrimaryEntityId, "light", "turn_on",
|
|
new Dictionary<string, object?> { ["color_temp_kelvin"] = DeviceValues.Integer(value, 2200, 5000, "灯光色温") })
|
|
{ Intent = DeviceCommandIntent.TurnRelaxationLightOn },
|
|
"灯光色温", 2200, 5000)
|
|
];
|
|
}
|
|
public override string Key => "lighting";
|
|
public override string Category => nameof(HealthDeviceCategory.Lighting);
|
|
public override string DisplayName => "卧室灯光";
|
|
public override string PrimaryEntityId => _entities.AmbientLight;
|
|
public override IReadOnlyList<DeviceParameterDefinition> Parameters { get; }
|
|
|
|
public override async Task ExecuteParameterAsync(DeviceCommand command, CancellationToken cancellationToken)
|
|
{
|
|
// 标准手动面板复用本灯的专属安全钩子;其他灯不会触发助眠灯/床垫联动。
|
|
command = command with { Intent = command.Service == "turn_off"
|
|
? DeviceCommandIntent.TurnRelaxationLightOff : DeviceCommandIntent.TurnRelaxationLightOn };
|
|
await _transition.CancelAsync(cancellationToken);
|
|
await Runner.SendAsync(command, cancellationToken);
|
|
if (command.Service == "turn_off") await _lightOff.NotifyAsync(cancellationToken);
|
|
if (command.ExpectedState is not null) await Runner.VerifyParameterAsync(command, cancellationToken);
|
|
}
|
|
|
|
public override async Task SetPowerAsync(bool turnOn, CancellationToken cancellationToken)
|
|
{
|
|
if (turnOn) { await _transition.StartSleepAsync(2700, cancellationToken); return; }
|
|
await _transition.CancelAsync(cancellationToken);
|
|
await Runner.SendAsync(new("关闭助眠灯光", PrimaryEntityId, "light", "turn_off")
|
|
{ Intent = DeviceCommandIntent.TurnRelaxationLightOff }, cancellationToken);
|
|
await _lightOff.NotifyAsync(cancellationToken);
|
|
}
|
|
|
|
public override async Task ExecuteSleepAsync(DeviceSceneContext context, PersonalizedSceneConfig config,
|
|
string constitutionCode, CancellationToken cancellationToken)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(PrimaryEntityId) || !context.States.TryGetValue(PrimaryEntityId, out var state) ||
|
|
!DeviceActionRunner.IsAvailable(state))
|
|
{
|
|
context.Results.Add(new() { Name = "开启助眠渐暗灯光", EntityId = PrimaryEntityId,
|
|
Status = "Skipped", Message = "灯光未配置或离线" }); return;
|
|
}
|
|
await context.ExternalAsync("开启助眠渐暗灯光", PrimaryEntityId,
|
|
async token => { await _transition.StartSleepAsync(config.LightColorTemperatureKelvin, token); }, cancellationToken);
|
|
}
|
|
|
|
public override IEnumerable<DeviceCommand> GetShutdownCommands()
|
|
=> [new("关闭助眠灯光", PrimaryEntityId, "light", "turn_off", ExpectedState: "off")
|
|
{ Intent = DeviceCommandIntent.TurnRelaxationLightOff }];
|
|
|
|
public override HomeAssistantScenePresetItem? BuildPreview(PersonalizedSceneConfig config, string constitutionCode)
|
|
=> string.IsNullOrWhiteSpace(PrimaryEntityId) ? null : Preview("开启助眠渐暗灯光",
|
|
$"从50%开始,每5秒降低1%,最终关灯 · 色温 {config.LightColorTemperatureKelvin}K",
|
|
new() { ["brightness"] = "50%→关闭", ["color_temp"] = $"{config.LightColorTemperatureKelvin}K" });
|
|
}
|