Files
Evergreen-Health/Evergreen.Health.Application/Health/Devices/Dehumidifier/BedPresenceDehumidifierStartAction.cs
T
2026-11-12 15:45:52 +08:00

57 lines
2.3 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.Dehumidifier;
public sealed class BedPresenceDehumidifierStartAction(DehumidifierModule dehumidifier, DeviceActionRunner runner,
IOptions<HomeAssistantOptions> options, TimeProvider clock) : IBedPresenceAction
{
private HomeAssistantOptions Configuration => options.Value;
public string Key => "dehumidifier-humidity-start";
public string Description => "湿度偏高时开启除湿机";
public string ConditionLabel => $"室内相对湿度超过 {Configuration.SleepScene.TargetHumidity}% 且除湿机关机时,发送开机指令。";
public bool SupportsTarget(string entityId) => entityId == dehumidifier.PrimaryEntityId &&
DehumidifierHumidityCondition.SupportsTarget(Configuration, entityId);
public async Task<string> ExecuteAsync(string entityId, CancellationToken token)
{
if (!SupportsTarget(entityId)) return "target-not-configured";
var command = dehumidifier.BuildStartCommand() with
{
ExpectedState = "on",
RetryOnVerificationMismatch = false
};
var reason = await runner.SendIfAsync(command, states => GetSkipReason(states, entityId), token);
if (reason is not null) return reason;
try
{
await runner.VerifyParameterAsync(command, token);
return "readback-confirmed";
}
catch (InvalidOperationException)
{
return "sent-readback-unconfirmed";
}
}
private string? GetSkipReason(IReadOnlyList<HomeAssistantState> states, string entityId)
{
var reason = DehumidifierHumidityCondition.SkipReason(states, Configuration, clock.GetUtcNow());
if (reason is not null) return reason;
var state = states.FirstOrDefault(item => string.Equals(item.EntityId, entityId, StringComparison.OrdinalIgnoreCase));
if (state is null || !DeviceActionRunner.IsAvailable(state)) return "dehumidifier-unavailable";
return state.State switch
{
"off" => null,
"on" => "dehumidifier-already-on",
_ => "dehumidifier-state-not-off"
};
}
}