From e2cc1564a0d1427ac10547099a637a8e9b32ddf7 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 30 Jan 2019 12:57:56 -0800 Subject: [PATCH] Add lovelace systeam health (#20592) --- homeassistant/components/lovelace/__init__.py | 52 ++++++++++++++- tests/common.py | 5 ++ tests/components/lovelace/test_init.py | 66 +++++++++++++++++++ 3 files changed, 120 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/lovelace/__init__.py b/homeassistant/components/lovelace/__init__.py index c3254d84a73..b4cb2b18dca 100644 --- a/homeassistant/components/lovelace/__init__.py +++ b/homeassistant/components/lovelace/__init__.py @@ -75,6 +75,9 @@ async def async_setup(hass, config): WS_TYPE_SAVE_CONFIG, websocket_lovelace_save_config, SCHEMA_SAVE_CONFIG) + hass.components.system_health.async_register_info( + DOMAIN, system_health_info) + return True @@ -86,11 +89,22 @@ class LovelaceStorage: self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) self._data = None + async def async_get_info(self): + """Return the YAML storage mode.""" + if self._data is None: + await self._load() + + if self._data['config'] is None: + return { + 'mode': 'auto-gen' + } + + return _config_info('storage', self._data['config']) + async def async_load(self, force): """Load config.""" if self._data is None: - data = await self._store.async_load() - self._data = data if data else {'config': None} + await self._load() config = self._data['config'] @@ -102,10 +116,15 @@ class LovelaceStorage: async def async_save(self, config): """Save config.""" if self._data is None: - self._data = {'config': None} + await self._load() self._data['config'] = config await self._store.async_save(self._data) + async def _load(self): + """Load the config.""" + data = await self._store.async_load() + self._data = data if data else {'config': None} + class LovelaceYAML: """Class to handle YAML-based Lovelace config.""" @@ -115,6 +134,19 @@ class LovelaceYAML: self.hass = hass self._cache = None + async def async_get_info(self): + """Return the YAML storage mode.""" + try: + config = await self.async_load(False) + except ConfigNotFound: + return { + 'mode': 'yaml', + 'error': '{} not found'.format( + self.hass.config.path(LOVELACE_CONFIG_FILE)) + } + + return _config_info('yaml', config) + async def async_load(self, force): """Load config.""" return await self.hass.async_add_executor_job(self._load_config, force) @@ -177,3 +209,17 @@ async def websocket_lovelace_config(hass, connection, msg): async def websocket_lovelace_save_config(hass, connection, msg): """Save Lovelace UI configuration.""" await hass.data[DOMAIN].async_save(msg['config']) + + +async def system_health_info(hass): + """Get info for the info page.""" + return await hass.data[DOMAIN].async_get_info() + + +def _config_info(mode, config): + """Generate info about the config.""" + return { + 'mode': mode, + 'resources': len(config.get('resources', [])), + 'views': len(config.get('views', [])) + } diff --git a/tests/common.py b/tests/common.py index 0f9b372c161..3642c5da6ec 100644 --- a/tests/common.py +++ b/tests/common.py @@ -890,3 +890,8 @@ async def flush_store(store): return await store._async_handle_write_data() + + +async def get_system_health_info(hass, domain): + """Get system health info.""" + return await hass.data['system_health']['info'][domain](hass) diff --git a/tests/components/lovelace/test_init.py b/tests/components/lovelace/test_init.py index 20490f8c0cd..7aa4ef0f5b3 100644 --- a/tests/components/lovelace/test_init.py +++ b/tests/components/lovelace/test_init.py @@ -4,6 +4,8 @@ from unittest.mock import patch from homeassistant.setup import async_setup_component from homeassistant.components import frontend, lovelace +from tests.common import get_system_health_info + async def test_lovelace_from_storage(hass, hass_ws_client, hass_storage): """Test we load lovelace config from storage.""" @@ -117,3 +119,67 @@ async def test_lovelace_from_yaml(hass, hass_ws_client): assert response['success'] assert response['result'] == {'hello': 'yo'} + + +async def test_system_health_info_autogen(hass): + """Test system health info endpoint.""" + assert await async_setup_component(hass, 'lovelace', {}) + info = await get_system_health_info(hass, 'lovelace') + assert info == {'mode': 'auto-gen'} + + +async def test_system_health_info_storage(hass, hass_storage): + """Test system health info endpoint.""" + hass_storage[lovelace.STORAGE_KEY] = { + 'key': 'lovelace', + 'version': 1, + 'data': { + 'config': { + 'resources': [], + 'views': [] + } + } + } + assert await async_setup_component(hass, 'lovelace', {}) + info = await get_system_health_info(hass, 'lovelace') + assert info == { + 'mode': 'storage', + 'resources': 0, + 'views': 0, + } + + +async def test_system_health_info_yaml(hass): + """Test system health info endpoint.""" + assert await async_setup_component(hass, 'lovelace', { + 'lovelace': { + 'mode': 'YAML' + } + }) + with patch('homeassistant.components.lovelace.load_yaml', return_value={ + 'views': [ + { + 'cards': [] + } + ] + }): + info = await get_system_health_info(hass, 'lovelace') + assert info == { + 'mode': 'yaml', + 'resources': 0, + 'views': 1, + } + + +async def test_system_health_info_yaml_not_found(hass): + """Test system health info endpoint.""" + assert await async_setup_component(hass, 'lovelace', { + 'lovelace': { + 'mode': 'YAML' + } + }) + info = await get_system_health_info(hass, 'lovelace') + assert info == { + 'mode': 'yaml', + 'error': "{} not found".format(hass.config.path('ui-lovelace.yaml')) + }