diff --git a/homeassistant/components/binary_sensor/mercedesme.py b/homeassistant/components/binary_sensor/mercedesme.py index a6c8da56ce8..fcf2d7122e2 100644 --- a/homeassistant/components/binary_sensor/mercedesme.py +++ b/homeassistant/components/binary_sensor/mercedesme.py @@ -9,7 +9,7 @@ import datetime from homeassistant.components.binary_sensor import (BinarySensorDevice) from homeassistant.components.mercedesme import ( - DATA_MME, MercedesMeEntity, BINARY_SENSORS) + DATA_MME, FEATURE_NOT_AVAILABLE, MercedesMeEntity, BINARY_SENSORS) DEPENDENCIES = ['mercedesme'] @@ -27,8 +27,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None): devices = [] for car in data.cars: for key, value in sorted(BINARY_SENSORS.items()): - devices.append(MercedesMEBinarySensor( - data, key, value[0], car["vin"], None)) + if car['availabilities'].get(key, 'INVALID') == 'VALID': + devices.append(MercedesMEBinarySensor( + data, key, value[0], car["vin"], None)) + else: + _LOGGER.warning(FEATURE_NOT_AVAILABLE, key, car["license"]) add_devices(devices, True) diff --git a/homeassistant/components/device_tracker/mercedesme.py b/homeassistant/components/device_tracker/mercedesme.py index 0aa2be96290..dcc9e3ab2ec 100644 --- a/homeassistant/components/device_tracker/mercedesme.py +++ b/homeassistant/components/device_tracker/mercedesme.py @@ -49,10 +49,13 @@ class MercedesMEDeviceTracker(object): def update_info(self, now=None): """Update the device info.""" for device in self.data.cars: - _LOGGER.debug("Updating %s", device["vin"]) + if not device['services'].get('VEHICLE_FINDER', False): + continue + location = self.data.get_location(device["vin"]) if location is None: - return False + continue + dev_id = device["vin"] name = device["license"] diff --git a/homeassistant/components/light/limitlessled.py b/homeassistant/components/light/limitlessled.py index 0c6b1143bbd..aad2abdd183 100644 --- a/homeassistant/components/light/limitlessled.py +++ b/homeassistant/components/light/limitlessled.py @@ -16,7 +16,7 @@ from homeassistant.components.light import ( SUPPORT_RGB_COLOR, SUPPORT_TRANSITION, Light, PLATFORM_SCHEMA) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['limitlessled==1.0.9'] +REQUIREMENTS = ['limitlessled==1.0.8'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/media_player/yamaha.py b/homeassistant/components/media_player/yamaha.py index f102d8a490d..5b8ac2ad236 100644 --- a/homeassistant/components/media_player/yamaha.py +++ b/homeassistant/components/media_player/yamaha.py @@ -60,7 +60,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): import rxv # Keep track of configured receivers so that we don't end up # discovering a receiver dynamically that we have static config - # for. Map each device from its unique_id to an instance since + # for. Map each device from its zone_id to an instance since # YamahaDevice is not hashable (thus not possible to add to a set). if hass.data.get(DATA_YAMAHA) is None: hass.data[DATA_YAMAHA] = {} @@ -100,8 +100,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): source_names, zone_names) # Only add device if it's not already added - if device.unique_id not in hass.data[DATA_YAMAHA]: - hass.data[DATA_YAMAHA][device.unique_id] = device + if device.zone_id not in hass.data[DATA_YAMAHA]: + hass.data[DATA_YAMAHA][device.zone_id] = device devices.append(device) else: _LOGGER.debug('Ignoring duplicate receiver %s', name) @@ -220,6 +220,11 @@ class YamahaDevice(MediaPlayerDevice): """List of available input sources.""" return self._source_list + @property + def zone_id(self): + """Return an zone_id to ensure 1 media player per zone.""" + return '{0}:{1}'.format(self.receiver.ctrl_url, self._zone) + @property def supported_features(self): """Flag media player features that are supported.""" diff --git a/homeassistant/components/mercedesme.py b/homeassistant/components/mercedesme.py index a228486e2c8..b809e46ec64 100644 --- a/homeassistant/components/mercedesme.py +++ b/homeassistant/components/mercedesme.py @@ -41,6 +41,8 @@ SENSORS = { DATA_MME = 'mercedesme' DOMAIN = 'mercedesme' +FEATURE_NOT_AVAILABLE = "The feature %s is not available for your car %s" + NOTIFICATION_ID = 'mercedesme_integration_notification' NOTIFICATION_TITLE = 'Mercedes me integration setup' diff --git a/homeassistant/components/sensor/eddystone_temperature.py b/homeassistant/components/sensor/eddystone_temperature.py index ef06458cd84..fb5fa2c1fba 100644 --- a/homeassistant/components/sensor/eddystone_temperature.py +++ b/homeassistant/components/sensor/eddystone_temperature.py @@ -18,7 +18,7 @@ from homeassistant.const import ( CONF_NAME, TEMP_CELSIUS, STATE_UNKNOWN, EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START) -REQUIREMENTS = ['beacontools[scan]==1.0.1'] +REQUIREMENTS = ['beacontools[scan]==1.2.1'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/sensor/mercedesme.py b/homeassistant/components/sensor/mercedesme.py index bc368745e40..bb7212678a7 100644 --- a/homeassistant/components/sensor/mercedesme.py +++ b/homeassistant/components/sensor/mercedesme.py @@ -8,7 +8,7 @@ import logging import datetime from homeassistant.components.mercedesme import ( - DATA_MME, MercedesMeEntity, SENSORS) + DATA_MME, FEATURE_NOT_AVAILABLE, MercedesMeEntity, SENSORS) DEPENDENCIES = ['mercedesme'] @@ -29,8 +29,12 @@ def setup_platform(hass, config, add_devices, discovery_info=None): devices = [] for car in data.cars: for key, value in sorted(SENSORS.items()): - devices.append( - MercedesMESensor(data, key, value[0], car["vin"], value[1])) + if car['availabilities'].get(key, 'INVALID') == 'VALID': + devices.append( + MercedesMESensor( + data, key, value[0], car["vin"], value[1])) + else: + _LOGGER.warning(FEATURE_NOT_AVAILABLE, key, car["license"]) add_devices(devices, True) diff --git a/homeassistant/components/sensor/wunderground.py b/homeassistant/components/sensor/wunderground.py index d0d9758c13a..aa5d431a7b0 100644 --- a/homeassistant/components/sensor/wunderground.py +++ b/homeassistant/components/sensor/wunderground.py @@ -11,14 +11,14 @@ import re import requests import voluptuous as vol -from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.helpers.typing import HomeAssistantType +from homeassistant.components.sensor import PLATFORM_SCHEMA, ENTITY_ID_FORMAT from homeassistant.const import ( CONF_MONITORED_CONDITIONS, CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, TEMP_FAHRENHEIT, TEMP_CELSIUS, LENGTH_INCHES, LENGTH_KILOMETERS, - LENGTH_MILES, LENGTH_FEET, STATE_UNKNOWN, ATTR_ATTRIBUTION, - ATTR_FRIENDLY_NAME) + LENGTH_MILES, LENGTH_FEET, STATE_UNKNOWN, ATTR_ATTRIBUTION) from homeassistant.exceptions import PlatformNotReady -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, generate_entity_id from homeassistant.util import Throttle import homeassistant.helpers.config_validation as cv @@ -637,7 +637,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): config.get(CONF_LANG), latitude, longitude) sensors = [] for variable in config[CONF_MONITORED_CONDITIONS]: - sensors.append(WUndergroundSensor(rest, variable)) + sensors.append(WUndergroundSensor(hass, rest, variable)) rest.update() if not rest.data: @@ -651,7 +651,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class WUndergroundSensor(Entity): """Implementing the WUnderground sensor.""" - def __init__(self, rest, condition): + def __init__(self, hass: HomeAssistantType, rest, condition): """Initialize the sensor.""" self.rest = rest self._condition = condition @@ -663,6 +663,8 @@ class WUndergroundSensor(Entity): self._entity_picture = None self._unit_of_measurement = self._cfg_expand("unit_of_measurement") self.rest.request_feature(SENSOR_TYPES[condition].feature) + self.entity_id = generate_entity_id( + ENTITY_ID_FORMAT, "pws_" + condition, hass=hass) def _cfg_expand(self, what, default=None): """Parse and return sensor data.""" @@ -684,9 +686,6 @@ class WUndergroundSensor(Entity): """Parse and update device state attributes.""" attrs = self._cfg_expand("device_state_attributes", {}) - self._attributes[ATTR_FRIENDLY_NAME] = self._cfg_expand( - "friendly_name") - for (attr, callback) in attrs.items(): if callable(callback): try: @@ -701,7 +700,7 @@ class WUndergroundSensor(Entity): @property def name(self): """Return the name of the sensor.""" - return "PWS_" + self._condition + return self._cfg_expand("friendly_name") @property def state(self): diff --git a/homeassistant/const.py b/homeassistant/const.py index 6af7b885561..917292648c9 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 63 -PATCH_VERSION = '1' +PATCH_VERSION = '2' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 4, 2) diff --git a/requirements_all.txt b/requirements_all.txt index 2a5f68791e0..6c1282ce8a7 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -118,7 +118,7 @@ basicmodem==0.7 batinfo==0.4.2 # homeassistant.components.sensor.eddystone_temperature -# beacontools[scan]==1.0.1 +# beacontools[scan]==1.2.1 # homeassistant.components.device_tracker.linksys_ap # homeassistant.components.sensor.geizhals @@ -454,7 +454,7 @@ liffylights==0.9.4 lightify==1.0.6.1 # homeassistant.components.light.limitlessled -limitlessled==1.0.9 +limitlessled==1.0.8 # homeassistant.components.linode linode-api==4.1.4b2 diff --git a/tests/components/sensor/test_wunderground.py b/tests/components/sensor/test_wunderground.py index 5f6028b1a14..c1508f49851 100644 --- a/tests/components/sensor/test_wunderground.py +++ b/tests/components/sensor/test_wunderground.py @@ -249,31 +249,41 @@ class TestWundergroundSetup(unittest.TestCase): None) for device in self.DEVICES: device.update() - self.assertTrue(str(device.name).startswith('PWS_')) - if device.name == 'PWS_weather': + entity_id = device.entity_id + friendly_name = device.name + self.assertTrue(entity_id.startswith('sensor.pws_')) + if entity_id == 'sensor.pws_weather': self.assertEqual(HTTPS_ICON_URL, device.entity_picture) self.assertEqual(WEATHER, device.state) self.assertIsNone(device.unit_of_measurement) - elif device.name == 'PWS_alerts': + self.assertEqual("Weather Summary", friendly_name) + elif entity_id == 'sensor.pws_alerts': self.assertEqual(1, device.state) self.assertEqual(ALERT_MESSAGE, device.device_state_attributes['Message']) self.assertEqual(ALERT_ICON, device.icon) self.assertIsNone(device.entity_picture) - elif device.name == 'PWS_location': + self.assertEqual('Alerts', friendly_name) + elif entity_id == 'sensor.pws_location': self.assertEqual('Holly Springs, NC', device.state) - elif device.name == 'PWS_elevation': + self.assertEqual('Location', friendly_name) + elif entity_id == 'sensor.pws_elevation': self.assertEqual('413', device.state) - elif device.name == 'PWS_feelslike_c': + self.assertEqual('Elevation', friendly_name) + elif entity_id == 'sensor.pws_feelslike_c': self.assertIsNone(device.entity_picture) self.assertEqual(FEELS_LIKE, device.state) self.assertEqual(TEMP_CELSIUS, device.unit_of_measurement) - elif device.name == 'PWS_weather_1d_metric': + self.assertEqual("Feels Like", friendly_name) + elif entity_id == 'sensor.pws_weather_1d_metric': self.assertEqual(FORECAST_TEXT, device.state) + self.assertEqual('Tuesday', friendly_name) else: - self.assertEqual(device.name, 'PWS_precip_1d_in') + self.assertEqual(entity_id, 'sensor.pws_precip_1d_in') self.assertEqual(PRECIP_IN, device.state) self.assertEqual(LENGTH_INCHES, device.unit_of_measurement) + self.assertEqual('Precipitation Intensity Today', + friendly_name) @unittest.mock.patch('requests.get', side_effect=ConnectionError('test exception'))