dynamically fetch yamaha media playback support (#4385)

This makes it so that media playback support for inputs is dynamically
fetched from the receiver, instead of assuming that all playback
commands work for all inputs.

Tests are added for this, using a FakeYamaha class, which has some
sample data stubbed in for key methods that need to be called. We also
include an example of the desc.xml needed to dynamically parse these
features for these tests (as this is done in platform init).
This commit is contained in:
Sean Dague 2016-11-16 00:56:40 -05:00 committed by Paulus Schoutsen
parent 2b86d89bb4
commit c06c82905a
4 changed files with 3541 additions and 10 deletions

View File

@ -18,17 +18,12 @@ from homeassistant.const import (CONF_NAME, CONF_HOST, STATE_OFF, STATE_ON,
STATE_PLAYING, STATE_IDLE)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['rxv==0.3.1']
REQUIREMENTS = ['rxv==0.4.0']
_LOGGER = logging.getLogger(__name__)
SUPPORT_YAMAHA = SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | \
SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_SELECT_SOURCE | \
SUPPORT_PLAY_MEDIA
# Only supported by some sources
SUPPORT_PLAYBACK = SUPPORT_PLAY_MEDIA | SUPPORT_PAUSE | SUPPORT_STOP | \
SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK
SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_SELECT_SOURCE
CONF_SOURCE_NAMES = 'source_names'
CONF_SOURCE_IGNORE = 'source_ignore'
@ -187,8 +182,16 @@ class YamahaDevice(MediaPlayerDevice):
def supported_media_commands(self):
"""Flag of media commands that are supported."""
supported_commands = SUPPORT_YAMAHA
if self._is_playback_supported:
supported_commands |= SUPPORT_PLAYBACK
supports = self._receiver.get_playback_support()
mapping = {'play': SUPPORT_PLAY_MEDIA,
'pause': SUPPORT_PAUSE,
'stop': SUPPORT_STOP,
'skip_f': SUPPORT_NEXT_TRACK,
'skip_r': SUPPORT_PREVIOUS_TRACK}
for attr, feature in mapping.items():
if getattr(supports, attr, False):
supported_commands |= feature
return supported_commands
def turn_off(self):

View File

@ -465,7 +465,7 @@ radiotherm==1.2
# rpi-rf==0.9.5
# homeassistant.components.media_player.yamaha
rxv==0.3.1
rxv==0.4.0
# homeassistant.components.media_player.samsungtv
samsungctl==0.5.1

View File

@ -0,0 +1,87 @@
"""The tests for the Yamaha Media player platform."""
import unittest
import xml.etree.ElementTree as ET
import rxv
def sample_content(name):
"""Read content into a string from a file."""
with open('tests/components/media_player/yamaha_samples/%s' % name,
encoding='utf-8') as f:
return f.read()
class FakeYamaha(rxv.rxv.RXV):
"""Fake Yamaha receiver.
This inherits from RXV but overrides methods for testing that
would normally have hit the network. This makes it easier to
ensure that usage of the rxv library by HomeAssistant is as we'd
expect.
"""
_fake_input = "HDMI1"
def _discover_features(self):
self._desc_xml = ET.fromstring(sample_content("desc.xml"))
@property
def input(self):
return self._fake_input
@input.setter
def input(self, input_name):
assert input_name in self.inputs()
self._fake_input = input_name
def inputs(self):
return {'AUDIO1': None,
'AUDIO2': None,
'AV1': None,
'AV2': None,
'AV3': None,
'AV4': None,
'AV5': None,
'AV6': None,
'AirPlay': 'AirPlay',
'HDMI1': None,
'HDMI2': None,
'HDMI3': None,
'HDMI4': None,
'HDMI5': None,
'NET RADIO': 'NET_RADIO',
'Pandora': 'Pandora',
'Rhapsody': 'Rhapsody',
'SERVER': 'SERVER',
'SiriusXM': 'SiriusXM',
'Spotify': 'Spotify',
'TUNER': 'Tuner',
'USB': 'USB',
'V-AUX': None,
'iPod (USB)': 'iPod_USB'}
class TestYamaha(unittest.TestCase):
"""Test the media_player yamaha module."""
def setUp(self): # pylint: disable=invalid-name
"""Setup things to be run when tests are started."""
super(TestYamaha, self).setUp()
self.rec = FakeYamaha('10.0.0.0')
def test_get_playback_support(self):
rec = self.rec
support = rec.get_playback_support()
self.assertFalse(support.play)
self.assertFalse(support.pause)
self.assertFalse(support.stop)
self.assertFalse(support.skip_f)
self.assertFalse(support.skip_r)
rec.input = "NET RADIO"
support = rec.get_playback_support()
self.assertTrue(support.play)
self.assertFalse(support.pause)
self.assertTrue(support.stop)
self.assertFalse(support.skip_f)
self.assertFalse(support.skip_r)

File diff suppressed because it is too large Load Diff