mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Universal source list (#4086)
* Add source_list to universal media player * Expanded attirubte and command support for UMP Added support to the universal media player for the following: Volume Set Current Source Set Source Current Volume The goal is to facilitate a single-card media player that includes source selection and setting the volume of the receiver. Example setup: ``` media_player: - platform: universal name: Media Center children: - media_player.kodi - media_player.cast commands: select_source: service: media_player.select_source data: entity_id: media_player.receiver volume_set: service: media_player.volume_set data: entity_id: media_player.receiver volume_mute: service: media_player.volume_mute data: entity_id: media_player.receiver turn_on: service: homeassistant.turn_on data: entity_id: media_player.receiver turn_off: service: homeassistant.turn_off data: entity_id: media_player.receiver attributes: state: media_player.receiver is_volume_muted: media_player.receiver|is_volume_muted volume_level: media_player.receiver|volume_level source: media_player.receiver|source source_list: media_player.receiver|source_list ``` * Remove print statements * Change service call back to use call_from_config * Modified service calls to use template data * linting fixes * Add tests * linting fices * More pylinting
This commit is contained in:
parent
7746ecd98e
commit
a099430834
@ -14,7 +14,7 @@ from homeassistant.components.media_player import (
|
||||
ATTR_MEDIA_CONTENT_TYPE, ATTR_MEDIA_DURATION, ATTR_MEDIA_EPISODE,
|
||||
ATTR_MEDIA_PLAYLIST, ATTR_MEDIA_SEASON, ATTR_MEDIA_SEEK_POSITION,
|
||||
ATTR_MEDIA_SERIES_TITLE, ATTR_MEDIA_TITLE, ATTR_MEDIA_TRACK,
|
||||
ATTR_MEDIA_VOLUME_LEVEL, ATTR_MEDIA_VOLUME_MUTED,
|
||||
ATTR_MEDIA_VOLUME_LEVEL, ATTR_MEDIA_VOLUME_MUTED, ATTR_INPUT_SOURCE_LIST,
|
||||
ATTR_SUPPORTED_MEDIA_COMMANDS, DOMAIN, SERVICE_PLAY_MEDIA,
|
||||
SUPPORT_TURN_OFF, SUPPORT_TURN_ON, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET,
|
||||
SUPPORT_VOLUME_STEP, SUPPORT_SELECT_SOURCE, SUPPORT_CLEAR_PLAYLIST,
|
||||
@ -38,6 +38,7 @@ CONF_COMMANDS = 'commands'
|
||||
CONF_PLATFORM = 'platform'
|
||||
CONF_SERVICE = 'service'
|
||||
CONF_SERVICE_DATA = 'service_data'
|
||||
ATTR_DATA = 'data'
|
||||
CONF_STATE = 'state'
|
||||
|
||||
OFF_STATES = [STATE_IDLE, STATE_OFF]
|
||||
@ -178,14 +179,15 @@ class UniversalMediaPlayer(MediaPlayerDevice):
|
||||
def _call_service(self, service_name, service_data=None,
|
||||
allow_override=False):
|
||||
"""Call either a specified or active child's service."""
|
||||
if allow_override and service_name in self._cmds:
|
||||
call_from_config(
|
||||
self.hass, self._cmds[service_name], blocking=True)
|
||||
return
|
||||
|
||||
if service_data is None:
|
||||
service_data = {}
|
||||
|
||||
if allow_override and service_name in self._cmds:
|
||||
call_from_config(
|
||||
self.hass, self._cmds[service_name],
|
||||
variables=service_data, blocking=True)
|
||||
return
|
||||
|
||||
active_child = self._child_state
|
||||
service_data[ATTR_ENTITY_ID] = active_child.entity_id
|
||||
|
||||
@ -233,7 +235,7 @@ class UniversalMediaPlayer(MediaPlayerDevice):
|
||||
@property
|
||||
def volume_level(self):
|
||||
"""Volume level of entity specified in attributes or active child."""
|
||||
return self._child_attr(ATTR_MEDIA_VOLUME_LEVEL)
|
||||
return self._override_or_child_attr(ATTR_MEDIA_VOLUME_LEVEL)
|
||||
|
||||
@property
|
||||
def is_volume_muted(self):
|
||||
@ -322,9 +324,14 @@ class UniversalMediaPlayer(MediaPlayerDevice):
|
||||
return self._child_attr(ATTR_APP_NAME)
|
||||
|
||||
@property
|
||||
def current_source(self):
|
||||
def source(self):
|
||||
""""Return the current input source of the device."""
|
||||
return self._child_attr(ATTR_INPUT_SOURCE)
|
||||
return self._override_or_child_attr(ATTR_INPUT_SOURCE)
|
||||
|
||||
@property
|
||||
def source_list(self):
|
||||
"""List of available input sources."""
|
||||
return self._override_or_child_attr(ATTR_INPUT_SOURCE_LIST)
|
||||
|
||||
@property
|
||||
def supported_media_commands(self):
|
||||
@ -340,6 +347,8 @@ class UniversalMediaPlayer(MediaPlayerDevice):
|
||||
SERVICE_VOLUME_DOWN]]):
|
||||
flags |= SUPPORT_VOLUME_STEP
|
||||
flags &= ~SUPPORT_VOLUME_SET
|
||||
elif SERVICE_VOLUME_SET in self._cmds:
|
||||
flags |= SUPPORT_VOLUME_SET
|
||||
|
||||
if SERVICE_VOLUME_MUTE in self._cmds and \
|
||||
ATTR_MEDIA_VOLUME_MUTED in self._attrs:
|
||||
@ -376,7 +385,7 @@ class UniversalMediaPlayer(MediaPlayerDevice):
|
||||
def set_volume_level(self, volume_level):
|
||||
"""Set volume level, range 0..1."""
|
||||
data = {ATTR_MEDIA_VOLUME_LEVEL: volume_level}
|
||||
self._call_service(SERVICE_VOLUME_SET, data)
|
||||
self._call_service(SERVICE_VOLUME_SET, data, allow_override=True)
|
||||
|
||||
def media_play(self):
|
||||
"""Send play commmand."""
|
||||
@ -424,7 +433,7 @@ class UniversalMediaPlayer(MediaPlayerDevice):
|
||||
def select_source(self, source):
|
||||
"""Set the input source."""
|
||||
data = {ATTR_INPUT_SOURCE: source}
|
||||
self._call_service(SERVICE_SELECT_SOURCE, data)
|
||||
self._call_service(SERVICE_SELECT_SOURCE, data, allow_override=True)
|
||||
|
||||
def clear_playlist(self):
|
||||
"""Clear players playlist."""
|
||||
|
@ -5,6 +5,8 @@ import unittest
|
||||
from homeassistant.const import (
|
||||
STATE_OFF, STATE_ON, STATE_UNKNOWN, STATE_PLAYING, STATE_PAUSED)
|
||||
import homeassistant.components.switch as switch
|
||||
import homeassistant.components.input_slider as input_slider
|
||||
import homeassistant.components.input_select as input_select
|
||||
import homeassistant.components.media_player as media_player
|
||||
import homeassistant.components.media_player.universal as universal
|
||||
|
||||
@ -142,6 +144,17 @@ class TestMediaPlayer(unittest.TestCase):
|
||||
self.mock_state_switch_id = switch.ENTITY_ID_FORMAT.format('state')
|
||||
self.hass.states.set(self.mock_state_switch_id, STATE_OFF)
|
||||
|
||||
self.mock_volume_id = input_slider.ENTITY_ID_FORMAT.format(
|
||||
'volume_level')
|
||||
self.hass.states.set(self.mock_volume_id, 0)
|
||||
|
||||
self.mock_source_list_id = input_select.ENTITY_ID_FORMAT.format(
|
||||
'source_list')
|
||||
self.hass.states.set(self.mock_source_list_id, ['dvd', 'htpc'])
|
||||
|
||||
self.mock_source_id = input_select.ENTITY_ID_FORMAT.format('source')
|
||||
self.hass.states.set(self.mock_source_id, 'dvd')
|
||||
|
||||
self.config_children_only = {
|
||||
'name': 'test', 'platform': 'universal',
|
||||
'children': [media_player.ENTITY_ID_FORMAT.format('mock1'),
|
||||
@ -153,6 +166,9 @@ class TestMediaPlayer(unittest.TestCase):
|
||||
media_player.ENTITY_ID_FORMAT.format('mock2')],
|
||||
'attributes': {
|
||||
'is_volume_muted': self.mock_mute_switch_id,
|
||||
'volume_level': self.mock_volume_id,
|
||||
'source': self.mock_source_id,
|
||||
'source_list': self.mock_source_list_id,
|
||||
'state': self.mock_state_switch_id
|
||||
}
|
||||
}
|
||||
@ -405,6 +421,42 @@ class TestMediaPlayer(unittest.TestCase):
|
||||
ump.update()
|
||||
self.assertTrue(ump.is_volume_muted)
|
||||
|
||||
def test_source_list_children_and_attr(self):
|
||||
"""Test source list property w/ children and attrs."""
|
||||
config = self.config_children_and_attr
|
||||
universal.validate_config(config)
|
||||
|
||||
ump = universal.UniversalMediaPlayer(self.hass, **config)
|
||||
|
||||
self.assertEqual("['dvd', 'htpc']", ump.source_list)
|
||||
|
||||
self.hass.states.set(self.mock_source_list_id, ['dvd', 'htpc', 'game'])
|
||||
self.assertEqual("['dvd', 'htpc', 'game']", ump.source_list)
|
||||
|
||||
def test_source_children_and_attr(self):
|
||||
"""Test source property w/ children and attrs."""
|
||||
config = self.config_children_and_attr
|
||||
universal.validate_config(config)
|
||||
|
||||
ump = universal.UniversalMediaPlayer(self.hass, **config)
|
||||
|
||||
self.assertEqual('dvd', ump.source)
|
||||
|
||||
self.hass.states.set(self.mock_source_id, 'htpc')
|
||||
self.assertEqual('htpc', ump.source)
|
||||
|
||||
def test_volume_level_children_and_attr(self):
|
||||
"""Test volume level property w/ children and attrs."""
|
||||
config = self.config_children_and_attr
|
||||
universal.validate_config(config)
|
||||
|
||||
ump = universal.UniversalMediaPlayer(self.hass, **config)
|
||||
|
||||
self.assertEqual('0', ump.volume_level)
|
||||
|
||||
self.hass.states.set(self.mock_volume_id, 100)
|
||||
self.assertEqual('100', ump.volume_level)
|
||||
|
||||
def test_is_volume_muted_children_and_attr(self):
|
||||
"""Test is volume muted property w/ children and attrs."""
|
||||
config = self.config_children_and_attr
|
||||
@ -443,18 +495,20 @@ class TestMediaPlayer(unittest.TestCase):
|
||||
config['commands']['volume_up'] = 'test'
|
||||
config['commands']['volume_down'] = 'test'
|
||||
config['commands']['volume_mute'] = 'test'
|
||||
config['commands']['volume_set'] = 'test'
|
||||
config['commands']['select_source'] = 'test'
|
||||
|
||||
ump = universal.UniversalMediaPlayer(self.hass, **config)
|
||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config['name'])
|
||||
ump.update()
|
||||
|
||||
self.mock_mp_1._supported_media_commands = universal.SUPPORT_VOLUME_SET
|
||||
self.mock_mp_1._state = STATE_PLAYING
|
||||
self.mock_mp_1.update_ha_state()
|
||||
ump.update()
|
||||
|
||||
check_flags = universal.SUPPORT_TURN_ON | universal.SUPPORT_TURN_OFF \
|
||||
| universal.SUPPORT_VOLUME_STEP | universal.SUPPORT_VOLUME_MUTE
|
||||
| universal.SUPPORT_VOLUME_STEP | universal.SUPPORT_VOLUME_MUTE \
|
||||
| universal.SUPPORT_SELECT_SOURCE
|
||||
|
||||
self.assertEqual(check_flags, ump.supported_media_commands)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user