Files
Evergreen-Health/Evergreen.Health.Application/Health/Devices/Outlet/OutletModule.cs
T
2026-10-09 16:46:30 +08:00

45 lines
2.3 KiB
C#

using Evergreen.Health.Application.Health.Devices.Contracts;
using Evergreen.Health.Application.Health.Integrations.HomeAssistant;
using Evergreen.Health.Application.Health.Models;
using Evergreen.Health.Application.Health.Scenes;
using Microsoft.Extensions.Options;
namespace Evergreen.Health.Application.Health.Devices.Outlet;
/// <summary>仅单独控制明确绑定的插座主开关;不使用服务开关、切换按钮或内部保护参数。</summary>
public sealed class OutletModule : HealthDeviceModule
{
private readonly string _entityId;
public OutletModule(DeviceActionRunner runner, IOptions<HomeAssistantOptions> options) : base(runner)
=> _entityId = options.Value.Entities.Outlet;
public override string Key => "outlet";
public override string Category => nameof(HealthDeviceCategory.Outlet);
public override string DisplayName => "智能插座";
public override string PrimaryEntityId => _entityId;
public override IReadOnlyList<DeviceParameterDefinition> Parameters => [];
public override async Task SetPowerAsync(bool turnOn, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
if (!_entityId.StartsWith("switch.", StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException("插座主开关尚未正确绑定");
var command = new DeviceCommand(turnOn ? "开启插座电源" : "关闭插座电源", _entityId, "switch",
turnOn ? "turn_on" : "turn_off", ExpectedState: turnOn ? "on" : "off")
{
ValidateCurrentState = state =>
{
if (!string.Equals(state.EntityId, _entityId, StringComparison.OrdinalIgnoreCase) ||
state.State is not ("on" or "off"))
throw new InvalidOperationException("插座主开关状态未确认,请刷新后再试");
},
// 等待有限次数回读,不因读数延迟再次通电,也不使用 toggle 反转电源。
RetryOnVerificationMismatch = false
};
await Runner.SendAsync(command, cancellationToken);
await Runner.VerifyParameterAsync(command, cancellationToken);
}
// 本版不接入舒睡/唤醒/一键关闭:沿用基类的无场景动作、无关闭命令、无场景预览。
}