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

53 lines
2.8 KiB
C#

using Evergreen.Health.Application.Health.Devices.Contracts;
using Evergreen.Health.Application.Health.Models;
using Evergreen.Health.Application.Health.Scenes;
namespace Evergreen.Health.Application.Health.Devices;
public abstract class HealthDeviceModule : IHealthDeviceModule
{
protected DeviceActionRunner Runner { get; }
protected HealthDeviceModule(DeviceActionRunner runner) => Runner = runner;
public abstract string Key { get; }
public abstract string Category { get; }
public abstract string DisplayName { get; }
public abstract string PrimaryEntityId { get; }
public virtual bool PowerUsesIndependentGateway => false;
public virtual bool ParameterUsesIndependentGateway(DeviceCommand command) => false;
public abstract IReadOnlyList<DeviceParameterDefinition> Parameters { get; }
public virtual IEnumerable<string> EntityIds => Parameters.Select(parameter => parameter.EntityId)
.Append(PrimaryEntityId).Where(id => !string.IsNullOrWhiteSpace(id)).Distinct(StringComparer.OrdinalIgnoreCase);
public DeviceCommand BuildParameterCommand(string parameterType, object? value)
=> (Parameters.FirstOrDefault(parameter => string.Equals(parameter.Key, parameterType, StringComparison.OrdinalIgnoreCase))
?? throw new InvalidOperationException($"不支持的参数类型:{parameterType}")).Build(value);
public virtual async Task ExecuteParameterAsync(DeviceCommand command, CancellationToken cancellationToken)
{
await Runner.SendAsync(command, cancellationToken);
if (command.ExpectedState is not null)
await Runner.VerifyParameterAsync(command, cancellationToken);
}
public virtual Task SetPowerAsync(bool turnOn, CancellationToken cancellationToken)
{
var domain = PrimaryEntityId.Split('.')[0];
if (domain is not ("switch" or "humidifier" or "light" or "media_player" or "climate"))
throw new InvalidOperationException("该模块没有安全的主控开关");
return Runner.SendAsync(new(turnOn ? "开启设备" : "关闭设备", PrimaryEntityId, domain,
turnOn ? "turn_on" : "turn_off"), cancellationToken);
}
public virtual Task ExecuteSleepAsync(DeviceSceneContext context, PersonalizedSceneConfig config,
string constitutionCode, CancellationToken cancellationToken) => Task.CompletedTask;
public virtual IEnumerable<DeviceCommand> GetShutdownCommands() => [];
public virtual HomeAssistantScenePresetItem? BuildPreview(PersonalizedSceneConfig config, string constitutionCode) => null;
protected HomeAssistantScenePresetItem Preview(string action, string detail,
Dictionary<string, object?>? parameters = null) => new()
{
DeviceName = DisplayName, Category = Category, EntityId = PrimaryEntityId,
Action = action, Detail = detail, Parameters = parameters ?? new()
};
}