27 lines
1.1 KiB
C#
27 lines
1.1 KiB
C#
namespace Evergreen.Health.Application.Health.Sleep;
|
|
|
|
/// <summary>本版没有异常判定算法;未来规则只产生事件,不直接操作音箱或家具。</summary>
|
|
public sealed record SleepAnomaly(string Code, string Description, DateTimeOffset ObservedAt);
|
|
public interface ISleepAnomalyRule
|
|
{
|
|
string Key { get; }
|
|
SleepAnomaly? Evaluate(IReadOnlyList<SleepObservation> observations);
|
|
}
|
|
|
|
/// <summary>每个舒睡会话独立持有;只有语音实际播报后才记录提醒时间。</summary>
|
|
public sealed class AnomalyReminderGate
|
|
{
|
|
private readonly TimeSpan _interval;
|
|
private readonly Dictionary<string, DateTimeOffset> _delivered = new(StringComparer.OrdinalIgnoreCase);
|
|
private readonly object _lock = new();
|
|
public AnomalyReminderGate(SleepWorkflowOptions options) => _interval = options.SameAnomalyReminderInterval;
|
|
public bool CanRemind(string code, DateTimeOffset now)
|
|
{
|
|
lock (_lock) return !_delivered.TryGetValue(code, out var last) || now - last >= _interval;
|
|
}
|
|
public void MarkDelivered(string code, DateTimeOffset now)
|
|
{
|
|
lock (_lock) _delivered[code] = now;
|
|
}
|
|
}
|