111
This commit is contained in:
@@ -109,6 +109,7 @@ public sealed class HomeAssistantDeviceSwitchOutput
|
||||
public string DeviceId { get; set; } = string.Empty;
|
||||
public string EntityId { get; set; } = string.Empty;
|
||||
public string State { get; set; } = string.Empty;
|
||||
public bool? IsMuted { get; set; }
|
||||
public string Message { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
@@ -172,30 +172,86 @@ public sealed class HealthHomeAssistantService : IDynamicApiController, ITransie
|
||||
};
|
||||
}
|
||||
|
||||
var service = input.TurnOn ? "turn_on" : "turn_off";
|
||||
var targetOn = input.TurnOn;
|
||||
bool? targetMuted = null;
|
||||
var service = targetOn ? "turn_on" : "turn_off";
|
||||
if (domain == "media_player")
|
||||
{
|
||||
service = input.TurnOn ? "media_play" : "media_pause";
|
||||
// Xiaomi Sound Pro 的 media_player state 会长期保持 playing,不能用它
|
||||
// 判断声音是否开启;is_volume_muted 才是该实体可稳定回读的控制状态。
|
||||
var currentMutedText = currentState.GetStringAttribute("is_volume_muted");
|
||||
var currentMuted = bool.TryParse(currentMutedText, out var parsedMuted) && parsedMuted;
|
||||
targetMuted = !currentMuted;
|
||||
targetOn = !targetMuted.Value;
|
||||
service = "volume_mute";
|
||||
}
|
||||
|
||||
var serviceData = new Dictionary<string, object?>
|
||||
{
|
||||
["entity_id"] = targetEntityId
|
||||
};
|
||||
if (targetMuted.HasValue)
|
||||
{
|
||||
serviceData["is_volume_muted"] = targetMuted.Value;
|
||||
}
|
||||
|
||||
await _homeAssistant.CallServiceAsync(domain, service, serviceData, cancellationToken);
|
||||
|
||||
var resultState = domain == "media_player"
|
||||
? currentState.State
|
||||
: (targetOn ? "on" : "off");
|
||||
bool? resultMuted = null;
|
||||
|
||||
if (domain == "media_player")
|
||||
{
|
||||
var stateConfirmed = false;
|
||||
for (var attempt = 0; attempt < 5; attempt++)
|
||||
{
|
||||
await Task.Delay(300, cancellationToken);
|
||||
var refreshedStates = await _homeAssistant.GetStatesAsync(cancellationToken);
|
||||
var refreshedState = refreshedStates.FirstOrDefault(s =>
|
||||
string.Equals(s.EntityId, targetEntityId, StringComparison.OrdinalIgnoreCase));
|
||||
if (refreshedState is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
resultState = refreshedState.State;
|
||||
var refreshedMutedText = refreshedState.GetStringAttribute("is_volume_muted");
|
||||
resultMuted = bool.TryParse(refreshedMutedText, out var refreshedMuted)
|
||||
? refreshedMuted
|
||||
: null;
|
||||
stateConfirmed = resultMuted == targetMuted;
|
||||
if (stateConfirmed)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stateConfirmed)
|
||||
{
|
||||
return new HomeAssistantDeviceSwitchOutput
|
||||
{
|
||||
Success = false,
|
||||
DeviceId = input.DeviceId,
|
||||
EntityId = targetEntityId,
|
||||
State = resultState,
|
||||
IsMuted = resultMuted,
|
||||
Message = $"音箱指令已发送,但静音状态未确认更新(当前:{(resultMuted.HasValue ? (resultMuted.Value ? "已静音" : "声音开启") : "未知")})"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return new HomeAssistantDeviceSwitchOutput
|
||||
{
|
||||
Success = true,
|
||||
DeviceId = input.DeviceId,
|
||||
EntityId = targetEntityId,
|
||||
State = domain == "media_player"
|
||||
? (input.TurnOn ? "playing" : "paused")
|
||||
: (input.TurnOn ? "on" : "off"),
|
||||
State = resultState,
|
||||
IsMuted = resultMuted,
|
||||
Message = domain == "media_player"
|
||||
? $"已成功{(input.TurnOn ? "开始播放" : "暂停播放")}"
|
||||
: $"已成功{(input.TurnOn ? "开启" : "关闭")}设备"
|
||||
? (targetMuted == true ? "音箱已静音" : "音箱声音已开启")
|
||||
: $"已成功{(targetOn ? "开启" : "关闭")}设备"
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -384,12 +440,21 @@ public sealed class HealthHomeAssistantService : IDynamicApiController, ITransie
|
||||
{
|
||||
}
|
||||
|
||||
var successMessage = parameterType switch
|
||||
{
|
||||
"mattress_left_mode" when !string.Equals(serviceData["option"]?.ToString(), "无", StringComparison.Ordinal) =>
|
||||
"左侧承托模式已启动;床垫共用气泵,右侧会自动停止",
|
||||
"mattress_right_mode" when !string.Equals(serviceData["option"]?.ToString(), "无", StringComparison.Ordinal) =>
|
||||
"右侧承托模式已启动;床垫共用气泵,左侧会自动停止",
|
||||
_ => "参数调节成功"
|
||||
};
|
||||
|
||||
return new HomeAssistantSetParameterOutput
|
||||
{
|
||||
Success = true,
|
||||
DeviceId = input.DeviceId,
|
||||
ParameterType = input.ParameterType ?? "",
|
||||
Message = "参数调节成功"
|
||||
Message = successMessage
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -539,13 +604,17 @@ public sealed class HealthHomeAssistantService : IDynamicApiController, ITransie
|
||||
if (enableSpeakerSleepMode)
|
||||
{
|
||||
await RunAction(states, results, "开启音箱睡眠模式", entities.SpeakerSleepMode, "switch", "turn_on", null, cancellationToken);
|
||||
await RunAction(states, results, "设置助眠音量", entities.Speaker, "media_player", "volume_set",
|
||||
new Dictionary<string, object?> { ["volume_level"] = speakerVolume / 100d }, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
await RunAction(states, results, "关闭音箱睡眠模式", entities.SpeakerSleepMode, "switch", "turn_off", null, cancellationToken);
|
||||
}
|
||||
// 音箱声音与睡眠模式是两种不同能力。即使用户未启用睡眠模式,
|
||||
// 一键舒睡也应取消静音并应用个性化音量。
|
||||
await RunAction(states, results, "开启音箱声音", entities.Speaker, "media_player", "volume_mute",
|
||||
new Dictionary<string, object?> { ["is_volume_muted"] = false }, cancellationToken);
|
||||
await RunAction(states, results, "设置助眠音量", entities.Speaker, "media_player", "volume_set",
|
||||
new Dictionary<string, object?> { ["volume_level"] = speakerVolume / 100d }, cancellationToken);
|
||||
|
||||
if (scene.EnableMattress)
|
||||
{
|
||||
@@ -571,6 +640,8 @@ public sealed class HealthHomeAssistantService : IDynamicApiController, ITransie
|
||||
await RunAction(states, results, "关闭香氛灯", entities.FragranceLight, "light", "turn_off", null, cancellationToken);
|
||||
await RunAction(states, results, "关闭助眠灯光", entities.AmbientLight, "light", "turn_off", null, cancellationToken);
|
||||
await RunAction(states, results, "关闭音箱睡眠模式", entities.SpeakerSleepMode, "switch", "turn_off", null, cancellationToken);
|
||||
await RunAction(states, results, "静音音箱", entities.Speaker, "media_player", "volume_mute",
|
||||
new Dictionary<string, object?> { ["is_volume_muted"] = true }, cancellationToken);
|
||||
if (_options.SleepScene.EnableMattress)
|
||||
{
|
||||
await RunAction(states, results, "关闭床垫左侧加热", entities.MattressLeftHeatingLevel, "number", "set_value",
|
||||
@@ -835,7 +906,9 @@ public sealed class HealthHomeAssistantService : IDynamicApiController, ITransie
|
||||
sceneEntityIds.Add(entities.FragranceSwitch);
|
||||
if (!string.IsNullOrWhiteSpace(entities.AmbientLight))
|
||||
sceneEntityIds.Add(entities.AmbientLight);
|
||||
if (_options.SleepScene.EnableSpeakerSleepMode && !string.IsNullOrWhiteSpace(entities.SpeakerSleepMode))
|
||||
if (!string.IsNullOrWhiteSpace(entities.Speaker))
|
||||
sceneEntityIds.Add(entities.Speaker);
|
||||
else if (_options.SleepScene.EnableSpeakerSleepMode && !string.IsNullOrWhiteSpace(entities.SpeakerSleepMode))
|
||||
sceneEntityIds.Add(entities.SpeakerSleepMode);
|
||||
if (_options.SleepScene.EnableMattress && !string.IsNullOrWhiteSpace(entities.MattressLeftHeatingLevel))
|
||||
sceneEntityIds.Add(entities.MattressLeftHeatingLevel);
|
||||
@@ -1114,17 +1187,17 @@ public sealed class HealthHomeAssistantService : IDynamicApiController, ITransie
|
||||
});
|
||||
}
|
||||
|
||||
if (enableSpeaker && !string.IsNullOrWhiteSpace(_options.Entities.SpeakerSleepMode))
|
||||
if (!string.IsNullOrWhiteSpace(_options.Entities.Speaker))
|
||||
{
|
||||
var vol = userConfig?.SpeakerVolumePercent ?? 15;
|
||||
presets.Add(new HomeAssistantScenePresetItem
|
||||
{
|
||||
DeviceName = "Xiaomi Sound Pro",
|
||||
Category = nameof(HealthDeviceCategory.Media),
|
||||
EntityId = _options.Entities.SpeakerSleepMode,
|
||||
Action = "开启音箱睡眠模式",
|
||||
Detail = $"切换睡眠模式开关 · 音量 {vol}%",
|
||||
Parameters = new() { ["sleep_mode"] = "开启", ["volume"] = $"{vol}%" }
|
||||
EntityId = _options.Entities.Speaker,
|
||||
Action = enableSpeaker ? "开启音箱声音和睡眠模式" : "开启音箱声音",
|
||||
Detail = enableSpeaker ? $"取消静音 · 开启睡眠模式 · 音量 {vol}%" : $"取消静音 · 音量 {vol}%",
|
||||
Parameters = new() { ["muted"] = false, ["sleep_mode"] = enableSpeaker ? "开启" : "关闭", ["volume"] = $"{vol}%" }
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user