using Evergreen.Health.Application.Health.Models; namespace Evergreen.Health.Application.Health.Policies; public sealed record RecommendedRoomRange(int Minimum, int Maximum) { public static RecommendedRoomRange Default { get; } = new(22, 25); public string Display => $"{Minimum}–{Maximum}℃"; public static RecommendedRoomRange ForConstitution(string code) => code switch { "yang_deficient" => new(24, 26), "yin_deficient" or "damp_heat" => new(21, 24), "phlegm_damp" => new(22, 24), "blood_stasis" => new(23, 25), _ => Default }; } public enum IndoorTemperatureIssue { Unavailable, Stale, Invalid } public sealed record IndoorTemperatureSample(double? Celsius, DateTimeOffset? ObservedAt, bool Available, string Reason) { public IndoorTemperatureIssue? Issue { get; init; } } public static class RoomTemperaturePolicy { public static ClimateAdviceOutput Evaluate(IndoorTemperatureSample sample, RecommendedRoomRange range) { var mode = !sample.Available || sample.Celsius is null ? "unavailable" : sample.Celsius < range.Minimum ? "heat" : sample.Celsius > range.Maximum ? "cool" : "off"; return new() { Mode = mode, RecommendedMinimumCelsius = range.Minimum, RecommendedMaximumCelsius = range.Maximum, Reason = mode switch { "heat" => $"室温低于建议 {range.Display}:建议空调制热", "cool" => $"室温高于建议 {range.Display}:建议空调制冷", "off" => $"室温在建议 {range.Display} 内:空调保持当前运行状态", _ => $"{sample.Reason},不自动开启空调" }, PendingIntegration = mode is "heat" or "cool" }; } // 仅在启动新舒睡场景时调用,状态查询和预览不随机更改目标值。 public static void PickTargetForSession(ClimateAdviceOutput advice) { if (advice.TargetTemperatureCelsius is null && (advice.Mode is "heat" or "cool")) advice.TargetTemperatureCelsius = Random.Shared.Next(advice.RecommendedMinimumCelsius, advice.RecommendedMaximumCelsius + 1); } }