This commit is contained in:
fuenmao
2026-10-09 18:06:11 +08:00
parent e6b90a06ab
commit 2d44cc3966
17 changed files with 1161 additions and 264 deletions
@@ -33,6 +33,7 @@ public sealed class HealthHomeAssistantService : IDynamicApiController, ITransie
private readonly MattressComfortService _mattressComfort;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly DeviceModuleRegistry _modules;
private readonly DeviceParameterController _parameters;
private readonly HealthSceneCoordinator _scenes;
private readonly HomeAssistantDeviceCatalog _catalog;
private readonly ILogger<HealthHomeAssistantService> _logger;
@@ -48,6 +49,7 @@ public sealed class HealthHomeAssistantService : IDynamicApiController, ITransie
MattressComfortService mattressComfort,
IHttpContextAccessor httpContextAccessor,
DeviceModuleRegistry modules,
DeviceParameterController parameters,
HealthSceneCoordinator scenes,
HomeAssistantDeviceCatalog catalog,
ILogger<HealthHomeAssistantService> logger)
@@ -62,6 +64,7 @@ public sealed class HealthHomeAssistantService : IDynamicApiController, ITransie
_mattressComfort = mattressComfort;
_httpContextAccessor = httpContextAccessor;
_modules = modules;
_parameters = parameters;
_scenes = scenes;
_catalog = catalog;
_logger = logger;
@@ -95,7 +98,7 @@ public sealed class HealthHomeAssistantService : IDynamicApiController, ITransie
[HttpPost("/api/health/home-assistant/lights/stop")]
public async Task<HomeAssistantLightTransitionOutput> StopLightTransition(CancellationToken cancellationToken)
{
try { return await _lightTransition.CancelAsync(cancellationToken); }
try { return await _lightTransition.CancelPrimaryAsync(cancellationToken); }
catch (Exception exception) when (exception is not OperationCanceledException) { return new HomeAssistantLightTransitionOutput { Success = false, Message = exception.Message }; }
}
@@ -303,20 +306,8 @@ public sealed class HealthHomeAssistantService : IDynamicApiController, ITransie
}
var parameterType = input.ParameterType.Trim().ToLowerInvariant();
var module = _modules.ForParameter(parameterType);
var command = module.BuildParameterCommand(parameterType, input.Value);
if (string.IsNullOrWhiteSpace(command.EntityId))
throw new InvalidOperationException("该参数尚未配置 Home Assistant 实体");
if (!string.IsNullOrWhiteSpace(input.EntityId) &&
!string.Equals(input.EntityId, command.EntityId, StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException("请求实体与该参数的受信任实体不匹配");
if (!targetDevice.Entities.Any(entity => string.Equals(entity.EntityId, command.EntityId, StringComparison.OrdinalIgnoreCase)))
throw new InvalidOperationException("该参数不属于指定设备");
// 外部音频网关不依赖 HA 媒体实体是否在线,但仍校验实体归属。
if (!module.ParameterUsesIndependentGateway(command) &&
(!stateMap.TryGetValue(command.EntityId, out var state) || !IsAvailable(state)))
throw new InvalidOperationException("目标参数实体当前离线或不可用");
await module.ExecuteParameterAsync(command, cancellationToken);
var command = await _parameters.ExecuteAsync(targetDevice, stateMap, parameterType, input.Value,
input.EntityId, cancellationToken);
return new HomeAssistantSetParameterOutput
{
Success = true, DeviceId = input.DeviceId, ParameterType = parameterType,