Darksky: Expose missing conditions for day 0 forecast (#18312)

Dark Sky Sensor didn't expose conditions for day 0 (today forecast) that
had the same name as current conditions. With this change all conditions
form day 0 (today) forecast are exposed the same way as conditions for
the rest of the days (1..7): as `dark_sky_<condition>_<day>`. As a
consequence, conditions for day 0 that were already exposed now have
`_0` suffix. This actually improves the code by removing most of
special handling, based on condition name.

To get day 0 conditions the user now has to add `- 0` to `forecast`
configuration parameter.

Conditions, for which suffix `_0` appeared: `precip_accumulation`,
`temperature_high`, `temperature_low`, `apparent_temperature_high`,
`apparent_temperature_low`, `precip_intensity_max`, `moon_phase`.

This is a breaking change!

Closes #18205
This commit is contained in:
Oleksii Serdiuk 2018-11-19 14:48:52 +01:00 committed by Pascal Vizeli
parent fc4dd4e51f
commit 01953ab46b
2 changed files with 27 additions and 38 deletions

View File

@ -43,7 +43,8 @@ DEPRECATED_SENSOR_TYPES = {
# Sensor types are defined like so: # Sensor types are defined like so:
# Name, si unit, us unit, ca unit, uk unit, uk2 unit # Name, si unit, us unit, ca unit, uk unit, uk2 unit
SENSOR_TYPES = { SENSOR_TYPES = {
'summary': ['Summary', None, None, None, None, None, None, ['daily']], 'summary': ['Summary', None, None, None, None, None, None,
['currently', 'hourly', 'daily']],
'minutely_summary': ['Minutely Summary', 'minutely_summary': ['Minutely Summary',
None, None, None, None, None, None, []], None, None, None, None, None, None, []],
'hourly_summary': ['Hourly Summary', None, None, None, None, None, None, 'hourly_summary': ['Hourly Summary', None, None, None, None, None, None,
@ -72,7 +73,7 @@ SENSOR_TYPES = {
['hourly', 'daily']], ['hourly', 'daily']],
'temperature': ['Temperature', 'temperature': ['Temperature',
'°C', '°F', '°C', '°C', '°C', 'mdi:thermometer', '°C', '°F', '°C', '°C', '°C', 'mdi:thermometer',
['currently', 'hourly']], ['currently', 'hourly', 'daily']],
'apparent_temperature': ['Apparent Temperature', 'apparent_temperature': ['Apparent Temperature',
'°C', '°F', '°C', '°C', '°C', 'mdi:thermometer', '°C', '°F', '°C', '°C', '°C', 'mdi:thermometer',
['currently', 'hourly']], ['currently', 'hourly']],
@ -98,15 +99,13 @@ SENSOR_TYPES = {
['currently', 'hourly', 'daily']], ['currently', 'hourly', 'daily']],
'apparent_temperature_max': ['Daily High Apparent Temperature', 'apparent_temperature_max': ['Daily High Apparent Temperature',
'°C', '°F', '°C', '°C', '°C', '°C', '°F', '°C', '°C', '°C',
'mdi:thermometer', 'mdi:thermometer', ['daily']],
['currently', 'hourly', 'daily']],
'apparent_temperature_high': ["Daytime High Apparent Temperature", 'apparent_temperature_high': ["Daytime High Apparent Temperature",
'°C', '°F', '°C', '°C', '°C', '°C', '°F', '°C', '°C', '°C',
'mdi:thermometer', ['daily']], 'mdi:thermometer', ['daily']],
'apparent_temperature_min': ['Daily Low Apparent Temperature', 'apparent_temperature_min': ['Daily Low Apparent Temperature',
'°C', '°F', '°C', '°C', '°C', '°C', '°F', '°C', '°C', '°C',
'mdi:thermometer', 'mdi:thermometer', ['daily']],
['currently', 'hourly', 'daily']],
'apparent_temperature_low': ['Overnight Low Apparent Temperature', 'apparent_temperature_low': ['Overnight Low Apparent Temperature',
'°C', '°F', '°C', '°C', '°C', '°C', '°F', '°C', '°C', '°C',
'mdi:thermometer', ['daily']], 'mdi:thermometer', ['daily']],
@ -124,8 +123,7 @@ SENSOR_TYPES = {
['daily']], ['daily']],
'precip_intensity_max': ['Daily Max Precip Intensity', 'precip_intensity_max': ['Daily Max Precip Intensity',
'mm/h', 'in', 'mm/h', 'mm/h', 'mm/h', 'mm/h', 'in', 'mm/h', 'mm/h', 'mm/h',
'mdi:thermometer', 'mdi:thermometer', ['daily']],
['currently', 'hourly', 'daily']],
'uv_index': ['UV Index', 'uv_index': ['UV Index',
UNIT_UV_INDEX, UNIT_UV_INDEX, UNIT_UV_INDEX, UNIT_UV_INDEX, UNIT_UV_INDEX, UNIT_UV_INDEX,
UNIT_UV_INDEX, UNIT_UV_INDEX, 'mdi:weather-sunny', UNIT_UV_INDEX, UNIT_UV_INDEX, 'mdi:weather-sunny',
@ -180,7 +178,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_UPDATE_INTERVAL, default=timedelta(seconds=300)): ( vol.Optional(CONF_UPDATE_INTERVAL, default=timedelta(seconds=300)): (
vol.All(cv.time_period, cv.positive_timedelta)), vol.All(cv.time_period, cv.positive_timedelta)),
vol.Optional(CONF_FORECAST): vol.Optional(CONF_FORECAST):
vol.All(cv.ensure_list, [vol.Range(min=1, max=7)]), vol.All(cv.ensure_list, [vol.Range(min=0, max=7)]),
}) })
@ -215,7 +213,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
for variable in config[CONF_MONITORED_CONDITIONS]: for variable in config[CONF_MONITORED_CONDITIONS]:
if variable in DEPRECATED_SENSOR_TYPES: if variable in DEPRECATED_SENSOR_TYPES:
_LOGGER.warning("Monitored condition %s is deprecated", variable) _LOGGER.warning("Monitored condition %s is deprecated", variable)
sensors.append(DarkSkySensor(forecast_data, variable, name)) if (not SENSOR_TYPES[variable][7] or
'currently' in SENSOR_TYPES[variable][7]):
sensors.append(DarkSkySensor(forecast_data, variable, name))
if forecast is not None and 'daily' in SENSOR_TYPES[variable][7]: if forecast is not None and 'daily' in SENSOR_TYPES[variable][7]:
for forecast_day in forecast: for forecast_day in forecast:
sensors.append(DarkSkySensor( sensors.append(DarkSkySensor(
@ -227,7 +227,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
class DarkSkySensor(Entity): class DarkSkySensor(Entity):
"""Implementation of a Dark Sky sensor.""" """Implementation of a Dark Sky sensor."""
def __init__(self, forecast_data, sensor_type, name, forecast_day=0): def __init__(self, forecast_data, sensor_type, name, forecast_day=None):
"""Initialize the sensor.""" """Initialize the sensor."""
self.client_name = name self.client_name = name
self._name = SENSOR_TYPES[sensor_type][0] self._name = SENSOR_TYPES[sensor_type][0]
@ -241,7 +241,7 @@ class DarkSkySensor(Entity):
@property @property
def name(self): def name(self):
"""Return the name of the sensor.""" """Return the name of the sensor."""
if self.forecast_day == 0: if self.forecast_day is None:
return '{} {}'.format(self.client_name, self._name) return '{} {}'.format(self.client_name, self._name)
return '{} {} {}'.format( return '{} {} {}'.format(
@ -318,30 +318,18 @@ class DarkSkySensor(Entity):
hourly = self.forecast_data.data_hourly hourly = self.forecast_data.data_hourly
self._state = getattr(hourly, 'summary', '') self._state = getattr(hourly, 'summary', '')
self._icon = getattr(hourly, 'icon', '') self._icon = getattr(hourly, 'icon', '')
elif self.forecast_day > 0 or ( elif self.type == 'daily_summary':
self.type in ['daily_summary',
'temperature_min',
'temperature_low',
'temperature_max',
'temperature_high',
'apparent_temperature_min',
'apparent_temperature_low',
'apparent_temperature_max',
'apparent_temperature_high',
'precip_intensity_max',
'precip_accumulation',
'moon_phase']):
self.forecast_data.update_daily() self.forecast_data.update_daily()
daily = self.forecast_data.data_daily daily = self.forecast_data.data_daily
if self.type == 'daily_summary': self._state = getattr(daily, 'summary', '')
self._state = getattr(daily, 'summary', '') self._icon = getattr(daily, 'icon', '')
self._icon = getattr(daily, 'icon', '') elif self.forecast_day is not None:
self.forecast_data.update_daily()
daily = self.forecast_data.data_daily
if hasattr(daily, 'data'):
self._state = self.get_state(daily.data[self.forecast_day])
else: else:
if hasattr(daily, 'data'): self._state = 0
self._state = self.get_state(
daily.data[self.forecast_day])
else:
self._state = 0
else: else:
self.forecast_data.update_currently() self.forecast_data.update_currently()
currently = self.forecast_data.data_currently currently = self.forecast_data.data_currently
@ -366,6 +354,7 @@ class DarkSkySensor(Entity):
# percentages # percentages
if self.type in ['precip_probability', 'cloud_cover', 'humidity']: if self.type in ['precip_probability', 'cloud_cover', 'humidity']:
return round(state * 100, 1) return round(state * 100, 1)
if self.type in ['dew_point', 'temperature', 'apparent_temperature', if self.type in ['dew_point', 'temperature', 'apparent_temperature',
'temperature_low', 'apparent_temperature_low', 'temperature_low', 'apparent_temperature_low',
'temperature_min', 'apparent_temperature_min', 'temperature_min', 'apparent_temperature_min',

View File

@ -20,7 +20,7 @@ VALID_CONFIG_MINIMAL = {
'platform': 'darksky', 'platform': 'darksky',
'api_key': 'foo', 'api_key': 'foo',
'forecast': [1, 2], 'forecast': [1, 2],
'monitored_conditions': ['summary', 'icon', 'temperature_max'], 'monitored_conditions': ['summary', 'icon', 'temperature_high'],
'update_interval': timedelta(seconds=120), 'update_interval': timedelta(seconds=120),
} }
} }
@ -30,7 +30,7 @@ INVALID_CONFIG_MINIMAL = {
'platform': 'darksky', 'platform': 'darksky',
'api_key': 'foo', 'api_key': 'foo',
'forecast': [1, 2], 'forecast': [1, 2],
'monitored_conditions': ['sumary', 'iocn', 'temperature_max'], 'monitored_conditions': ['sumary', 'iocn', 'temperature_high'],
'update_interval': timedelta(seconds=120), 'update_interval': timedelta(seconds=120),
} }
} }
@ -42,7 +42,7 @@ VALID_CONFIG_LANG_DE = {
'forecast': [1, 2], 'forecast': [1, 2],
'units': 'us', 'units': 'us',
'language': 'de', 'language': 'de',
'monitored_conditions': ['summary', 'icon', 'temperature_max', 'monitored_conditions': ['summary', 'icon', 'temperature_high',
'minutely_summary', 'hourly_summary', 'minutely_summary', 'hourly_summary',
'daily_summary', 'humidity', ], 'daily_summary', 'humidity', ],
'update_interval': timedelta(seconds=120), 'update_interval': timedelta(seconds=120),
@ -55,7 +55,7 @@ INVALID_CONFIG_LANG = {
'api_key': 'foo', 'api_key': 'foo',
'forecast': [1, 2], 'forecast': [1, 2],
'language': 'yz', 'language': 'yz',
'monitored_conditions': ['summary', 'icon', 'temperature_max'], 'monitored_conditions': ['summary', 'icon', 'temperature_high'],
'update_interval': timedelta(seconds=120), 'update_interval': timedelta(seconds=120),
} }
} }
@ -154,7 +154,7 @@ class TestDarkSkySetup(unittest.TestCase):
assert mock_get_forecast.called assert mock_get_forecast.called
assert mock_get_forecast.call_count == 1 assert mock_get_forecast.call_count == 1
assert len(self.hass.states.entity_ids()) == 9 assert len(self.hass.states.entity_ids()) == 8
state = self.hass.states.get('sensor.dark_sky_summary') state = self.hass.states.get('sensor.dark_sky_summary')
assert state is not None assert state is not None