Files
Evergreen-Health/Evergreen.Health.Application/Health/Policies/RoomTemperaturePolicy.cs
T
2026-11-12 15:45:52 +08:00

51 lines
2.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}