38 lines
1.9 KiB
C#
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";
|
|
}
|
|
}
|