Update StepSpeaker and Speaker interfaces in Alexa (#31444)

* Yield only one Speaker interface.

* Yield PowerController only is supported.

* Revert "Yield PowerController only is supported."

This reverts commit c0dbf7e4

* Add Alexa.Speaker interface properties.

* Refactor tests for Alexa.Speaker and Alexa.StepSpeaker.

* Code Smell Change.

* Fix R1705: Unnecessary "elif" after "return".
This commit is contained in:
ochlocracy 2020-02-03 17:20:39 -05:00 committed by GitHub
parent 3f9dbe6845
commit c8d9b83b24
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 165 additions and 101 deletions

View file

@ -1,5 +1,6 @@
"""Alexa capabilities."""
import logging
import math
from homeassistant.components import (
cover,
@ -645,6 +646,43 @@ class AlexaSpeaker(AlexaCapability):
"""Return the Alexa API name of this interface."""
return "Alexa.Speaker"
def properties_supported(self):
"""Return what properties this entity supports."""
properties = [{"name": "volume"}]
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if supported & media_player.SUPPORT_VOLUME_MUTE:
properties.append({"name": "muted"})
return properties
def properties_proactively_reported(self):
"""Return True if properties asynchronously reported."""
return True
def properties_retrievable(self):
"""Return True if properties can be retrieved."""
return True
def get_property(self, name):
"""Read and return a property."""
if name == "volume":
current_level = self.entity.attributes.get(
media_player.ATTR_MEDIA_VOLUME_LEVEL
)
try:
current = math.floor(int(current_level * 100))
except ZeroDivisionError:
current = 0
return current
if name == "muted":
return bool(
self.entity.attributes.get(media_player.ATTR_MEDIA_VOLUME_MUTED)
)
return None
class AlexaStepSpeaker(AlexaCapability):
"""Implements Alexa.StepSpeaker.

View file

@ -508,12 +508,7 @@ class MediaPlayerCapabilities(AlexaEntity):
supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
if supported & media_player.const.SUPPORT_VOLUME_SET:
yield AlexaSpeaker(self.entity)
step_volume_features = (
media_player.const.SUPPORT_VOLUME_MUTE
| media_player.const.SUPPORT_VOLUME_STEP
)
if supported & step_volume_features:
elif supported & media_player.const.SUPPORT_VOLUME_STEP:
yield AlexaStepSpeaker(self.entity)
playback_features = (

View file

@ -16,6 +16,7 @@ from homeassistant.components.media_player.const import (
SUPPORT_TURN_ON,
SUPPORT_VOLUME_MUTE,
SUPPORT_VOLUME_SET,
SUPPORT_VOLUME_STEP,
)
import homeassistant.components.vacuum as vacuum
from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT
@ -904,7 +905,6 @@ async def test_media_player(hass):
"Alexa.PlaybackStateReporter",
"Alexa.PowerController",
"Alexa.Speaker",
"Alexa.StepSpeaker",
)
playback_capability = get_capability(capabilities, "Alexa.PlaybackController")
@ -958,93 +958,6 @@ async def test_media_player(hass):
hass,
)
call, _ = await assert_request_calls_service(
"Alexa.Speaker",
"SetVolume",
"media_player#test",
"media_player.volume_set",
hass,
payload={"volume": 50},
)
assert call.data["volume_level"] == 0.5
call, _ = await assert_request_calls_service(
"Alexa.Speaker",
"SetMute",
"media_player#test",
"media_player.volume_mute",
hass,
payload={"mute": True},
)
assert call.data["is_volume_muted"]
call, _, = await assert_request_calls_service(
"Alexa.Speaker",
"SetMute",
"media_player#test",
"media_player.volume_mute",
hass,
payload={"mute": False},
)
assert not call.data["is_volume_muted"]
await assert_percentage_changes(
hass,
[(0.7, "-5"), (0.8, "5"), (0, "-80")],
"Alexa.Speaker",
"AdjustVolume",
"media_player#test",
"volume",
"media_player.volume_set",
"volume_level",
)
call, _ = await assert_request_calls_service(
"Alexa.StepSpeaker",
"SetMute",
"media_player#test",
"media_player.volume_mute",
hass,
payload={"mute": True},
)
assert call.data["is_volume_muted"]
call, _, = await assert_request_calls_service(
"Alexa.StepSpeaker",
"SetMute",
"media_player#test",
"media_player.volume_mute",
hass,
payload={"mute": False},
)
assert not call.data["is_volume_muted"]
call, _ = await assert_request_calls_service(
"Alexa.StepSpeaker",
"AdjustVolume",
"media_player#test",
"media_player.volume_up",
hass,
payload={"volumeSteps": 1, "volumeStepsDefault": False},
)
call, _ = await assert_request_calls_service(
"Alexa.StepSpeaker",
"AdjustVolume",
"media_player#test",
"media_player.volume_down",
hass,
payload={"volumeSteps": -1, "volumeStepsDefault": False},
)
call, _ = await assert_request_calls_service(
"Alexa.StepSpeaker",
"AdjustVolume",
"media_player#test",
"media_player.volume_up",
hass,
payload={"volumeSteps": 10, "volumeStepsDefault": True},
)
call, _ = await assert_request_calls_service(
"Alexa.ChannelController",
"ChangeChannel",
@ -1140,7 +1053,6 @@ async def test_media_player_power(hass):
"Alexa.PowerController",
"Alexa.SeekController",
"Alexa.Speaker",
"Alexa.StepSpeaker",
)
await assert_request_calls_service(
@ -1265,22 +1177,141 @@ async def test_media_player_inputs(hass):
async def test_media_player_speaker(hass):
"""Test media player discovery with device class speaker."""
"""Test media player with speaker interface."""
device = (
"media_player.test",
"media_player.test_speaker",
"off",
{
"friendly_name": "Test media player",
"supported_features": 51765,
"friendly_name": "Test media player speaker",
"supported_features": SUPPORT_VOLUME_MUTE | SUPPORT_VOLUME_SET,
"volume_level": 0.75,
"device_class": "speaker",
},
)
appliance = await discovery_test(device, hass)
assert appliance["endpointId"] == "media_player#test"
assert appliance["endpointId"] == "media_player#test_speaker"
assert appliance["displayCategories"][0] == "SPEAKER"
assert appliance["friendlyName"] == "Test media player"
assert appliance["friendlyName"] == "Test media player speaker"
capabilities = assert_endpoint_capabilities(
appliance,
"Alexa",
"Alexa.EndpointHealth",
"Alexa.PowerController",
"Alexa.Speaker",
)
speaker_capability = get_capability(capabilities, "Alexa.Speaker")
properties = speaker_capability["properties"]
assert {"name": "volume"} in properties["supported"]
assert {"name": "muted"} in properties["supported"]
call, _ = await assert_request_calls_service(
"Alexa.Speaker",
"SetVolume",
"media_player#test_speaker",
"media_player.volume_set",
hass,
payload={"volume": 50},
)
assert call.data["volume_level"] == 0.5
call, _ = await assert_request_calls_service(
"Alexa.Speaker",
"SetMute",
"media_player#test_speaker",
"media_player.volume_mute",
hass,
payload={"mute": True},
)
assert call.data["is_volume_muted"]
call, _, = await assert_request_calls_service(
"Alexa.Speaker",
"SetMute",
"media_player#test_speaker",
"media_player.volume_mute",
hass,
payload={"mute": False},
)
assert not call.data["is_volume_muted"]
await assert_percentage_changes(
hass,
[(0.7, "-5"), (0.8, "5"), (0, "-80")],
"Alexa.Speaker",
"AdjustVolume",
"media_player#test_speaker",
"volume",
"media_player.volume_set",
"volume_level",
)
async def test_media_player_step_speaker(hass):
"""Test media player with step speaker interface."""
device = (
"media_player.test_step_speaker",
"off",
{
"friendly_name": "Test media player step speaker",
"supported_features": SUPPORT_VOLUME_MUTE | SUPPORT_VOLUME_STEP,
"device_class": "speaker",
},
)
appliance = await discovery_test(device, hass)
assert appliance["endpointId"] == "media_player#test_step_speaker"
assert appliance["displayCategories"][0] == "SPEAKER"
assert appliance["friendlyName"] == "Test media player step speaker"
call, _ = await assert_request_calls_service(
"Alexa.StepSpeaker",
"SetMute",
"media_player#test_step_speaker",
"media_player.volume_mute",
hass,
payload={"mute": True},
)
assert call.data["is_volume_muted"]
call, _, = await assert_request_calls_service(
"Alexa.StepSpeaker",
"SetMute",
"media_player#test_step_speaker",
"media_player.volume_mute",
hass,
payload={"mute": False},
)
assert not call.data["is_volume_muted"]
call, _ = await assert_request_calls_service(
"Alexa.StepSpeaker",
"AdjustVolume",
"media_player#test_step_speaker",
"media_player.volume_up",
hass,
payload={"volumeSteps": 1, "volumeStepsDefault": False},
)
call, _ = await assert_request_calls_service(
"Alexa.StepSpeaker",
"AdjustVolume",
"media_player#test_step_speaker",
"media_player.volume_down",
hass,
payload={"volumeSteps": -1, "volumeStepsDefault": False},
)
call, _ = await assert_request_calls_service(
"Alexa.StepSpeaker",
"AdjustVolume",
"media_player#test_step_speaker",
"media_player.volume_up",
hass,
payload={"volumeSteps": 10, "volumeStepsDefault": True},
)
async def test_media_player_seek(hass):