Files
Evergreen-Health/Evergreen.Health.Application/Health/Devices/Lighting/BedPresenceSleepLightAction.cs
T
2026-11-11 16:11:41 +08:00

38 lines
1.9 KiB
C#

using Evergreen.Health.Application.Health.Integrations.HomeAssistant;
using Evergreen.Health.Application.Health.Scenes;
using Evergreen.Health.Application.Health.Sleep;
using Microsoft.Extensions.Options;
namespace Evergreen.Health.Application.Health.Devices.Lighting;
public sealed class BedPresenceSleepLightAction(HomeAssistantLightTransitionService lights, DeviceActionRunner runner,
DeviceExecutionOptions execution, IOptions<HomeAssistantOptions> options) : IBedPresenceAction
{
public string Key => "light-sleep";
public string Description => "启动助眠渐暗";
public bool SupportsTarget(string entityId) => options.Value.Enabled && entityId?.StartsWith("light.", StringComparison.Ordinal) == true &&
(entityId == options.Value.Entities.AmbientLight || options.Value.AdditionalSleepLights.Any(light => light.EntityId == entityId));
public async Task<string> ExecuteAsync(string entityId, CancellationToken token)
{
if (!SupportsTarget(entityId)) return "target-not-configured";
var transition = await lights.StartSleepIfIdleAsync(entityId, options.Value.SleepScene.LightColorTemperatureKelvin, token);
if (transition == null) return "already-running";
for (var attempt = 0; attempt < execution.VerificationAttempts; attempt++)
{
await runner.DelayAsync(execution.VerificationDelay, token);
try
{
var state = await runner.ReadAvailableStateAsync(entityId, token);
var brightness = state.GetDoubleAttribute("brightness");
if (state.State == "on" && brightness is double value &&
Math.Abs(value / 255 * 100 - transition.BrightnessPercent) <= 1.5)
return "readback-confirmed";
}
catch (InvalidOperationException) { /* 实体暂未回报,下一轮只重读状态。 */ }
}
return "sent-readback-unconfirmed";
}
}