mirror of
https://github.com/home-assistant/core.git
synced 2025-11-09 19:09:32 +00:00
Support muting and relative-volume media_players in Google Assistant (#38651)
Support the action.devices.commands.mute intent to mute and unmute media_players that declare support for mute/unmute. For media players with support for volume up/down, but no support for setting the volume to a specific number, allow use of the action.devices.commands.relativeMute intent to control volume up/down. This will improve support for IR blasters and other open-loop media_player integrations.
This commit is contained in:
@@ -2003,9 +2003,7 @@ async def test_volume_media_player(hass):
|
||||
"""Test volume trait support for media player domain."""
|
||||
assert helpers.get_google_type(media_player.DOMAIN, None) is not None
|
||||
assert trait.VolumeTrait.supported(
|
||||
media_player.DOMAIN,
|
||||
media_player.SUPPORT_VOLUME_SET | media_player.SUPPORT_VOLUME_MUTE,
|
||||
None,
|
||||
media_player.DOMAIN, media_player.SUPPORT_VOLUME_SET, None,
|
||||
)
|
||||
|
||||
trt = trait.VolumeTrait(
|
||||
@@ -2014,16 +2012,21 @@ async def test_volume_media_player(hass):
|
||||
"media_player.bla",
|
||||
media_player.STATE_PLAYING,
|
||||
{
|
||||
ATTR_SUPPORTED_FEATURES: media_player.SUPPORT_VOLUME_SET,
|
||||
media_player.ATTR_MEDIA_VOLUME_LEVEL: 0.3,
|
||||
media_player.ATTR_MEDIA_VOLUME_MUTED: False,
|
||||
},
|
||||
),
|
||||
BASIC_CONFIG,
|
||||
)
|
||||
|
||||
assert trt.sync_attributes() == {}
|
||||
assert trt.sync_attributes() == {
|
||||
"volumeMaxLevel": 100,
|
||||
"levelStepSize": 10,
|
||||
"volumeCanMuteAndUnmute": False,
|
||||
"commandOnlyVolume": False,
|
||||
}
|
||||
|
||||
assert trt.query_attributes() == {"currentVolume": 30, "isMuted": False}
|
||||
assert trt.query_attributes() == {"currentVolume": 30}
|
||||
|
||||
calls = async_mock_service(
|
||||
hass, media_player.DOMAIN, media_player.SERVICE_VOLUME_SET
|
||||
@@ -2035,40 +2038,130 @@ async def test_volume_media_player(hass):
|
||||
media_player.ATTR_MEDIA_VOLUME_LEVEL: 0.6,
|
||||
}
|
||||
|
||||
calls = async_mock_service(
|
||||
hass, media_player.DOMAIN, media_player.SERVICE_VOLUME_SET
|
||||
)
|
||||
await trt.execute(
|
||||
trait.COMMAND_VOLUME_RELATIVE, BASIC_DATA, {"relativeSteps": 10}, {}
|
||||
)
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data == {
|
||||
ATTR_ENTITY_ID: "media_player.bla",
|
||||
media_player.ATTR_MEDIA_VOLUME_LEVEL: 0.4,
|
||||
}
|
||||
|
||||
|
||||
async def test_volume_media_player_relative(hass):
|
||||
"""Test volume trait support for media player domain."""
|
||||
"""Test volume trait support for relative-volume-only media players."""
|
||||
assert trait.VolumeTrait.supported(
|
||||
media_player.DOMAIN, media_player.SUPPORT_VOLUME_STEP, None,
|
||||
)
|
||||
trt = trait.VolumeTrait(
|
||||
hass,
|
||||
State(
|
||||
"media_player.bla",
|
||||
media_player.STATE_PLAYING,
|
||||
{
|
||||
media_player.ATTR_MEDIA_VOLUME_LEVEL: 0.3,
|
||||
ATTR_ASSUMED_STATE: True,
|
||||
ATTR_SUPPORTED_FEATURES: media_player.SUPPORT_VOLUME_STEP,
|
||||
},
|
||||
),
|
||||
BASIC_CONFIG,
|
||||
)
|
||||
|
||||
assert trt.sync_attributes() == {
|
||||
"volumeMaxLevel": 100,
|
||||
"levelStepSize": 10,
|
||||
"volumeCanMuteAndUnmute": False,
|
||||
"commandOnlyVolume": True,
|
||||
}
|
||||
|
||||
assert trt.query_attributes() == {}
|
||||
|
||||
calls = async_mock_service(
|
||||
hass, media_player.DOMAIN, media_player.SERVICE_VOLUME_UP
|
||||
)
|
||||
|
||||
await trt.execute(
|
||||
trait.COMMAND_VOLUME_RELATIVE, BASIC_DATA, {"relativeSteps": 10}, {},
|
||||
)
|
||||
assert len(calls) == 10
|
||||
for call in calls:
|
||||
assert call.data == {
|
||||
ATTR_ENTITY_ID: "media_player.bla",
|
||||
}
|
||||
|
||||
calls = async_mock_service(
|
||||
hass, media_player.DOMAIN, media_player.SERVICE_VOLUME_DOWN
|
||||
)
|
||||
await trt.execute(
|
||||
trait.COMMAND_VOLUME_RELATIVE, BASIC_DATA, {"relativeSteps": -10}, {},
|
||||
)
|
||||
assert len(calls) == 10
|
||||
for call in calls:
|
||||
assert call.data == {
|
||||
ATTR_ENTITY_ID: "media_player.bla",
|
||||
}
|
||||
|
||||
with pytest.raises(SmartHomeError):
|
||||
await trt.execute(trait.COMMAND_SET_VOLUME, BASIC_DATA, {"volumeLevel": 42}, {})
|
||||
|
||||
with pytest.raises(SmartHomeError):
|
||||
await trt.execute(trait.COMMAND_MUTE, BASIC_DATA, {"mute": True}, {})
|
||||
|
||||
|
||||
async def test_media_player_mute(hass):
|
||||
"""Test volume trait support for muting."""
|
||||
assert trait.VolumeTrait.supported(
|
||||
media_player.DOMAIN,
|
||||
media_player.SUPPORT_VOLUME_STEP | media_player.SUPPORT_VOLUME_MUTE,
|
||||
None,
|
||||
)
|
||||
trt = trait.VolumeTrait(
|
||||
hass,
|
||||
State(
|
||||
"media_player.bla",
|
||||
media_player.STATE_PLAYING,
|
||||
{
|
||||
ATTR_SUPPORTED_FEATURES: (
|
||||
media_player.SUPPORT_VOLUME_STEP | media_player.SUPPORT_VOLUME_MUTE
|
||||
),
|
||||
media_player.ATTR_MEDIA_VOLUME_MUTED: False,
|
||||
},
|
||||
),
|
||||
BASIC_CONFIG,
|
||||
)
|
||||
|
||||
assert trt.sync_attributes() == {}
|
||||
assert trt.sync_attributes() == {
|
||||
"volumeMaxLevel": 100,
|
||||
"levelStepSize": 10,
|
||||
"volumeCanMuteAndUnmute": True,
|
||||
"commandOnlyVolume": False,
|
||||
}
|
||||
assert trt.query_attributes() == {"isMuted": False}
|
||||
|
||||
assert trt.query_attributes() == {"currentVolume": 30, "isMuted": False}
|
||||
|
||||
calls = async_mock_service(
|
||||
hass, media_player.DOMAIN, media_player.SERVICE_VOLUME_SET
|
||||
mute_calls = async_mock_service(
|
||||
hass, media_player.DOMAIN, media_player.SERVICE_VOLUME_MUTE
|
||||
)
|
||||
|
||||
await trt.execute(
|
||||
trait.COMMAND_VOLUME_RELATIVE,
|
||||
BASIC_DATA,
|
||||
{"volumeRelativeLevel": 20, "relativeSteps": 2},
|
||||
{},
|
||||
trait.COMMAND_MUTE, BASIC_DATA, {"mute": True}, {},
|
||||
)
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data == {
|
||||
assert len(mute_calls) == 1
|
||||
assert mute_calls[0].data == {
|
||||
ATTR_ENTITY_ID: "media_player.bla",
|
||||
media_player.ATTR_MEDIA_VOLUME_LEVEL: 0.5,
|
||||
media_player.ATTR_MEDIA_VOLUME_MUTED: True,
|
||||
}
|
||||
|
||||
unmute_calls = async_mock_service(
|
||||
hass, media_player.DOMAIN, media_player.SERVICE_VOLUME_MUTE
|
||||
)
|
||||
await trt.execute(
|
||||
trait.COMMAND_MUTE, BASIC_DATA, {"mute": False}, {},
|
||||
)
|
||||
assert len(unmute_calls) == 1
|
||||
assert unmute_calls[0].data == {
|
||||
ATTR_ENTITY_ID: "media_player.bla",
|
||||
media_player.ATTR_MEDIA_VOLUME_MUTED: False,
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user