using Evergreen.Health.Application.Health.Devices.Environment; using Evergreen.Health.Application.Health.Integrations.HomeAssistant; using Evergreen.Health.Application.Health.Policies; using Evergreen.Health.Application.Health.Sleep; using Microsoft.Extensions.Options; namespace Evergreen.Health.Application.Health.Devices.Climate; public sealed class BedPresenceClimatePreview(IHomeAssistantGateway gateway, IndoorEnvironmentReader environment, IOptions options) : IBedPresenceAction { private HomeAssistantOptions Configuration => options.Value; public string Key => "climate-temperature-preview"; public string Description => "按室温判断空调模式"; public bool PreviewOnly => true; public string ConditionLabel => $"室温高于 {RecommendedRoomRange.Default.Maximum}℃ 时计划制冷,低于 {RecommendedRoomRange.Default.Minimum}℃ 时计划制热。"; public bool SupportsTarget(string entityId) => Configuration.Enabled && entityId?.StartsWith("climate.", StringComparison.Ordinal) == true && entityId == Configuration.Entities.Climate && Configuration.Entities.Temperature?.StartsWith("sensor.", StringComparison.Ordinal) == true; public async Task ExecuteAsync(string entityId, CancellationToken token) { if (!SupportsTarget(entityId)) return "target-not-configured"; IReadOnlyList states; try { states = await gateway.GetStatesAsync(token); } catch (Exception error) when (error is not OperationCanceledException) { return "preview-temperature-unavailable"; } var sample = environment.Read(states); return RoomTemperaturePolicy.Evaluate(sample, RecommendedRoomRange.Default).Mode switch { "cool" => "preview-climate-cool", "heat" => "preview-climate-heat", "off" => "preview-temperature-within-range", _ => sample.Issue switch { IndoorTemperatureIssue.Stale => "preview-temperature-stale", IndoorTemperatureIssue.Invalid => "preview-temperature-invalid", _ => "preview-temperature-unavailable" } }; } }