diff --git a/homeassistant/components/media_player/directv.py b/homeassistant/components/media_player/directv.py index 4767428894b..009a720276e 100644 --- a/homeassistant/components/media_player/directv.py +++ b/homeassistant/components/media_player/directv.py @@ -48,12 +48,12 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the DirecTV platform.""" - known_devices = hass.data.get(DATA_DIRECTV) - if not known_devices: - known_devices = [] + known_devices = hass.data.get(DATA_DIRECTV, []) hosts = [] if CONF_HOST in config: + _LOGGER.debug("Adding configured device %s with client address %s ", + config.get(CONF_NAME), config.get(CONF_DEVICE)) hosts.append([ config.get(CONF_NAME), config.get(CONF_HOST), config.get(CONF_PORT), config.get(CONF_DEVICE) @@ -64,29 +64,57 @@ def setup_platform(hass, config, add_entities, discovery_info=None): name = 'DirecTV_{}'.format(discovery_info.get('serial', '')) # Attempt to discover additional RVU units - try: - resp = requests.get( - 'http://%s:%d/info/getLocations' % (host, DEFAULT_PORT)).json() - if "locations" in resp: - for loc in resp["locations"]: - if("locationName" in loc and "clientAddr" in loc - and loc["clientAddr"] not in known_devices): - hosts.append([str.title(loc["locationName"]), host, - DEFAULT_PORT, loc["clientAddr"]]) + _LOGGER.debug("Doing discovery of DirecTV devices on %s", host) - except requests.exceptions.RequestException: + from DirectPy import DIRECTV + dtv = DIRECTV(host, DEFAULT_PORT) + try: + resp = dtv.get_locations() + except requests.exceptions.RequestException as ex: # Bail out and just go forward with uPnP data - if DEFAULT_DEVICE not in known_devices: - hosts.append([name, host, DEFAULT_PORT, DEFAULT_DEVICE]) + # Make sure that this device is not already configured + # Comparing based on host (IP) and clientAddr. + _LOGGER.debug("Request exception %s trying to get locations", ex) + resp = { + 'locations': [{ + 'locationName': name, + 'clientAddr': DEFAULT_DEVICE + }] + } + + _LOGGER.debug("Known devices: %s", known_devices) + for loc in resp.get("locations") or []: + if "locationName" not in loc or "clientAddr" not in loc: + continue + + # Make sure that this device is not already configured + # Comparing based on host (IP) and clientAddr. + device_unknown = True + for device in known_devices: + if host in device and loc["clientAddr"] in device: + device_unknown = False + _LOGGER.debug("Discovered device %s on host %s with " + "client address %s is already " + "configured", + str.title(loc["locationName"]), + host, loc["clientAddr"]) + break + + if device_unknown: + _LOGGER.debug("Adding discovered device %s with" + " client address %s", + str.title(loc["locationName"]), + loc["clientAddr"]) + hosts.append([str.title(loc["locationName"]), host, + DEFAULT_PORT, loc["clientAddr"]]) dtvs = [] for host in hosts: dtvs.append(DirecTvDevice(*host)) - known_devices.append(host[-1]) + hass.data.setdefault(DATA_DIRECTV, []).append(host) add_entities(dtvs) - hass.data[DATA_DIRECTV] = known_devices class DirecTvDevice(MediaPlayerDevice): @@ -104,28 +132,43 @@ class DirecTvDevice(MediaPlayerDevice): self._last_position = None self._is_recorded = None self._assumed_state = None + self._available = False _LOGGER.debug("Created DirecTV device for %s", self._name) def update(self): """Retrieve latest state.""" - _LOGGER.debug("Updating state for %s", self._name) - self._is_standby = self.dtv.get_standby() - if self._is_standby: - self._current = None - self._is_recorded = None - self._paused = None - self._assumed_state = False - self._last_position = None - self._last_update = None - else: - self._current = self.dtv.get_tuned() - self._is_recorded = self._current.get('uniqueId') is not None - self._paused = self._last_position == self._current['offset'] - self._assumed_state = self._is_recorded - self._last_position = self._current['offset'] - self._last_update = dt_util.now() if not self._paused or\ - self._last_update is None else self._last_update + _LOGGER.debug("Updating status for %s", self._name) + try: + self._available = True + self._is_standby = self.dtv.get_standby() + if self._is_standby: + self._current = None + self._is_recorded = None + self._paused = None + self._assumed_state = False + self._last_position = None + self._last_update = None + else: + self._current = self.dtv.get_tuned() + if self._current['status']['code'] == 200: + self._is_recorded = self._current.get('uniqueId')\ + is not None + self._paused = self._last_position == \ + self._current['offset'] + self._assumed_state = self._is_recorded + self._last_position = self._current['offset'] + self._last_update = dt_util.now() if not self._paused or\ + self._last_update is None else self._last_update + else: + self._available = False + except requests.RequestException as ex: + _LOGGER.error("Request error trying to update current status for" + " %s. %s", self._name, ex) + self._available = False + except Exception: + self._available = False + raise @property def device_state_attributes(self): @@ -160,6 +203,11 @@ class DirecTvDevice(MediaPlayerDevice): return STATE_PLAYING + @property + def available(self): + """Return if able to retrieve information from DVR or not.""" + return self._available + @property def assumed_state(self): """Return if we assume the state or not."""