From 8a4c12334681b06e2ba122b020bec7ea1289a98f Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 6 Dec 2018 21:20:26 +0100 Subject: [PATCH 1/4] Force refresh Lovelace --- homeassistant/components/lovelace/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/lovelace/__init__.py b/homeassistant/components/lovelace/__init__.py index 0d9b6a6d9fe890..ee1510adcb2b05 100644 --- a/homeassistant/components/lovelace/__init__.py +++ b/homeassistant/components/lovelace/__init__.py @@ -48,6 +48,7 @@ SCHEMA_GET_LOVELACE_UI = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({ vol.Required('type'): vol.Any(WS_TYPE_GET_LOVELACE_UI, OLD_WS_TYPE_GET_LOVELACE_UI), + vol.Optional('force', default=False): bool, }) SCHEMA_MIGRATE_CONFIG = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({ @@ -144,12 +145,12 @@ class DuplicateIdError(HomeAssistantError): """Duplicate ID's.""" -def load_config(hass) -> JSON_TYPE: +def load_config(hass, force: bool) -> JSON_TYPE: """Load a YAML file.""" fname = hass.config.path(LOVELACE_CONFIG_FILE) # Check for a cached version of the config - if LOVELACE_DATA in hass.data: + if not force and LOVELACE_DATA in hass.data: config, last_update = hass.data[LOVELACE_DATA] modtime = os.path.getmtime(fname) if config and last_update > modtime: @@ -539,7 +540,8 @@ async def send_with_error_handling(hass, connection, msg): @handle_yaml_errors async def websocket_lovelace_config(hass, connection, msg): """Send Lovelace UI config over WebSocket configuration.""" - return await hass.async_add_executor_job(load_config, hass) + return await hass.async_add_executor_job(load_config, hass, + msg.get('force', False)) @websocket_api.async_response From 4ad64b28191d57bf0e60b6942b81f915b53be3f8 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 6 Dec 2018 22:46:39 +0100 Subject: [PATCH 2/4] Check config on load --- homeassistant/components/lovelace/__init__.py | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/homeassistant/components/lovelace/__init__.py b/homeassistant/components/lovelace/__init__.py index ee1510adcb2b05..24bbc36d2dd6ea 100644 --- a/homeassistant/components/lovelace/__init__.py +++ b/homeassistant/components/lovelace/__init__.py @@ -159,23 +159,31 @@ def load_config(hass, force: bool) -> JSON_TYPE: config = yaml.load_yaml(fname, False) seen_card_ids = set() seen_view_ids = set() + if 'views' in config and not isinstance(config['views'], list): + raise HomeAssistantError("Views should be a list.") for view in config.get('views', []): - view_id = view.get('id') - if view_id: - view_id = str(view_id) - if view_id in seen_view_ids: - raise DuplicateIdError( - 'ID `{}` has multiple occurances in views'.format(view_id)) - seen_view_ids.add(view_id) + if 'id' in view and not (isinstance(view['id'], str) or + isinstance(view['id'], int)): + raise HomeAssistantError( + "Your config contains view(s) with invalid ID(s).") + view_id = str(view.get('id', '')) + if view_id in seen_view_ids: + raise DuplicateIdError( + 'ID `{}` has multiple occurances in views'.format(view_id)) + seen_view_ids.add(view_id) + if 'cards' in view and not isinstance(view['cards'], list): + raise HomeAssistantError("Cards should be a list.") for card in view.get('cards', []): - card_id = card.get('id') - if card_id: - card_id = str(card_id) - if card_id in seen_card_ids: - raise DuplicateIdError( - 'ID `{}` has multiple occurances in cards' - .format(card_id)) - seen_card_ids.add(card_id) + if 'id' in card and not (isinstance(card['id'], str) or + isinstance(card['id'], int)): + raise HomeAssistantError( + "Your config contains card(s) with invalid ID(s).") + card_id = str(card.get('id', '')) + if card_id in seen_card_ids: + raise DuplicateIdError( + 'ID `{}` has multiple occurances in cards' + .format(card_id)) + seen_card_ids.add(card_id) hass.data[LOVELACE_DATA] = (config, time.time()) return config From cf03909f7f15889c712dd5f6c945c92ca21f1176 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 7 Dec 2018 07:07:16 +0100 Subject: [PATCH 3/4] Update __init__.py --- homeassistant/components/lovelace/__init__.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/lovelace/__init__.py b/homeassistant/components/lovelace/__init__.py index 24bbc36d2dd6ea..85bc82a21497d6 100644 --- a/homeassistant/components/lovelace/__init__.py +++ b/homeassistant/components/lovelace/__init__.py @@ -162,8 +162,7 @@ def load_config(hass, force: bool) -> JSON_TYPE: if 'views' in config and not isinstance(config['views'], list): raise HomeAssistantError("Views should be a list.") for view in config.get('views', []): - if 'id' in view and not (isinstance(view['id'], str) or - isinstance(view['id'], int)): + if 'id' in view and not (isinstance(view['id'], (str, int)): raise HomeAssistantError( "Your config contains view(s) with invalid ID(s).") view_id = str(view.get('id', '')) @@ -174,8 +173,7 @@ def load_config(hass, force: bool) -> JSON_TYPE: if 'cards' in view and not isinstance(view['cards'], list): raise HomeAssistantError("Cards should be a list.") for card in view.get('cards', []): - if 'id' in card and not (isinstance(card['id'], str) or - isinstance(card['id'], int)): + if 'id' in card and not (isinstance(card['id'], (str, int)): raise HomeAssistantError( "Your config contains card(s) with invalid ID(s).") card_id = str(card.get('id', '')) From 16001dc42be6fdd8beb1ed34ade5859ccd56280f Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 7 Dec 2018 07:08:28 +0100 Subject: [PATCH 4/4] Update __init__.py --- homeassistant/components/lovelace/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/lovelace/__init__.py b/homeassistant/components/lovelace/__init__.py index 85bc82a21497d6..f6a8a3fd688021 100644 --- a/homeassistant/components/lovelace/__init__.py +++ b/homeassistant/components/lovelace/__init__.py @@ -162,7 +162,7 @@ def load_config(hass, force: bool) -> JSON_TYPE: if 'views' in config and not isinstance(config['views'], list): raise HomeAssistantError("Views should be a list.") for view in config.get('views', []): - if 'id' in view and not (isinstance(view['id'], (str, int)): + if 'id' in view and not isinstance(view['id'], (str, int)): raise HomeAssistantError( "Your config contains view(s) with invalid ID(s).") view_id = str(view.get('id', '')) @@ -173,7 +173,7 @@ def load_config(hass, force: bool) -> JSON_TYPE: if 'cards' in view and not isinstance(view['cards'], list): raise HomeAssistantError("Cards should be a list.") for card in view.get('cards', []): - if 'id' in card and not (isinstance(card['id'], (str, int)): + if 'id' in card and not isinstance(card['id'], (str, int)): raise HomeAssistantError( "Your config contains card(s) with invalid ID(s).") card_id = str(card.get('id', ''))