From 837994196ed5f8d272557cde07ace070066a1c6d Mon Sep 17 00:00:00 2001 From: nordlead2005 Date: Fri, 27 Jan 2017 01:32:45 -0500 Subject: [PATCH] Added forecast support to DarkSky (#5264) * Added forecast support to DarkSky modified: homeassistant/components/sensor/darksky.py modified: tests/components/sensor/test_darksky.py * Fix async_volume_up / async_volume_down (#5249) async_volume_up / async_volume_down should be async versions of volume_up / volume_down, not a async version of the default variants of volume_up / volume_down. The previous code always called into the mediaplayers set_volume_level, and never into volume_up / volume_down. Signed-off-by: Anton Lundin * adding a default icon "blind" to a PowerView blinds scene. (#5210) * adding a default icon "blind" to a PowerView blinds scene. * Adding icon property to define blind icon. Removed it from the state attributes dict. * fixing lint error * Added forecast support to DarkSky modified: homeassistant/components/sensor/darksky.py modified: tests/components/sensor/test_darksky.py * Use SHA hash to make token harder to guess (#5258) * Use SHA hash to make token harder to guess Use hashlib SHA256 to encode object id instead of using it directly. * Cache access token Instead of generating a token on the fly cache it in the constructor. * Fix lint * Bugfix async device_tracker see callback (#5259) * Add support for NAD receivers (#5191) * Add support for NAD receivers * remove self.update() in various methods * remove setting attributes in various methods * Change import to hass style * Updated Config Validation, extended daily forecast to all supported types * Fix style errors from previous commit, fix test since adding daily for all supported types * Removed temperature from daily as it isn't supported * Added forecast support to DarkSky modified: homeassistant/components/sensor/darksky.py modified: tests/components/sensor/test_darksky.py * Updated Config Validation, extended daily forecast to all supported types * Fix style errors from previous commit, fix test since adding daily for all supported types * Removed temperature from daily as it isn't supported * Revert "Bugfix camera streams (#5306)" This reverts commit 4b43537801a5c088329f6b12c99c95fdb2eb0e9c. Revert "Version bump for kodi dependency (#5307)" This reverts commit 6abad6b76e610b1bfb13f3f9342a2a0a53971fcf. Revert "Add HMWIOSwitch to sensor, binary (#5304)" This reverts commit 2c3f55acc4cc8890e54bf6a94f5a960eee28c486. Revert "Remove GTFS default name & string change" This reverts commit 6000c59bb559b8e37553b3f0def79c2bd84f2af2. Revert "Update pyhomematic 1.19 & small cleanups (#5299)" This reverts commit a30711f1a0e2d4a286799d714fe59ff147883fab. Revert "[sensor] Add Dublin bus RTPI sensor (#5257)" This reverts commit 1219ca3c3bc083c8f919c4db7eb3670686e52861. Revert "Bugfix group reload (#5292)" This reverts commit baa8e53e66167a1fb0f9d090f28325454ad3d4ef. Revert "Support for TrackR device trackers (#5010)" This reverts commit f7a1d63d52dc7687a07cd2c52ef4e8e6894e45d9. Revert "Bump pywemo version." This reverts commit dc937cc8cffbb9ec2b4342d801f8d7332a8dd9cf. Revert "Upgrade to voluptuous to 0.9.3 (#5288)" This reverts commit d12decc4714cb61af58ab08581712b8be5367960. Revert "Upgrade distro to 1.0.2 (#5291)" This reverts commit 64800fd48c02520b1f44be960dc8c539f82d1692. Revert "Don't build Adafruit_BBIO - doesn't work on all platforms. (#5281)" This reverts commit 9a3c0c8cd3a06d118cfcf58d1078912e41f12f31. Revert "Convert flic to synchronous platform. (#5276)" This reverts commit eb9b95c2922181b097258856af9bd2bc4d7a814e. Revert "Upgrade to aiohttp 1.2 (#4964)" This reverts commit e68e29e03ebd43175761d1ae2b4e598d382d2cf4. Revert "Fix TCP sensor to correctly use value_template (#5211)" This reverts commit 1cf9ae5a01d663bb9e3d3e38741b2ae818b36f93. Revert "Cleanup language support on TTS (#5255)" This reverts commit 3f3a3bcc8ac7eec2e5e9eba9981c74db3842f22d. Revert "Add last triggered to script (#5261)" This reverts commit 467cb18625da9323f743ed62a342e446a79fb05b. Revert "Bump flux_led version and make use of PyPi package (#5267)" This reverts commit 34a9fb01ac1fb9568f18677be5faf3d23ab7dc2a. Revert "Add support for NAD receivers (#5191)" This reverts commit 3b59e169f1bc11b3887bc98b2f8425f6c70a0df2. Revert "Bugfix async device_tracker see callback (#5259)" This reverts commit 71fddd26eb9c9ffe6cbd809298f07e17aad152a4. Revert "Use SHA hash to make token harder to guess (#5258)" This reverts commit 922308bc1f7a2a0a769a8c29d663c90a97a0583b. * Revert "Revert "Bugfix camera streams (#5306)"" This reverts commit 2ee8c44021cf9c3a91d20f9ee26752aa8369d2e6. * Update darksky.py --- homeassistant/components/sensor/darksky.py | 102 ++++++++++++++------- tests/components/sensor/test_darksky.py | 5 +- 2 files changed, 70 insertions(+), 37 deletions(-) diff --git a/homeassistant/components/sensor/darksky.py b/homeassistant/components/sensor/darksky.py index ab79cff2aad..bf3ff0587a3 100644 --- a/homeassistant/components/sensor/darksky.py +++ b/homeassistant/components/sensor/darksky.py @@ -25,58 +25,76 @@ _LOGGER = logging.getLogger(__name__) CONF_ATTRIBUTION = "Powered by Dark Sky" CONF_UNITS = 'units' CONF_UPDATE_INTERVAL = 'update_interval' +CONF_FORECAST = 'forecast' DEFAULT_NAME = 'Dark Sky' # Sensor types are defined like so: # Name, si unit, us unit, ca unit, uk unit, uk2 unit SENSOR_TYPES = { - 'summary': ['Summary', None, None, None, None, None, None], + 'summary': ['Summary', None, None, None, None, None, None, []], 'minutely_summary': ['Minutely Summary', - None, None, None, None, None, None], - 'hourly_summary': ['Hourly Summary', None, None, None, None, None, None], - 'daily_summary': ['Daily Summary', None, None, None, None, None, None], - 'icon': ['Icon', None, None, None, None, None, None], + None, None, None, None, None, None, []], + 'hourly_summary': ['Hourly Summary', None, None, None, None, None, None, + []], + 'daily_summary': ['Daily Summary', None, None, None, None, None, None, []], + 'icon': ['Icon', None, None, None, None, None, None, + ['currently', 'hourly', 'daily']], 'nearest_storm_distance': ['Nearest Storm Distance', - 'km', 'mi', 'km', 'km', 'mi', - 'mdi:weather-lightning'], + 'km', 'm', 'km', 'km', 'm', + 'mdi:weather-lightning', ['currently']], 'nearest_storm_bearing': ['Nearest Storm Bearing', '°', '°', '°', '°', '°', - 'mdi:weather-lightning'], + 'mdi:weather-lightning', ['currently']], 'precip_type': ['Precip', None, None, None, None, None, - 'mdi:weather-pouring'], + 'mdi:weather-pouring', + ['currently', 'minutely', 'hourly', 'daily']], 'precip_intensity': ['Precip Intensity', - 'mm', 'in', 'mm', 'mm', 'mm', 'mdi:weather-rainy'], + 'mm', 'in', 'mm', 'mm', 'mm', 'mdi:weather-rainy', + ['currently', 'minutely', 'hourly', 'daily']], 'precip_probability': ['Precip Probability', - '%', '%', '%', '%', '%', 'mdi:water-percent'], + '%', '%', '%', '%', '%', 'mdi:water-percent', + ['currently', 'minutely', 'hourly', 'daily']], 'temperature': ['Temperature', - '°C', '°F', '°C', '°C', '°C', 'mdi:thermometer'], + '°C', '°F', '°C', '°C', '°C', 'mdi:thermometer', + ['currently', 'hourly']], 'apparent_temperature': ['Apparent Temperature', - '°C', '°F', '°C', '°C', '°C', 'mdi:thermometer'], + '°C', '°F', '°C', '°C', '°C', 'mdi:thermometer', + ['currently', 'hourly']], 'dew_point': ['Dew point', '°C', '°F', '°C', '°C', '°C', - 'mdi:thermometer'], + 'mdi:thermometer', ['currently', 'hourly', 'daily']], 'wind_speed': ['Wind Speed', 'm/s', 'mph', 'km/h', 'mph', 'mph', - 'mdi:weather-windy'], - 'wind_bearing': ['Wind Bearing', '°', '°', '°', '°', '°', 'mdi:compass'], + 'mdi:weather-windy', ['currently', 'hourly', 'daily']], + 'wind_bearing': ['Wind Bearing', '°', '°', '°', '°', '°', 'mdi:compass', + ['currently', 'hourly', 'daily']], 'cloud_cover': ['Cloud Coverage', '%', '%', '%', '%', '%', - 'mdi:weather-partlycloudy'], - 'humidity': ['Humidity', '%', '%', '%', '%', '%', 'mdi:water-percent'], + 'mdi:weather-partlycloudy', + ['currently', 'hourly', 'daily']], + 'humidity': ['Humidity', '%', '%', '%', '%', '%', 'mdi:water-percent', + ['currently', 'hourly', 'daily']], 'pressure': ['Pressure', 'mbar', 'mbar', 'mbar', 'mbar', 'mbar', - 'mdi:gauge'], - 'visibility': ['Visibility', 'km', 'mi', 'km', 'km', 'mi', 'mdi:eye'], - 'ozone': ['Ozone', 'DU', 'DU', 'DU', 'DU', 'DU', 'mdi:eye'], + 'mdi:gauge', ['currently', 'hourly', 'daily']], + 'visibility': ['Visibility', 'km', 'm', 'km', 'km', 'm', 'mdi:eye', + ['currently', 'hourly', 'daily']], + 'ozone': ['Ozone', 'DU', 'DU', 'DU', 'DU', 'DU', 'mdi:eye', + ['currently', 'hourly', 'daily']], 'apparent_temperature_max': ['Daily High Apparent Temperature', '°C', '°F', '°C', '°C', '°C', - 'mdi:thermometer'], + 'mdi:thermometer', + ['currently', 'hourly', 'daily']], 'apparent_temperature_min': ['Daily Low Apparent Temperature', '°C', '°F', '°C', '°C', '°C', - 'mdi:thermometer'], + 'mdi:thermometer', + ['currently', 'hourly', 'daily']], 'temperature_max': ['Daily High Temperature', - '°C', '°F', '°C', '°C', '°C', 'mdi:thermometer'], + '°C', '°F', '°C', '°C', '°C', 'mdi:thermometer', + ['currently', 'hourly', 'daily']], 'temperature_min': ['Daily Low Temperature', - '°C', '°F', '°C', '°C', '°C', 'mdi:thermometer'], + '°C', '°F', '°C', '°C', '°C', 'mdi:thermometer', + ['currently', 'hourly', 'daily']], 'precip_intensity_max': ['Daily Max Precip Intensity', - 'mm', 'in', 'mm', 'mm', 'mm', 'mdi:thermometer'], + 'mm', 'in', 'mm', 'mm', 'mm', 'mdi:thermometer', + ['currently', 'hourly', 'daily']], } PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ @@ -87,6 +105,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_UNITS): vol.In(['auto', 'si', 'us', 'ca', 'uk', 'uk2']), vol.Optional(CONF_UPDATE_INTERVAL, default=timedelta(seconds=120)): ( vol.All(cv.time_period, cv.positive_timedelta)), + vol.Optional(CONF_FORECAST): + vol.All(cv.ensure_list, [vol.Range(min=1, max=7)]), }) @@ -119,9 +139,14 @@ def setup_platform(hass, config, add_devices, discovery_info=None): name = config.get(CONF_NAME) + forecast = config.get(CONF_FORECAST) sensors = [] for variable in config[CONF_MONITORED_CONDITIONS]: sensors.append(DarkSkySensor(forecast_data, variable, name)) + if forecast is not None and 'daily' in SENSOR_TYPES[variable][7]: + for forecast_day in forecast: + sensors.append(DarkSkySensor(forecast_data, + variable, name, forecast_day)) add_devices(sensors, True) @@ -129,19 +154,24 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class DarkSkySensor(Entity): """Implementation of a Dark Sky sensor.""" - def __init__(self, forecast_data, sensor_type, name): + def __init__(self, forecast_data, sensor_type, name, forecast_day=0): """Initialize the sensor.""" self.client_name = name self._name = SENSOR_TYPES[sensor_type][0] self.forecast_data = forecast_data self.type = sensor_type + self.forecast_day = forecast_day self._state = None self._unit_of_measurement = None @property def name(self): """Return the name of the sensor.""" - return '{} {}'.format(self.client_name, self._name) + if self.forecast_day == 0: + return '{} {}'.format(self.client_name, self._name) + else: + return '{} {} {}'.format(self.client_name, self._name, + self.forecast_day) @property def state(self): @@ -198,19 +228,21 @@ class DarkSkySensor(Entity): self.forecast_data.update_hourly() hourly = self.forecast_data.data_hourly self._state = getattr(hourly, 'summary', '') - elif self.type in ['daily_summary', - 'temperature_min', - 'temperature_max', - 'apparent_temperature_min', - 'apparent_temperature_max', - 'precip_intensity_max']: + elif self.forecast_day > 0 or ( + self.type in ['daily_summary', + 'temperature_min', + 'temperature_max', + 'apparent_temperature_min', + 'apparent_temperature_max', + 'precip_intensity_max']): self.forecast_data.update_daily() daily = self.forecast_data.data_daily if self.type == 'daily_summary': self._state = getattr(daily, 'summary', '') else: if hasattr(daily, 'data'): - self._state = self.get_state(daily.data[0]) + self._state = self.get_state( + daily.data[self.forecast_day]) else: self._state = 0 else: diff --git a/tests/components/sensor/test_darksky.py b/tests/components/sensor/test_darksky.py index e3c83bad2a6..effa7b3dbd8 100644 --- a/tests/components/sensor/test_darksky.py +++ b/tests/components/sensor/test_darksky.py @@ -32,7 +32,8 @@ class TestDarkSkySetup(unittest.TestCase): self.key = 'foo' self.config = { 'api_key': 'foo', - 'monitored_conditions': ['summary', 'icon'], + 'forecast': [1, 2], + 'monitored_conditions': ['summary', 'icon', 'temperature_max'], 'update_interval': timedelta(seconds=120), } self.lat = 37.8267 @@ -80,4 +81,4 @@ class TestDarkSkySetup(unittest.TestCase): darksky.setup_platform(self.hass, self.config, self.add_entities) self.assertTrue(mock_get_forecast.called) self.assertEqual(mock_get_forecast.call_count, 1) - self.assertEqual(len(self.entities), 2) + self.assertEqual(len(self.entities), 7)