This commit is contained in:
fuenmao
2026-10-08 10:16:43 +08:00
parent af596104e2
commit 4a634ef4c2
8 changed files with 261 additions and 25 deletions
@@ -155,7 +155,20 @@ public sealed class HomeAssistantLightTransitionService : IHostedService
var light = await ReadAvailableLightAsync(cancellationToken);
if (!string.Equals(light.State, "on", StringComparison.OrdinalIgnoreCase))
{
SetStatus(false, false, mode, 0, mode == "wake" ? WakeTargetPercent : 0, "灯已从其他位置关闭,渐变已停止");
if (mode == "sleep")
{
try
{
await StopMattressMassageAsync(cancellationToken);
SetStatus(true, false, mode, 0, 0, "灯已关闭,床垫按摩已停止");
}
catch (Exception exception) when (exception is not OperationCanceledException)
{
_logger.LogWarning(exception, "灯已关闭,但床垫按摩停止失败");
SetStatus(false, false, mode, 0, 0, exception.Message);
}
}
else SetStatus(false, false, mode, 0, WakeTargetPercent, "灯已从其他位置关闭,渐变已停止");
return;
}
@@ -178,7 +191,17 @@ public sealed class HomeAssistantLightTransitionService : IHostedService
{
["entity_id"] = LightEntityId
}, cancellationToken);
SetStatus(true, false, mode, 0, 0, "助眠渐暗已完成,灯光已关闭");
SetStatus(true, false, mode, 0, 0, "灯光已关闭,正在停止床垫按摩");
try
{
await StopMattressMassageAsync(cancellationToken);
SetStatus(true, false, mode, 0, 0, "助眠渐暗已完成,灯光与床垫按摩已关闭");
}
catch (Exception exception) when (exception is not OperationCanceledException)
{
_logger.LogWarning(exception, "助眠渐暗已完成,但床垫按摩停止失败");
SetStatus(false, false, mode, 0, 0, exception.Message);
}
return;
}
@@ -204,6 +227,43 @@ public sealed class HomeAssistantLightTransitionService : IHostedService
}
}
private async Task StopMattressMassageAsync(CancellationToken cancellationToken)
{
var massageEntities = new[]
{
_options.Entities.MattressLeftMassagePart,
_options.Entities.MattressRightMassagePart
}.Where(entityId => !string.IsNullOrWhiteSpace(entityId)).Distinct().ToArray();
var failures = new List<string>();
foreach (var entityId in massageEntities)
{
try
{
var confirmed = false;
for (var attempt = 0; attempt < 2 && !confirmed; attempt++)
{
await _homeAssistant.CallServiceAsync("select", "select_option", new Dictionary<string, object?>
{
["entity_id"] = entityId,
["option"] = "无"
}, cancellationToken);
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
var current = (await _homeAssistant.GetStatesAsync(cancellationToken))
.FirstOrDefault(item => string.Equals(item.EntityId, entityId, StringComparison.OrdinalIgnoreCase));
confirmed = current?.State == "无";
}
if (!confirmed) failures.Add(entityId);
}
catch (Exception exception) when (exception is not OperationCanceledException)
{
_logger.LogWarning(exception, "灯光熄灭后未能关闭床垫按摩 {EntityId}", entityId);
failures.Add(entityId);
}
}
if (failures.Count > 0)
throw new InvalidOperationException($"灯光已关闭,但床垫按摩未确认关闭:{string.Join("、", failures)}");
}
private async Task StopCurrentAsync()
{
if (_activeCancellation is null) return;