51 lines
2.2 KiB
C#
51 lines
2.2 KiB
C#
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);
|
||
}
|
||
}
|