From bbdb7a6f4c201d8785f72b81b2f99e361e0d1a31 Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Wed, 23 Jan 2019 11:37:21 -0800 Subject: [PATCH 1/6] Hotfix for blink initialization failure. Fixes #20335 (#20351) --- homeassistant/components/blink/__init__.py | 2 +- requirements_all.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/blink/__init__.py b/homeassistant/components/blink/__init__.py index ac2a4574b9ccb0..57500fcc8a63e9 100644 --- a/homeassistant/components/blink/__init__.py +++ b/homeassistant/components/blink/__init__.py @@ -15,7 +15,7 @@ CONF_BINARY_SENSORS, CONF_SENSORS, CONF_FILENAME, CONF_MONITORED_CONDITIONS, TEMP_FAHRENHEIT) -REQUIREMENTS = ['blinkpy==0.11.1'] +REQUIREMENTS = ['blinkpy==0.11.2'] _LOGGER = logging.getLogger(__name__) diff --git a/requirements_all.txt b/requirements_all.txt index 4f96d15c61faec..549b8fe3503ec7 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -196,7 +196,7 @@ bellows==0.7.0 bimmer_connected==0.5.3 # homeassistant.components.blink -blinkpy==0.11.1 +blinkpy==0.11.2 # homeassistant.components.light.blinksticklight blinkstick==1.1.8 From 2b542b77895b37a5f434286455caad846afdcde0 Mon Sep 17 00:00:00 2001 From: Eliseo Martelli Date: Thu, 24 Jan 2019 02:05:16 +0100 Subject: [PATCH 2/6] [FIX] Time reporting incorrect in sensor.gtt (#20362) * quick fix * remove print statement * fixes * remove lambda * added pylint disable * should be fine now --- homeassistant/components/sensor/gtt.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/sensor/gtt.py b/homeassistant/components/sensor/gtt.py index f0e141f3549513..a64c743381df9e 100644 --- a/homeassistant/components/sensor/gtt.py +++ b/homeassistant/components/sensor/gtt.py @@ -79,8 +79,7 @@ def device_state_attributes(self): def update(self): """Update device state.""" self.data.get_data() - next_time = datetime.strptime( - self.data.state_bus['time'][0]['run'], "%H:%M") + next_time = get_datetime(self.data.state_bus) self._state = next_time.isoformat() @@ -99,8 +98,7 @@ def __init__(self, stop, bus_name): def get_data(self): """Get the data from the api.""" self.bus_list = self._pygtt.get_by_stop(self._stop) - self.bus_list.sort(key=lambda b: - datetime.strptime(b['time'][0]['run'], "%H:%M")) + self.bus_list.sort(key=get_datetime) if self._bus_name is not None: self.state_bus = self.get_bus_by_name() @@ -113,3 +111,13 @@ def get_bus_by_name(self): for bus in self.bus_list: if bus['bus_name'] == self._bus_name: return bus + + +def get_datetime(bus): + """Get the datetime from a bus.""" + bustime = datetime.strptime(bus['time'][0]['run'], "%H:%M") + now = datetime.now() + bustime = bustime.replace(year=now.year, month=now.month, day=now.day) + if bustime < now: + bustime = bustime + timedelta(days=1) + return bustime From 65d9460e09fff6cf40ae9f0c5ea09d450a91e0fe Mon Sep 17 00:00:00 2001 From: Diogo Gomes Date: Thu, 24 Jan 2019 05:14:21 +0000 Subject: [PATCH 3/6] Fix error when API doesn't return a forecast. (#20365) * add guard * wrong logic --- homeassistant/components/weather/ipma.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/homeassistant/components/weather/ipma.py b/homeassistant/components/weather/ipma.py index a2f5058ac1e804..fda0fef4f25951 100644 --- a/homeassistant/components/weather/ipma.py +++ b/homeassistant/components/weather/ipma.py @@ -116,6 +116,9 @@ def name(self): @property def condition(self): """Return the current condition.""" + if not self._forecast: + return + return next((k for k, v in CONDITION_CLASSES.items() if self._forecast[0].idWeatherType in v), None) From 3c32bfda95a3e82b74655a56f5818a33817cdf14 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 23 Jan 2019 21:12:38 -0800 Subject: [PATCH 4/6] Fix restore state crashing invalid entity ID (#20367) --- homeassistant/helpers/restore_state.py | 6 +++-- tests/helpers/test_restore_state.py | 34 +++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/homeassistant/helpers/restore_state.py b/homeassistant/helpers/restore_state.py index 33b612b555a035..355555ec9dc7b9 100644 --- a/homeassistant/helpers/restore_state.py +++ b/homeassistant/helpers/restore_state.py @@ -4,7 +4,8 @@ from datetime import timedelta, datetime from typing import Any, Dict, List, Set, Optional # noqa pylint_disable=unused-import -from homeassistant.core import HomeAssistant, callback, State, CoreState +from homeassistant.core import ( + HomeAssistant, callback, State, CoreState, valid_entity_id) from homeassistant.const import ( EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP) import homeassistant.util.dt as dt_util @@ -80,7 +81,8 @@ async def load_instance(hass: HomeAssistant) -> 'RestoreStateData': else: data.last_states = { item['state']['entity_id']: StoredState.from_dict(item) - for item in stored_states} + for item in stored_states + if valid_entity_id(item['state']['entity_id'])} _LOGGER.debug( 'Created cache with %s', list(data.last_states)) diff --git a/tests/helpers/test_restore_state.py b/tests/helpers/test_restore_state.py index b13bc87421b4e0..bc2ab6937c3aae 100644 --- a/tests/helpers/test_restore_state.py +++ b/tests/helpers/test_restore_state.py @@ -6,7 +6,8 @@ from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.entity import Entity from homeassistant.helpers.restore_state import ( - RestoreStateData, RestoreEntity, StoredState, DATA_RESTORE_STATE_TASK) + RestoreStateData, RestoreEntity, StoredState, DATA_RESTORE_STATE_TASK, + STORAGE_KEY) from homeassistant.util import dt as dt_util from asynctest import patch @@ -218,3 +219,34 @@ async def test_state_saved_on_remove(hass): # We should store the input boolean state when it is removed assert data.last_states['input_boolean.b0'].state.state == 'on' + + +async def test_restoring_invalid_entity_id(hass, hass_storage): + """Test restoring invalid entity IDs.""" + entity = RestoreEntity() + entity.hass = hass + entity.entity_id = 'test.invalid__entity_id' + now = dt_util.utcnow().isoformat() + hass_storage[STORAGE_KEY] = { + 'version': 1, + 'key': STORAGE_KEY, + 'data': [ + { + 'state': { + 'entity_id': 'test.invalid__entity_id', + 'state': 'off', + 'attributes': {}, + 'last_changed': now, + 'last_updated': now, + 'context': { + 'id': '3c2243ff5f30447eb12e7348cfd5b8ff', + 'user_id': None + } + }, + 'last_seen': dt_util.utcnow().isoformat() + } + ] + } + + state = await entity.async_get_last_state() + assert state is None From 2b2809a4c64fe328e20913fe589e3a98c2d48135 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 23 Jan 2019 21:13:55 -0800 Subject: [PATCH 5/6] Calling save before load would crash Lovelace storage (#20368) --- homeassistant/components/lovelace/__init__.py | 2 ++ tests/components/lovelace/test_init.py | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/homeassistant/components/lovelace/__init__.py b/homeassistant/components/lovelace/__init__.py index e6f122bce19542..c3254d84a73ccf 100644 --- a/homeassistant/components/lovelace/__init__.py +++ b/homeassistant/components/lovelace/__init__.py @@ -101,6 +101,8 @@ async def async_load(self, force): async def async_save(self, config): """Save config.""" + if self._data is None: + self._data = {'config': None} self._data['config'] = config await self._store.async_save(self._data) diff --git a/tests/components/lovelace/test_init.py b/tests/components/lovelace/test_init.py index 15548b28cfb3a8..20490f8c0cd9e6 100644 --- a/tests/components/lovelace/test_init.py +++ b/tests/components/lovelace/test_init.py @@ -50,6 +50,27 @@ async def test_lovelace_from_storage(hass, hass_ws_client, hass_storage): } +async def test_lovelace_from_storage_save_before_load(hass, hass_ws_client, + hass_storage): + """Test we can load lovelace config from storage.""" + assert await async_setup_component(hass, 'lovelace', {}) + client = await hass_ws_client(hass) + + # Store new config + await client.send_json({ + 'id': 6, + 'type': 'lovelace/config/save', + 'config': { + 'yo': 'hello' + } + }) + response = await client.receive_json() + assert response['success'] + assert hass_storage[lovelace.STORAGE_KEY]['data'] == { + 'config': {'yo': 'hello'} + } + + async def test_lovelace_from_yaml(hass, hass_ws_client): """Test we load lovelace config from yaml.""" assert await async_setup_component(hass, 'lovelace', { From 761385dea1d38099f1f3668074a32a1aee304305 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 23 Jan 2019 21:14:52 -0800 Subject: [PATCH 6/6] Bumped version to 0.86.1 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index ef9f7b38384289..aaac6fecb73711 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -2,7 +2,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 86 -PATCH_VERSION = '0' +PATCH_VERSION = '1' __short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION) __version__ = '{}.{}'.format(__short_version__, PATCH_VERSION) REQUIRED_PYTHON_VER = (3, 5, 3)