mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 09:17:53 +00:00
alexa: Add media_player InputController support (#11946)
`media_player`s can support select_source so map that to an InputController. [1]: https://developer.amazon.com/docs/device-apis/alexa-inputcontroller.html
This commit is contained in:
parent
7d6ef4445e
commit
766875f702
@ -357,6 +357,11 @@ class _AlexaPlaybackController(_AlexaInterface):
|
||||
return 'Alexa.PlaybackController'
|
||||
|
||||
|
||||
class _AlexaInputController(_AlexaInterface):
|
||||
def name(self):
|
||||
return 'Alexa.InputController'
|
||||
|
||||
|
||||
class _AlexaTemperatureSensor(_AlexaInterface):
|
||||
def name(self):
|
||||
return 'Alexa.TemperatureSensor'
|
||||
@ -475,6 +480,9 @@ class _MediaPlayerCapabilities(_AlexaEntity):
|
||||
if supported & playback_features:
|
||||
yield _AlexaPlaybackController(self.entity)
|
||||
|
||||
if supported & media_player.SUPPORT_SELECT_SOURCE:
|
||||
yield _AlexaInputController(self.entity)
|
||||
|
||||
|
||||
@ENTITY_ADAPTERS.register(scene.DOMAIN)
|
||||
class _SceneCapabilities(_AlexaEntity):
|
||||
@ -1081,6 +1089,41 @@ def async_api_set_volume(hass, config, request, entity):
|
||||
return api_message(request)
|
||||
|
||||
|
||||
@HANDLERS.register(('Alexa.InputController', 'SelectInput'))
|
||||
@extract_entity
|
||||
@asyncio.coroutine
|
||||
def async_api_select_input(hass, config, request, entity):
|
||||
"""Process a set input request."""
|
||||
media_input = request[API_PAYLOAD]['input']
|
||||
|
||||
# attempt to map the ALL UPPERCASE payload name to a source
|
||||
source_list = entity.attributes[media_player.ATTR_INPUT_SOURCE_LIST] or []
|
||||
for source in source_list:
|
||||
# response will always be space separated, so format the source in the
|
||||
# most likely way to find a match
|
||||
formatted_source = source.lower().replace('-', ' ').replace('_', ' ')
|
||||
if formatted_source in media_input.lower():
|
||||
media_input = source
|
||||
break
|
||||
else:
|
||||
msg = 'failed to map input {} to a media source on {}'.format(
|
||||
media_input, entity.entity_id)
|
||||
_LOGGER.error(msg)
|
||||
return api_error(
|
||||
request, error_type='INVALID_VALUE', error_message=msg)
|
||||
|
||||
data = {
|
||||
ATTR_ENTITY_ID: entity.entity_id,
|
||||
media_player.ATTR_INPUT_SOURCE: media_input,
|
||||
}
|
||||
|
||||
yield from hass.services.async_call(
|
||||
entity.domain, media_player.SERVICE_SELECT_SOURCE,
|
||||
data, blocking=False)
|
||||
|
||||
return api_message(request)
|
||||
|
||||
|
||||
@HANDLERS.register(('Alexa.Speaker', 'AdjustVolume'))
|
||||
@extract_entity
|
||||
@asyncio.coroutine
|
||||
|
@ -1161,6 +1161,52 @@ def test_api_set_volume(hass):
|
||||
assert msg['header']['name'] == 'Response'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
@pytest.mark.parametrize(
|
||||
"domain,payload,source_list,idx", [
|
||||
('media_player', 'GAME CONSOLE', ['tv', 'game console'], 1),
|
||||
('media_player', 'SATELLITE TV', ['satellite-tv', 'game console'], 0),
|
||||
('media_player', 'SATELLITE TV', ['satellite_tv', 'game console'], 0),
|
||||
('media_player', 'BAD DEVICE', ['satellite_tv', 'game console'], None),
|
||||
]
|
||||
)
|
||||
def test_api_select_input(hass, domain, payload, source_list, idx):
|
||||
"""Test api set input process."""
|
||||
request = get_new_request(
|
||||
'Alexa.InputController', 'SelectInput', 'media_player#test')
|
||||
|
||||
# add payload
|
||||
request['directive']['payload']['input'] = payload
|
||||
|
||||
# setup test devices
|
||||
hass.states.async_set(
|
||||
'media_player.test', 'off', {
|
||||
'friendly_name': "Test media player",
|
||||
'source': 'unknown',
|
||||
'source_list': source_list,
|
||||
})
|
||||
|
||||
call_media_player = async_mock_service(hass, domain, 'select_source')
|
||||
|
||||
msg = yield from smart_home.async_handle_message(
|
||||
hass, DEFAULT_CONFIG, request)
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert 'event' in msg
|
||||
msg = msg['event']
|
||||
|
||||
# test where no source matches
|
||||
if idx is None:
|
||||
assert len(call_media_player) == 0
|
||||
assert msg['header']['name'] == 'ErrorResponse'
|
||||
return
|
||||
|
||||
assert len(call_media_player) == 1
|
||||
assert call_media_player[0].data['entity_id'] == 'media_player.test'
|
||||
assert call_media_player[0].data['source'] == source_list[idx]
|
||||
assert msg['header']['name'] == 'Response'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
@pytest.mark.parametrize(
|
||||
"result,adjust", [(0.7, '-5'), (0.8, '5'), (0, '-80')])
|
||||
|
Loading…
x
Reference in New Issue
Block a user