From 5d23afdc9e268754924ebe9c47a7044581e871f4 Mon Sep 17 00:00:00 2001 From: Jan Almeroth Date: Mon, 30 Oct 2017 18:50:20 +0100 Subject: [PATCH] Introducing multi-zone support for yamaha_musiccast devices (#9968) * Introduce zones to yamaha_musiccast * Introducing new config 'interval_seconds' * Version bump pymusiccast * Removing name parameter --- CODEOWNERS | 1 + .../media_player/yamaha_musiccast.py | 84 +++++++++---------- requirements_all.txt | 2 +- 3 files changed, 41 insertions(+), 46 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index d135e657c9b..8fd5d0826c1 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -51,6 +51,7 @@ homeassistant/components/light/tplink.py @rytilahti homeassistant/components/light/yeelight.py @rytilahti homeassistant/components/media_player/kodi.py @armills homeassistant/components/media_player/monoprice.py @etsinko +homeassistant/components/media_player/yamaha_musiccast.py @jalmeroth homeassistant/components/sensor/airvisual.py @bachya homeassistant/components/sensor/irish_rail_transport.py @ttroy50 homeassistant/components/sensor/miflora.py @danielhiversen diff --git a/homeassistant/components/media_player/yamaha_musiccast.py b/homeassistant/components/media_player/yamaha_musiccast.py index 3e12b3bf7fa..27efc4f3814 100644 --- a/homeassistant/components/media_player/yamaha_musiccast.py +++ b/homeassistant/components/media_player/yamaha_musiccast.py @@ -2,7 +2,6 @@ media_player: - platform: yamaha_musiccast - name: "Living Room" host: 192.168.xxx.xx port: 5005 @@ -13,7 +12,7 @@ import voluptuous as vol import homeassistant.helpers.config_validation as cv from homeassistant.const import ( - CONF_NAME, CONF_HOST, CONF_PORT, + CONF_HOST, CONF_PORT, STATE_UNKNOWN, STATE_ON ) from homeassistant.components.media_player import ( @@ -34,16 +33,17 @@ SUPPORTED_FEATURES = ( ) KNOWN_HOSTS_KEY = 'data_yamaha_musiccast' +INTERVAL_SECONDS = 'interval_seconds' -REQUIREMENTS = ['pymusiccast==0.1.2'] +REQUIREMENTS = ['pymusiccast==0.1.3'] -DEFAULT_NAME = "Yamaha Receiver" DEFAULT_PORT = 5005 +DEFAULT_INTERVAL = 480 PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Required(CONF_HOST): cv.string, vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.positive_int, + vol.Optional(INTERVAL_SECONDS, default=DEFAULT_INTERVAL): cv.positive_int, }) @@ -57,9 +57,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None): known_hosts = hass.data[KNOWN_HOSTS_KEY] = [] _LOGGER.debug("known_hosts: %s", known_hosts) - name = config.get(CONF_NAME) host = config.get(CONF_HOST) port = config.get(CONF_PORT) + interval = config.get(INTERVAL_SECONDS) # Get IP of host to prevent duplicates try: @@ -81,14 +81,20 @@ def setup_platform(hass, config, add_devices, discovery_info=None): known_hosts.append(reg_host) try: - receiver = pymusiccast.McDevice(ipaddr, udp_port=port) + receiver = pymusiccast.McDevice( + ipaddr, udp_port=port, mc_interval=interval) except pymusiccast.exceptions.YMCInitError as err: _LOGGER.error(err) receiver = None if receiver: - _LOGGER.debug("receiver: %s / Port: %d", receiver, port) - add_devices([YamahaDevice(receiver, name)], True) + for zone in receiver.zones: + _LOGGER.debug( + "receiver: %s / Port: %d / Zone: %s", + receiver, port, zone) + add_devices( + [YamahaDevice(receiver, receiver.zones[zone])], + True) else: known_hosts.remove(reg_host) @@ -96,24 +102,26 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class YamahaDevice(MediaPlayerDevice): """Representation of a Yamaha MusicCast device.""" - def __init__(self, receiver, name): + def __init__(self, recv, zone): """Initialize the Yamaha MusicCast device.""" - self._receiver = receiver - self._name = name - self.power = STATE_UNKNOWN - self.volume = 0 - self.volume_max = 0 - self.mute = False + self._recv = recv + self._name = recv.name self._source = None self._source_list = [] - self.status = STATE_UNKNOWN + self._zone = zone + self.mute = False self.media_status = None - self._receiver.set_yamaha_device(self) + self.power = STATE_UNKNOWN + self.status = STATE_UNKNOWN + self.volume = 0 + self.volume_max = 0 + self._recv.set_yamaha_device(self) + self._zone.set_yamaha_device(self) @property def name(self): """Return the name of the device.""" - return self._name + return "{} ({})".format(self._name, self._zone.zone_id) @property def state(self): @@ -197,71 +205,57 @@ class YamahaDevice(MediaPlayerDevice): def update(self): """Get the latest details from the device.""" _LOGGER.debug("update: %s", self.entity_id) - - # call from constructor setup_platform() - if not self.entity_id: - _LOGGER.debug("First run") - self._receiver.update_status(push=False) - # call from regular polling - else: - # update_status_timer was set before - if self._receiver.update_status_timer: - _LOGGER.debug( - "is_alive: %s", - self._receiver.update_status_timer.is_alive()) - # e.g. computer was suspended, while hass was running - if not self._receiver.update_status_timer.is_alive(): - _LOGGER.debug("Reinitializing") - self._receiver.update_status() + self._recv.update_status() + self._zone.update_status() def turn_on(self): """Turn on specified media player or all.""" _LOGGER.debug("Turn device: on") - self._receiver.set_power(True) + self._zone.set_power(True) def turn_off(self): """Turn off specified media player or all.""" _LOGGER.debug("Turn device: off") - self._receiver.set_power(False) + self._zone.set_power(False) def media_play(self): """Send the media player the command for play/pause.""" _LOGGER.debug("Play") - self._receiver.set_playback("play") + self._recv.set_playback("play") def media_pause(self): """Send the media player the command for pause.""" _LOGGER.debug("Pause") - self._receiver.set_playback("pause") + self._recv.set_playback("pause") def media_stop(self): """Send the media player the stop command.""" _LOGGER.debug("Stop") - self._receiver.set_playback("stop") + self._recv.set_playback("stop") def media_previous_track(self): """Send the media player the command for prev track.""" _LOGGER.debug("Previous") - self._receiver.set_playback("previous") + self._recv.set_playback("previous") def media_next_track(self): """Send the media player the command for next track.""" _LOGGER.debug("Next") - self._receiver.set_playback("next") + self._recv.set_playback("next") def mute_volume(self, mute): """Send mute command.""" _LOGGER.debug("Mute volume: %s", mute) - self._receiver.set_mute(mute) + self._zone.set_mute(mute) def set_volume_level(self, volume): """Set volume level, range 0..1.""" _LOGGER.debug("Volume level: %.2f / %d", volume, volume * self.volume_max) - self._receiver.set_volume(volume * self.volume_max) + self._zone.set_volume(volume * self.volume_max) def select_source(self, source): """Send the media player the command to select input source.""" _LOGGER.debug("select_source: %s", source) self.status = STATE_UNKNOWN - self._receiver.set_input(source) + self._zone.set_input(source) diff --git a/requirements_all.txt b/requirements_all.txt index 03997632013..d503d8e88f6 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -721,7 +721,7 @@ pymodbus==1.3.1 pymonoprice==0.2 # homeassistant.components.media_player.yamaha_musiccast -pymusiccast==0.1.2 +pymusiccast==0.1.3 # homeassistant.components.cover.myq pymyq==0.0.8