From c06c82905ae50aca256917019e5447db84fdd144 Mon Sep 17 00:00:00 2001 From: Sean Dague Date: Wed, 16 Nov 2016 00:56:40 -0500 Subject: [PATCH] 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). --- .../components/media_player/yamaha.py | 21 +- requirements_all.txt | 2 +- tests/components/media_player/test_yamaha.py | 87 + .../media_player/yamaha_samples/desc.xml | 3441 +++++++++++++++++ 4 files changed, 3541 insertions(+), 10 deletions(-) create mode 100644 tests/components/media_player/test_yamaha.py create mode 100644 tests/components/media_player/yamaha_samples/desc.xml diff --git a/homeassistant/components/media_player/yamaha.py b/homeassistant/components/media_player/yamaha.py index 0e265199fce..68c491d7a24 100644 --- a/homeassistant/components/media_player/yamaha.py +++ b/homeassistant/components/media_player/yamaha.py @@ -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): diff --git a/requirements_all.txt b/requirements_all.txt index bf8f5a24c4b..13b8c7bfb70 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -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 diff --git a/tests/components/media_player/test_yamaha.py b/tests/components/media_player/test_yamaha.py new file mode 100644 index 00000000000..de31096e2b8 --- /dev/null +++ b/tests/components/media_player/test_yamaha.py @@ -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) diff --git a/tests/components/media_player/yamaha_samples/desc.xml b/tests/components/media_player/yamaha_samples/desc.xml new file mode 100644 index 00000000000..d403fade5f7 --- /dev/null +++ b/tests/components/media_player/yamaha_samples/desc.xml @@ -0,0 +1,3441 @@ + + + Title_1 + + + On + Off + + Param_1 + + On + Off + + + + + + + Param_1 + + Available + Unavailable + + + + + + + Param_1 + + 1,15,UTF-8 + + + + Param_1 + + 1,15,UTF-8 + + + + + + On + Standby + + + On + Off + + Param_1 + + On + Off + + + + + + Disable + Enable + + Param_1 + + Disable + Enable + + + + + System,Misc,Event,Notice + System,Power_Control,Power + System,Misc,Network,Network_Name + System,Misc,Network,Network_Standby + System,Misc,Network,DMC_Control + System,Misc,Event,Notice + System,Misc,Network,Network_Name + System,Misc,Network,Network_Standby + System,Misc,Update,Yamaha_Network_Site,Status + System,Misc,Network,DMC_Control + + + + + + Param_1 + + 1,9,Latin-1 + + + + Name,Zone=Param_1 + + 1,9,Latin-1 + + + + + + + Param_1 + + + + + + Input,Input_Sel=Param_1 + + + + + + + + Param_1 + + + + + + Input,Input_Sel=Param_1 + + + + + + + + + + Val=Param_1:Exp=Param_2:Unit=Param_3 + + -805,165,5 + + + 1 + + + dB + + + + Volume,Lvl,Val=Param_1:Volume,Lvl,Exp=Param_2:Volume,Lvl,Unit=Param_3 + + -805,165,5 + + + 1 + + + dB + + + + + On + Off + + Volume,Mute=Param_1 + + On + Off + + + + + + + On + Standby + + Power_Control,Power=Param_1 + + On + Standby + + + + + Last + 120 min + 90 min + 60 min + 30 min + Off + + Power_Control,Sleep=Param_1 + + 120 min + 90 min + 60 min + 30 min + Off + + + + + + + Play + Pause + Stop + + + Skip Fwd + Skip Rev + + + + + Up + Down + Left + Right + Return + Sel + Return to Home + On Screen + Top Menu + Menu + Option + Display + + + + + + + Param_1 + + Hall in Munich + Hall in Vienna + Chamber + Cellar Club + The Roxy Theatre + The Bottom Line + Sports + Action Game + Roleplaying Game + Music Video + Standard + Spectacle + Sci-Fi + Adventure + Drama + Mono Movie + Surround Decoder + 2ch Stereo + 7ch Stereo + + + + Surround,Program_Sel,Current,Sound_Program=Param_1 + + Hall in Munich + Hall in Vienna + Chamber + Cellar Club + The Roxy Theatre + The Bottom Line + Sports + Action Game + Roleplaying Game + Music Video + Standard + Spectacle + Sci-Fi + Adventure + Drama + Mono Movie + Surround Decoder + 2ch Stereo + 7ch Stereo + + + + + On + Off + + Surround,Program_Sel,Current,Straight=Param_1 + + On + Off + + + + + On + Off + + Surround,Program_Sel,Current,Enhancer=Param_1 + + On + Off + + + + + + + + Val=Param_1:Exp=Param_2:Unit=Param_3 + + -60,60,5 + + + 1 + + + dB + + + + Sound_Video,Tone,Bass,Val=Param_1:Sound_Video,Tone,Bass,Exp=Param_2:Sound_Video,Tone,Bass,Unit=Param_3 + + -60,60,5 + + + 1 + + + dB + + + + + + Val=Param_1:Exp=Param_2:Unit=Param_3 + + -60,60,5 + + + 1 + + + dB + + + + Sound_Video,Tone,Treble,Val=Param_1:Sound_Video,Tone,Treble,Exp=Param_2:Sound_Video,Tone,Treble,Unit=Param_3 + + -60,60,5 + + + 1 + + + dB + + + + + + + Val=Param_1:Exp=Param_2:Unit=Param_3 + + -60,60,5 + + + 1 + + + dB + + + + Volume,Subwoofer_Trim,Val=Param_1:Volume,Subwoofer_Trim,Exp=Param_2:Volume,Subwoofer_Trim,Unit=Param_3 + + -60,60,5 + + + 1 + + + dB + + + + + Auto + Off + + Sound_Video,Adaptive_DRC=Param_1 + + Auto + Off + + + + + Auto + Off + + Surround,_3D_Cinema_DSP=Param_1 + + Auto + Off + + + + + + Param_1 + + 0,5,1 + + + + Sound_Video,Dialogue_Adjust,Dialogue_Lift=Param_1 + + 0,5,1 + + + + + + Param_1 + + 0,3,1 + + + + Sound_Video,Dialogue_Adjust,Dialogue_Lvl=Param_1 + + 0,3,1 + + + + + On + Off + + Sound_Video,Pure_Direct,Mode=Param_1 + + On + Off + + + + + + Sound_Video,HDMI,Standby_Through_Info=Param_1 + + On + Off + + + + + + Main_Zone,Power_Control,Power + Main_Zone,Volume,Lvl + Main_Zone,Volume,Mute + Main_Zone,Input,Input_Sel + Main_Zone,Config,Name,Zone + Main_Zone,Scene,Scene_Sel + Main_Zone,Sound_Video,Tone,Bass + Main_Zone,Sound_Video,Tone,Treble + Main_Zone,Surround,Program_Sel,Current,Sound_Program + Main_Zone,Surround,Program_Sel,Current,Straight + Main_Zone,Surround,Program_Sel,Current,Enhancer + Main_Zone,Sound_Video,Adaptive_DRC + Main_Zone,Surround,_3D_Cinema_DSP + Main_Zone,Sound_Video,Dialogue_Adjust,Dialogue_Lift + System,Sound_Video,HDMI,Video,Preset_Sel,Current + Main_Zone,Sound_Video,Pure_Direct,Mode + Main_Zone,Cursor_Control,Cursor + Main_Zone,Cursor_Control,Menu_Control + Main_Zone,Surround,Enhancer_Type + Main_Zone,Sound_Video,Dialogue_Adjust,Dialogue_Lvl + Main_Zone,Volume,Subwoofer_Trim + Main_Zone,Power_Control,Sleep + Main_Zone,Play_Control,Playback + Main_Zone,Basic_Status + Main_Zone,Input,Input_Sel_Item + Main_Zone,Config + Main_Zone,Scene,Scene_Sel_Item + + + + + + Param_1 + + 1,9,Latin-1 + + + + Name,Zone=Param_1 + + 1,9,Latin-1 + + + + + + Param_1 + + + + + + Input,Input_Sel=Param_1 + + + + + + + + + Val=Param_1:Exp=Param_2:Unit=Param_3 + + -805,165,5 + + + 1 + + + dB + + + + Volume,Lvl,Val=Param_1:Volume,Lvl,Exp=Param_2:Volume,Lvl,Unit=Param_3 + + -805,165,5 + + + 1 + + + dB + + + + + On + Off + + Volume,Mute=Param_1 + + On + Off + + + + + + Volume,Output_Info=Param_1 + + Fixed + Variable + + + + + + + On + Standby + + Power_Control,Power=Param_1 + + On + Standby + + + + + Last + 120 min + 90 min + 60 min + 30 min + Off + + Power_Control,Sleep=Param_1 + + 120 min + 90 min + 60 min + 30 min + Off + + + + + + + Play + Pause + Stop + + + Skip Fwd + Skip Rev + + + + Zone_2,Power_Control,Power + Zone_2,Volume,Lvl + Zone_2,Volume,Mute + Zone_2,Input,Input_Sel + Zone_2,Config,Name,Zone + Zone_2,Scene,Scene_Sel + Zone_2,Sound_Video,Tone,Bass + Zone_2,Sound_Video,Tone,Treble + Zone_2,Cursor_Control,Cursor + Zone_2,Cursor_Control,Menu_Control + Zone_2,Volume,Output + Zone_2,Power_Control,Sleep + Zone_2,Play_Control,Playback + Zone_2,Basic_Status + Zone_2,Input,Input_Sel_Item + Zone_2,Config + Zone_2,Scene,Scene_Sel_Item + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + + Auto Up + Auto Down + Cancel + + Tuning,Freq,AM,Val=Param_1:Tuning,Freq,AM,Exp=Param_2:Tuning,Freq,AM,Unit=Param_3 + + 530,1710,10 + Auto Up + Auto Down + + + 0 + + + + + kHz + + + + + + + Auto Up + Auto Down + Cancel + + Tuning,Freq,FM,Val=Param_1:Tuning,Freq,FM,Exp=Param_2:Tuning,Freq,FM,Unit=Param_3 + + 8750,10790,20 + Auto Up + Auto Down + + + 2 + + + + + MHz + + + + + + + Up + Down + + Preset,Preset_Sel=Param_1 + + + + + + + + AM + FM + + Tuning,Band=Param_1 + + AM + FM + + + + + + + Val=Param_1:Exp=Param_2:Unit=Param_3 + + 530,1710,10 + + + 0 + + + kHz + + + + Tuning,Freq,AM,Val=Param_1:Tuning,Freq,AM,Exp=Param_2:Tuning,Freq,AM,Unit=Param_3 + + 530,1710,10 + Auto Up + Auto Down + + + 0 + + + + + kHz + + + + + + + + Val=Param_1:Exp=Param_2:Unit=Param_3 + + 8750,10790,20 + + + 2 + + + MHz + + + + Tuning,Freq,FM,Val=Param_1:Tuning,Freq,FM,Exp=Param_2:Tuning,Freq,FM,Unit=Param_3 + + 8750,10790,20 + Auto Up + Auto Down + + + 2 + + + + + MHz + + + + + + + + + Param_1 + + + + + + Preset,Preset_Sel=Param_1 + + + + + + + + + + Tuning,Band=Param_1 + + AM + FM + + + + + + Tuning,Freq,Current,Val=Param_1:Tuning,Freq,Current,Exp=Param_2:Tuning,Freq,Current,Unit=Param_3 + + 530,1710,10 + 8750,10790,20 + Auto Up + Auto Down + + + 0 + 2 + + + + + kHz + MHz + + + + + + + + + Signal_Info,Tuned=Param_1 + + Negate + Assert + + + + + + Signal_Info,Stereo=Param_1 + + Negate + Assert + + + + + + + Tuner,Play_Control,Search_Mode + Tuner,Play_Control,Preset,Preset_Sel + Tuner,Play_Control,Tuning,Band + Tuner,Play_Control,Tuning,Freq,FM + Tuner,Play_Control,Tuning,Freq,AM + Tuner,Play_Control,Tuning,Freq,FM,Val + Tuner,Play_Control,Tuning,Freq,AM,Val + Tuner,Play_Info + Tuner,Config + Tuner,Play_Control,Preset,Preset_Sel_Item + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Play + Pause + + Playback_Info=Param_1 + + Play + Stop + + + + + Skip Fwd + Skip Rev + + + + + + Meta_Info,Artist=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Album=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Song=Param_1 + + 0,128,UTF-8 + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Playback_Info=Param_1 + + Play + Stop + + + + + + Album_ART,URL=Param_1 + + 0,128,UTF-8 + + + + + + Album_ART,ID=Param_1 + + 0,255,1 + + + + + + Album_ART,Format=Param_1 + + BMP + YMF + + + + + + Input_Logo,URL_S=Param_1 + + 0,128,UTF-8 + + + + + + AirPlay,Play_Control,Playback + AirPlay,Play_Info + AirPlay,Config + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Play + Pause + + Playback_Info=Param_1 + + Play + Pause + Stop + + + + + Skip Fwd + Skip Rev + + + + + + Meta_Info,Artist=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Album=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Track=Param_1 + + 0,128,UTF-8 + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Playback_Info=Param_1 + + Play + Pause + Stop + + + + + + Input_Logo,URL_S=Param_1 + + 0,128,UTF-8 + + + + + + Spotify,Play_Control,Playback + Spotify,Play_Control,Play_Mode,Repeat + Spotify,Play_Control,Play_Mode,Shuffle + Spotify,Play_Info + Spotify,Config + + + + + Extended + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Off + One + All + + Play_Mode,Repeat=Param_1 + + Off + One + All + + + + + Off + Songs + Albums + + Play_Mode,Shuffle=Param_1 + + Off + Songs + Albums + + + + + Play + Pause + Stop + + Playback_Info=Param_1 + + Play + Pause + Stop + + + + + Skip Fwd + Skip Rev + + + + + + Meta_Info,Artist=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Album=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Song=Param_1 + + 0,128,UTF-8 + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Playback_Info=Param_1 + + Play + Pause + Stop + + + + + + Play_Mode,Repeat=Param_1 + + Off + One + All + + + + + + Play_Mode,Shuffle=Param_1 + + Off + Songs + Albums + + + + + + Album_ART,URL=Param_1 + + 0,128,UTF-8 + + + + + + Album_ART,ID=Param_1 + + 0,255,1 + + + + + + Album_ART,Format=Param_1 + + BMP + YMF + + + + + + + + + Param_1 + + 1,8,1,Line_% + + + + + Up + Down + Return + Sel + Return to Home + + + + Param_1 + + 1,65536,1 + + + + + Up + Down + + + + + + Menu_Status=Param_1 + + Ready + Busy + + + + + + Menu_Layer=Param_1 + + 1,16,1 + + + + + + Menu_Name=Param_1 + + 0,128,UTF-8 + + + + + + Line_1 + + Current_List,Line_1,Txt=Param_1:Current_List,Line_1,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_2 + + Current_List,Line_2,Txt=Param_1:Current_List,Line_2,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_3 + + Current_List,Line_3,Txt=Param_1:Current_List,Line_3,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_4 + + Current_List,Line_4,Txt=Param_1:Current_List,Line_4,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_5 + + Current_List,Line_5,Txt=Param_1:Current_List,Line_5,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_6 + + Current_List,Line_6,Txt=Param_1:Current_List,Line_6,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_7 + + Current_List,Line_7,Txt=Param_1:Current_List,Line_7,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_8 + + Current_List,Line_8,Txt=Param_1:Current_List,Line_8,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + + + Cursor_Position,Current_Line=Param_1 + + 1,65536,1 + + + + + + Cursor_Position,Max_Line=Param_1 + + 0,65536,1 + + + + + + + iPod_USB,Play_Control,Playback + iPod_USB,List_Control,Direct_Sel + iPod_USB,List_Control,Jump_Line + iPod_USB,List_Control,Cursor + iPod_USB,List_Control,Page + iPod_USB,Play_Control,Play_Mode,Repeat + iPod_USB,Play_Control,Play_Mode,Shuffle + iPod_USB,Play_Control,iPod_Mode + iPod_USB,Play_Info + iPod_USB,List_Info + iPod_USB,Config + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Off + One + All + + Play_Mode,Repeat=Param_1 + + Off + One + All + + + + + Off + On + + Play_Mode,Shuffle=Param_1 + + Off + On + + + + + Play + Pause + Stop + + Playback_Info=Param_1 + + Play + Pause + Stop + + + + + Skip Fwd + Skip Rev + + + + + + Meta_Info,Artist=Param_1 + + 0,64,UTF-8 + + + + + + Meta_Info,Album=Param_1 + + 0,64,UTF-8 + + + + + + Meta_Info,Song=Param_1 + + 0,64,UTF-8 + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Playback_Info=Param_1 + + Play + Pause + Stop + + + + + + Play_Mode,Repeat=Param_1 + + Off + One + All + + + + + + Play_Mode,Shuffle=Param_1 + + Off + On + + + + + + Album_ART,URL=Param_1 + + 0,128,UTF-8 + + + + + + Album_ART,ID=Param_1 + + 0,255,1 + + + + + + Album_ART,Format=Param_1 + + BMP + YMF + + + + + + + + + Param_1 + + 1,8,1,Line_% + + + + + Up + Down + Return + Sel + Return to Home + + + + Param_1 + + 1,65536,1 + + + + + Up + Down + + + + + + Menu_Status=Param_1 + + Ready + Busy + + + + + + Menu_Layer=Param_1 + + 1,16,1 + + + + + + Menu_Name=Param_1 + + 0,128,UTF-8 + + + + + + Line_1 + + Current_List,Line_1,Txt=Param_1:Current_List,Line_1,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_2 + + Current_List,Line_2,Txt=Param_1:Current_List,Line_2,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_3 + + Current_List,Line_3,Txt=Param_1:Current_List,Line_3,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_4 + + Current_List,Line_4,Txt=Param_1:Current_List,Line_4,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_5 + + Current_List,Line_5,Txt=Param_1:Current_List,Line_5,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_6 + + Current_List,Line_6,Txt=Param_1:Current_List,Line_6,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_7 + + Current_List,Line_7,Txt=Param_1:Current_List,Line_7,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_8 + + Current_List,Line_8,Txt=Param_1:Current_List,Line_8,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + + + Cursor_Position,Current_Line=Param_1 + + 1,65536,1 + + + + + + Cursor_Position,Max_Line=Param_1 + + 0,65536,1 + + + + + + + USB,Play_Control,Play_Mode,Repeat + USB,Play_Control,Play_Mode,Shuffle + USB,Play_Control,Playback + USB,Play_Control,Preset,Preset_Sel + USB,List_Control,Direct_Sel + USB,List_Control,Jump_Line + USB,List_Control,Cursor + USB,List_Control,Page + USB,Play_Info + USB,List_Info + USB,Config + USB,Play_Control,Preset,Preset_Sel_Item + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Play + Stop + + Playback_Info=Param_1 + + Play + Stop + + + + + + + + Meta_Info,Station=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Album=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Song=Param_1 + + 0,128,UTF-8 + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Playback_Info=Param_1 + + Play + Stop + + + + + + Album_ART,URL=Param_1 + + 0,128,UTF-8 + + + + + + Album_ART,ID=Param_1 + + 0,255,1 + + + + + + Album_ART,Format=Param_1 + + BMP + YMF + + + + + + + + + Param_1 + + 1,8,1,Line_% + + + + + Up + Down + Return + Sel + Return to Home + + + + Param_1 + + 1,65536,1 + + + + + Up + Down + + + + + + Menu_Status=Param_1 + + Ready + Busy + + + + + + Menu_Layer=Param_1 + + 1,16,1 + + + + + + Menu_Name=Param_1 + + 0,128,UTF-8 + + + + + + Line_1 + + Current_List,Line_1,Txt=Param_1:Current_List,Line_1,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_2 + + Current_List,Line_2,Txt=Param_1:Current_List,Line_2,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_3 + + Current_List,Line_3,Txt=Param_1:Current_List,Line_3,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_4 + + Current_List,Line_4,Txt=Param_1:Current_List,Line_4,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_5 + + Current_List,Line_5,Txt=Param_1:Current_List,Line_5,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_6 + + Current_List,Line_6,Txt=Param_1:Current_List,Line_6,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_7 + + Current_List,Line_7,Txt=Param_1:Current_List,Line_7,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_8 + + Current_List,Line_8,Txt=Param_1:Current_List,Line_8,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + + + Cursor_Position,Current_Line=Param_1 + + 1,65536,1 + + + + + + Cursor_Position,Max_Line=Param_1 + + 0,65536,1 + + + + + + + NET_RADIO,Play_Control,Playback + NET_RADIO,List_Control,Direct_Sel + NET_RADIO,List_Control,Jump_Line + NET_RADIO,List_Control,Cursor + NET_RADIO,List_Control,Page + NET_RADIO,Play_Control,Preset,Preset_Sel + NET_RADIO,List_Control,Bookmark + NET_RADIO,Play_Info + NET_RADIO,List_Info + NET_RADIO,Config + NET_RADIO,Play_Control,Preset,Preset_Sel_Item + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Off + One + All + + Play_Mode,Repeat=Param_1 + + Off + One + All + + + + + Off + On + + Play_Mode,Shuffle=Param_1 + + Off + On + + + + + Play + Pause + Stop + + Playback_Info=Param_1 + + Play + Pause + Stop + + + + + Skip Fwd + Skip Rev + + + + + + Meta_Info,Artist=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Album=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Song=Param_1 + + 0,128,UTF-8 + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Playback_Info=Param_1 + + Play + Pause + Stop + + + + + + Play_Mode,Repeat=Param_1 + + Off + One + All + + + + + + Play_Mode,Shuffle=Param_1 + + Off + On + + + + + + Album_ART,URL=Param_1 + + 0,128,UTF-8 + + + + + + Album_ART,ID=Param_1 + + 0,255,1 + + + + + + Album_ART,Format=Param_1 + + BMP + YMF + + + + + + + + + Param_1 + + 1,8,1,Line_% + + + + + Up + Down + Return + Sel + Return to Home + + + + Param_1 + + 1,65536,1 + + + + + Up + Down + + + + + + Menu_Status=Param_1 + + Ready + Busy + + + + + + Menu_Layer=Param_1 + + 1,16,1 + + + + + + Menu_Name=Param_1 + + 0,128,UTF-8 + + + + + + Line_1 + + Current_List,Line_1,Txt=Param_1:Current_List,Line_1,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_2 + + Current_List,Line_2,Txt=Param_1:Current_List,Line_2,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_3 + + Current_List,Line_3,Txt=Param_1:Current_List,Line_3,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_4 + + Current_List,Line_4,Txt=Param_1:Current_List,Line_4,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_5 + + Current_List,Line_5,Txt=Param_1:Current_List,Line_5,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_6 + + Current_List,Line_6,Txt=Param_1:Current_List,Line_6,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_7 + + Current_List,Line_7,Txt=Param_1:Current_List,Line_7,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_8 + + Current_List,Line_8,Txt=Param_1:Current_List,Line_8,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + + + Cursor_Position,Current_Line=Param_1 + + 1,65536,1 + + + + + + Cursor_Position,Max_Line=Param_1 + + 0,65536,1 + + + + + + + SERVER,Play_Control,Play_Mode,Repeat + SERVER,Play_Control,Play_Mode,Shuffle + SERVER,Play_Control,Playback + SERVER,Play_Control,Preset,Preset_Sel + SERVER,List_Control,Direct_Sel + SERVER,List_Control,Jump_Line + SERVER,List_Control,Cursor + SERVER,List_Control,Page + SERVER,Play_Control,Play_URI + SERVER,Play_Info + SERVER,List_Info + SERVER,Config + SERVER,Play_Control,Preset,Preset_Sel_Item + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Off + One + All + + Play_Mode,Repeat=Param_1 + + Off + One + All + + + + + Off + On + + Play_Mode,Shuffle=Param_1 + + Off + On + + + + + Play + Pause + Stop + + Playback_Info=Param_1 + + Play + Pause + Stop + + + + + Skip Fwd + Skip Rev + + + + + + Meta_Info,Artist=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Album=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Song=Param_1 + + 0,128,UTF-8 + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Playback_Info=Param_1 + + Play + Pause + Stop + + + + + + Play_Mode,Repeat=Param_1 + + Off + One + All + + + + + + Play_Mode,Shuffle=Param_1 + + Off + On + + + + + + Album_ART,URL=Param_1 + + 0,128,UTF-8 + + + + + + Album_ART,ID=Param_1 + + 0,255,1 + + + + + + Album_ART,Format=Param_1 + + BMP + YMF + + + + + + Input_Logo,URL_S=Param_1 + + 0,128,UTF-8 + + + + + + + + + Param_1 + + 1,8,1,Line_% + + + + + + Line=Param_1:Keyword=Param_2 + + 1,8,1,Line_% + + + 0,30,Ascii + + + + + Up + Down + Return + Sel + Return to Home + + + + Param_1 + + 1,65536,1 + + + + + Up + Down + + + + + + Menu_Status=Param_1 + + Ready + Busy + + + + + + Menu_Layer=Param_1 + + 1,16,1 + + + + + + Menu_Name=Param_1 + + 0,128,UTF-8 + + + + + + Line_1 + + Current_List,Line_1,Txt=Param_1:Current_List,Line_1,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + Keyword + + + + + Line_2 + + Current_List,Line_2,Txt=Param_1:Current_List,Line_2,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + Keyword + + + + + Line_3 + + Current_List,Line_3,Txt=Param_1:Current_List,Line_3,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + Keyword + + + + + Line_4 + + Current_List,Line_4,Txt=Param_1:Current_List,Line_4,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + Keyword + + + + + Line_5 + + Current_List,Line_5,Txt=Param_1:Current_List,Line_5,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + Keyword + + + + + Line_6 + + Current_List,Line_6,Txt=Param_1:Current_List,Line_6,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + Keyword + + + + + Line_7 + + Current_List,Line_7,Txt=Param_1:Current_List,Line_7,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + Keyword + + + + + Line_8 + + Current_List,Line_8,Txt=Param_1:Current_List,Line_8,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + Keyword + + + + + + + Cursor_Position,Current_Line=Param_1 + + 1,65536,1 + + + + + + Cursor_Position,Max_Line=Param_1 + + 0,65536,1 + + + + + + + Rhapsody,Play_Control,Play_Mode,Repeat + Rhapsody,Play_Control,Play_Mode,Shuffle + Rhapsody,Play_Control,Playback + Rhapsody,Play_Control,Preset,Preset_Sel + Rhapsody,List_Control,Direct_Sel + Rhapsody,List_Control,Jump_Line + Rhapsody,List_Control,Cursor + Rhapsody,List_Control,Page + Rhapsody,List_Control,Direct_Sel_with_Keyword + Rhapsody,Play_Info + Rhapsody,List_Info + Rhapsody,Config + Rhapsody,Play_Control,Preset,Preset_Sel_Item + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Play + Stop + + Playback_Info=Param_1 + + Play + Stop + + + + + + + + Meta_Info,Ch_Name=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Artist=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Song=Param_1 + + 0,128,UTF-8 + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Playback_Info=Param_1 + + Play + Stop + + + + + + Album_ART,URL=Param_1 + + 0,128,UTF-8 + + + + + + Album_ART,ID=Param_1 + + 0,255,1 + + + + + + Album_ART,Format=Param_1 + + BMP + YMF + + + + + + Input_Logo,URL_S=Param_1 + + 0,128,UTF-8 + + + + + + + + + Param_1 + + 1,8,1,Line_% + + + + + Up + Down + Return + Sel + Return to Home + + + + Param_1 + + 1,65536,1 + + + + + Up + Down + + + + + + Menu_Status=Param_1 + + Ready + Busy + + + + + + Menu_Layer=Param_1 + + 1,16,1 + + + + + + Menu_Name=Param_1 + + 0,128,UTF-8 + + + + + + Line_1 + + Current_List,Line_1,Txt=Param_1:Current_List,Line_1,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_2 + + Current_List,Line_2,Txt=Param_1:Current_List,Line_2,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_3 + + Current_List,Line_3,Txt=Param_1:Current_List,Line_3,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_4 + + Current_List,Line_4,Txt=Param_1:Current_List,Line_4,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_5 + + Current_List,Line_5,Txt=Param_1:Current_List,Line_5,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_6 + + Current_List,Line_6,Txt=Param_1:Current_List,Line_6,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_7 + + Current_List,Line_7,Txt=Param_1:Current_List,Line_7,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_8 + + Current_List,Line_8,Txt=Param_1:Current_List,Line_8,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + + + Cursor_Position,Current_Line=Param_1 + + 1,65536,1 + + + + + + Cursor_Position,Max_Line=Param_1 + + 0,65536,1 + + + + + + + SiriusXM,Play_Control,Playback + SiriusXM,Play_Control,Preset,Preset_Sel + SiriusXM,List_Control,Direct_Sel + SiriusXM,List_Control,Jump_Line + SiriusXM,List_Control,Cursor + SiriusXM,List_Control,Page + SiriusXM,Play_Info + SiriusXM,List_Info + SiriusXM,Config + SiriusXM,Play_Control,Preset,Preset_Sel_Item + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Play + Pause + Stop + + Playback_Info=Param_1 + + Play + Pause + Stop + + + + + Skip Fwd + + + Thumb Up + Thumb Down + + Feedback=Param_1 + + --- + Thumb Up + Thumb Down + + + + + + + + Meta_Info,Station=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Album=Param_1 + + 0,128,UTF-8 + + + + + + Meta_Info,Track=Param_1 + + 0,128,UTF-8 + + + + + + Feedback=Param_1 + + --- + Thumb Up + Thumb Down + + + + + + Feature_Availability=Param_1 + + Ready + Not Ready + + + + + + Playback_Info=Param_1 + + Play + Pause + Stop + + + + + + Album_ART,URL=Param_1 + + 0,128,UTF-8 + + + + + + Album_ART,ID=Param_1 + + 0,255,1 + + + + + + Album_ART,Format=Param_1 + + BMP + YMF + + + + + + Input_Logo,URL_S=Param_1 + + 0,128,UTF-8 + + + + + + + + + Param_1 + + 1,8,1,Line_% + + + + + Up + Down + Return + Sel + Return to Home + + + + Param_1 + + 1,65536,1 + + + + + Up + Down + + + + + + Menu_Status=Param_1 + + Ready + Busy + + + + + + Menu_Layer=Param_1 + + 1,16,1 + + + + + + Menu_Name=Param_1 + + 0,128,UTF-8 + + + + + + Line_1 + + Current_List,Line_1,Txt=Param_1:Current_List,Line_1,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_2 + + Current_List,Line_2,Txt=Param_1:Current_List,Line_2,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_3 + + Current_List,Line_3,Txt=Param_1:Current_List,Line_3,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_4 + + Current_List,Line_4,Txt=Param_1:Current_List,Line_4,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_5 + + Current_List,Line_5,Txt=Param_1:Current_List,Line_5,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_6 + + Current_List,Line_6,Txt=Param_1:Current_List,Line_6,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_7 + + Current_List,Line_7,Txt=Param_1:Current_List,Line_7,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + Line_8 + + Current_List,Line_8,Txt=Param_1:Current_List,Line_8,Attribute=Param_2 + + 0,128,UTF-8 + + + Container + Unplayable Item + Item + Unselectable + + + + + + + Cursor_Position,Current_Line=Param_1 + + 1,65536,1 + + + + + + Cursor_Position,Max_Line=Param_1 + + 0,65536,1 + + + + + + + Pandora,Play_Control,Feedback + Pandora,Play_Control,Playback + Pandora,Play_Control,Preset,Preset_Sel + Pandora,List_Control,Direct_Sel + Pandora,List_Control,Jump_Line + Pandora,List_Control,Cursor + Pandora,List_Control,Page + Pandora,Play_Info + Pandora,List_Info + Pandora,Config + Pandora,Play_Control,Preset,Preset_Sel_Item + + +