From 3dc70436f1937ab6767f8f9dc5bbbe712352990e Mon Sep 17 00:00:00 2001 From: koolsb <14332595+koolsb@users.noreply.github.com> Date: Thu, 19 Apr 2018 04:31:50 -0500 Subject: [PATCH] Add additional receiver for Onkyo zone 2 (#13551) --- .../components/media_player/onkyo.py | 86 ++++++++++++++++++- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/media_player/onkyo.py b/homeassistant/components/media_player/onkyo.py index 432d9ce108f..58703165385 100644 --- a/homeassistant/components/media_player/onkyo.py +++ b/homeassistant/components/media_player/onkyo.py @@ -22,6 +22,7 @@ REQUIREMENTS = ['onkyo-eiscp==1.2.4'] _LOGGER = logging.getLogger(__name__) CONF_SOURCES = 'sources' +CONF_ZONE2 = 'zone2' DEFAULT_NAME = 'Onkyo Receiver' @@ -40,6 +41,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_SOURCES, default=DEFAULT_SOURCES): {cv.string: cv.string}, + vol.Optional(CONF_ZONE2, default=False): cv.boolean, }) @@ -57,6 +59,14 @@ def setup_platform(hass, config, add_devices, discovery_info=None): eiscp.eISCP(host), config.get(CONF_SOURCES), name=config.get(CONF_NAME))) KNOWN_HOSTS.append(host) + + # Add Zone2 if configured + if config.get(CONF_ZONE2): + _LOGGER.debug("Setting up zone 2") + hosts.append(OnkyoDeviceZone2(eiscp.eISCP(host), + config.get(CONF_SOURCES), + name=config.get(CONF_NAME) + + " Zone 2")) except OSError: _LOGGER.error("Unable to connect to receiver at %s", host) else: @@ -98,8 +108,9 @@ class OnkyoDevice(MediaPlayerDevice): return result def update(self): - """Get the latest details from the device.""" + """Get the latest state from the device.""" status = self.command('system-power query') + if not status: return if status[1] == 'on': @@ -107,9 +118,11 @@ class OnkyoDevice(MediaPlayerDevice): else: self._pwstate = STATE_OFF return + volume_raw = self.command('volume query') mute_raw = self.command('audio-muting query') current_source_raw = self.command('input-selector query') + if not (volume_raw and mute_raw and current_source_raw): return @@ -147,12 +160,12 @@ class OnkyoDevice(MediaPlayerDevice): @property def is_volume_muted(self): - """Boolean if volume is currently muted.""" + """Return boolean indicating mute status.""" return self._muted @property def supported_features(self): - """Flag media player features that are supported.""" + """Return media player features that are supported.""" return SUPPORT_ONKYO @property @@ -166,7 +179,7 @@ class OnkyoDevice(MediaPlayerDevice): return self._source_list def turn_off(self): - """Turn off media player.""" + """Turn the media player off.""" self.command('system-power standby') def set_volume_level(self, volume): @@ -189,3 +202,68 @@ class OnkyoDevice(MediaPlayerDevice): if source in self._source_list: source = self._reverse_mapping[source] self.command('input-selector {}'.format(source)) + + +class OnkyoDeviceZone2(OnkyoDevice): + """Representation of an Onkyo device's zone 2.""" + + def update(self): + """Get the latest state from the device.""" + status = self.command('zone2.power=query') + + if not status: + return + if status[1] == 'on': + self._pwstate = STATE_ON + else: + self._pwstate = STATE_OFF + return + + volume_raw = self.command('zone2.volume=query') + mute_raw = self.command('zone2.muting=query') + current_source_raw = self.command('zone2.selector=query') + + if not (volume_raw and mute_raw and current_source_raw): + return + + # eiscp can return string or tuple. Make everything tuples. + if isinstance(current_source_raw[1], str): + current_source_tuples = \ + (current_source_raw[0], (current_source_raw[1],)) + else: + current_source_tuples = current_source_raw + + for source in current_source_tuples[1]: + if source in self._source_mapping: + self._current_source = self._source_mapping[source] + break + else: + self._current_source = '_'.join( + [i for i in current_source_tuples[1]]) + self._muted = bool(mute_raw[1] == 'on') + self._volume = volume_raw[1] / 80.0 + + def turn_off(self): + """Turn the media player off.""" + self.command('zone2.power=standby') + + def set_volume_level(self, volume): + """Set volume level, input is range 0..1. Onkyo ranges from 1-80.""" + self.command('zone2.volume={}'.format(int(volume*80))) + + def mute_volume(self, mute): + """Mute (true) or unmute (false) media player.""" + if mute: + self.command('zone2.muting=on') + else: + self.command('zone2.muting=off') + + def turn_on(self): + """Turn the media player on.""" + self.command('zone2.power=on') + + def select_source(self, source): + """Set the input source.""" + if source in self._source_list: + source = self._reverse_mapping[source] + self.command('zone2.selector={}'.format(source))