From e954b708a14178f0957ae52b726c6e637e217888 Mon Sep 17 00:00:00 2001 From: c727 Date: Tue, 23 Jan 2018 02:03:58 +0100 Subject: [PATCH 01/13] Component for custom frontend cards tbd --- homeassistant/components/custom_card.py | 95 +++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 homeassistant/components/custom_card.py diff --git a/homeassistant/components/custom_card.py b/homeassistant/components/custom_card.py new file mode 100644 index 00000000000000..56cb5dcc426232 --- /dev/null +++ b/homeassistant/components/custom_card.py @@ -0,0 +1,95 @@ +""" +Show custom ha-cards and sate-cards on Home Assistant frontend +""" +import asyncio +import logging + +import voluptuous as vol + +from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity_component import EntityComponent +import homeassistant.helpers.config_validation as cv + +DOMAIN = 'custom_card' + +ENTITY_ID_FORMAT_HA_CARD = 'custom_ha_card' + '.{}' +ENTITY_ID_FORMAT_STATE_CARD = 'custom_state_card' + '.{}' + +_LOGGER = logging.getLogger(__name__) + +CONF_HA_CARD = 'ha_card' +CONF_STATE_CARD = 'state_card' +CONF_MORE_INFO_CARD = 'more_info_card' +CONF_CONFIG = 'config' + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({ + cv.slug: vol.Any({ + vol.Optional(CONF_HA_CARD): cv.string, + vol.Optional(CONF_STATE_CARD): cv.string, + vol.Optional(CONF_MORE_INFO_CARD): cv.string, + vol.Optional(CONF_CONFIG): cv.match_all, + }, None) + }) +}, extra=vol.ALLOW_EXTRA) + + +@asyncio.coroutine +def async_setup(hass, config): + """Initialize custom card.""" + component = EntityComponent(_LOGGER, DOMAIN, hass) + + entities = [] + + for object_id, cfg in config[DOMAIN].items(): + if not cfg: + cfg = {} + + ha_card = cfg.get(CONF_HA_CARD) + state_card = cfg.get(CONF_STATE_CARD) + more_info_card = cfg.get(CONF_MORE_INFO_CARD) + config = cfg.get(CONF_CONFIG) + entities.append(CustomCard(object_id, ha_card, state_card, more_info_card, config)) + + + if not entities: + return False + + yield from component.async_add_entities(entities) + + return True + +class CustomCard(Entity): + """Representation of a custom card.""" + + def __init__(self, object_id, ha_card, state_card, more_info_card, config): + """Initialize a boolean input.""" + self._ha_card = ha_card + self._state_card = state_card + if self._ha_card: + self.entity_id = ENTITY_ID_FORMAT_HA_CARD.format(object_id) + else: + self.entity_id = ENTITY_ID_FORMAT_STATE_CARD.format(object_id) + self._more_info_card = more_info_card + self._config = config + + @property + def state(self): + """Return card as state.""" + if self._ha_card: + return self._ha_card + return self._state_card + + @property + def device_state_attributes(self): + """Return the state attributes.""" + _attributes = {} + if self._ha_card: + _attributes['ha_card'] = self._ha_card + if self._state_card: + _attributes['state_card'] = self._state_card + if self._more_info_card: + _attributes['more_info_card'] = self._more_info_card + if self._config: + _attributes['config'] = self._config + return _attributes From 87fef66784995dbe64fc89738417b04cde40bb7a Mon Sep 17 00:00:00 2001 From: c727 Date: Tue, 23 Jan 2018 15:29:16 +0100 Subject: [PATCH 02/13] Improve code --- homeassistant/components/custom_card.py | 48 ++++++++++++++----------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/homeassistant/components/custom_card.py b/homeassistant/components/custom_card.py index 56cb5dcc426232..2d5636738c049e 100644 --- a/homeassistant/components/custom_card.py +++ b/homeassistant/components/custom_card.py @@ -1,5 +1,8 @@ """ Show custom ha-cards and sate-cards on Home Assistant frontend + +For more details about this component, please refer to the documentation +at https://home-assistant.io/components/custom_card/ """ import asyncio import logging @@ -49,47 +52,50 @@ def async_setup(hass, config): state_card = cfg.get(CONF_STATE_CARD) more_info_card = cfg.get(CONF_MORE_INFO_CARD) config = cfg.get(CONF_CONFIG) - entities.append(CustomCard(object_id, ha_card, state_card, more_info_card, config)) + if ha_card == None and state_card == None: + _LOGGER.error("Entity config must contain ha_card and/or state_card ({}).".format(object_id)) + return False + + entities.append(CustomCard(object_id, ha_card, state_card, + more_info_card, config)) if not entities: - return False + return False yield from component.async_add_entities(entities) return True + class CustomCard(Entity): """Representation of a custom card.""" def __init__(self, object_id, ha_card, state_card, more_info_card, config): - """Initialize a boolean input.""" - self._ha_card = ha_card - self._state_card = state_card - if self._ha_card: + """Initialize a custom card.""" + if ha_card: self.entity_id = ENTITY_ID_FORMAT_HA_CARD.format(object_id) + self._state = ha_card else: self.entity_id = ENTITY_ID_FORMAT_STATE_CARD.format(object_id) - self._more_info_card = more_info_card - self._config = config + self._state = state_card + + self._attributes = {} + if ha_card: + self._attributes['ha_card'] = ha_card + if state_card: + self._attributes['state_card'] = state_card + if more_info_card: + self._attributes['more_info_card'] = more_info_card + if config: + self._attributes['config'] = config @property def state(self): """Return card as state.""" - if self._ha_card: - return self._ha_card - return self._state_card + return self._state @property def device_state_attributes(self): """Return the state attributes.""" - _attributes = {} - if self._ha_card: - _attributes['ha_card'] = self._ha_card - if self._state_card: - _attributes['state_card'] = self._state_card - if self._more_info_card: - _attributes['more_info_card'] = self._more_info_card - if self._config: - _attributes['config'] = self._config - return _attributes + return self._attributes From 21d28522344b2680b63a34ffd689688e9e4c8177 Mon Sep 17 00:00:00 2001 From: c727 Date: Tue, 23 Jan 2018 15:33:55 +0100 Subject: [PATCH 03/13] Fix Hound --- homeassistant/components/custom_card.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/custom_card.py b/homeassistant/components/custom_card.py index 2d5636738c049e..35fd1786c541bd 100644 --- a/homeassistant/components/custom_card.py +++ b/homeassistant/components/custom_card.py @@ -53,12 +53,13 @@ def async_setup(hass, config): more_info_card = cfg.get(CONF_MORE_INFO_CARD) config = cfg.get(CONF_CONFIG) - if ha_card == None and state_card == None: - _LOGGER.error("Entity config must contain ha_card and/or state_card ({}).".format(object_id)) + if ha_card is None and state_card is None: + _LOGGER.error("Entity config must contain ha_card " + + "and/or state_card ({}).".format(object_id)) return False entities.append(CustomCard(object_id, ha_card, state_card, - more_info_card, config)) + more_info_card, config)) if not entities: return False @@ -72,7 +73,7 @@ class CustomCard(Entity): """Representation of a custom card.""" def __init__(self, object_id, ha_card, state_card, more_info_card, config): - """Initialize a custom card.""" + """Initialize a custom card.""" if ha_card: self.entity_id = ENTITY_ID_FORMAT_HA_CARD.format(object_id) self._state = ha_card From 7720351fcd4ecb4fa94d5826c5f024d143b6aace Mon Sep 17 00:00:00 2001 From: c727 Date: Tue, 23 Jan 2018 15:44:57 +0100 Subject: [PATCH 04/13] Fix Hound --- homeassistant/components/custom_card.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/custom_card.py b/homeassistant/components/custom_card.py index 35fd1786c541bd..82b5b197aeaa88 100644 --- a/homeassistant/components/custom_card.py +++ b/homeassistant/components/custom_card.py @@ -55,11 +55,11 @@ def async_setup(hass, config): if ha_card is None and state_card is None: _LOGGER.error("Entity config must contain ha_card " + - "and/or state_card ({}).".format(object_id)) + "and/or state_card (%s)", object_id) return False entities.append(CustomCard(object_id, ha_card, state_card, - more_info_card, config)) + more_info_card, config)) if not entities: return False @@ -80,7 +80,7 @@ def __init__(self, object_id, ha_card, state_card, more_info_card, config): else: self.entity_id = ENTITY_ID_FORMAT_STATE_CARD.format(object_id) self._state = state_card - + self._attributes = {} if ha_card: self._attributes['ha_card'] = ha_card From 174da22ec1a7514d8509e7777d319e3dc692f3d0 Mon Sep 17 00:00:00 2001 From: c727 Date: Fri, 26 Jan 2018 16:48:56 +0100 Subject: [PATCH 05/13] Update based on feedback --- homeassistant/components/custom_card.py | 99 ++++++++++++++----------- 1 file changed, 54 insertions(+), 45 deletions(-) diff --git a/homeassistant/components/custom_card.py b/homeassistant/components/custom_card.py index 82b5b197aeaa88..4285375a7b08fa 100644 --- a/homeassistant/components/custom_card.py +++ b/homeassistant/components/custom_card.py @@ -1,5 +1,5 @@ """ -Show custom ha-cards and sate-cards on Home Assistant frontend +Show custom full-cards (ha-cards) and sate-cards on Home Assistant frontend For more details about this component, please refer to the documentation at https://home-assistant.io/components/custom_card/ @@ -9,18 +9,15 @@ import voluptuous as vol -from homeassistant.helpers.entity import Entity -from homeassistant.helpers.entity_component import EntityComponent +from aiohttp import web +from homeassistant.components import http import homeassistant.helpers.config_validation as cv DOMAIN = 'custom_card' -ENTITY_ID_FORMAT_HA_CARD = 'custom_ha_card' + '.{}' -ENTITY_ID_FORMAT_STATE_CARD = 'custom_state_card' + '.{}' - _LOGGER = logging.getLogger(__name__) -CONF_HA_CARD = 'ha_card' +CONF_FULL_CARD = 'full_card' CONF_STATE_CARD = 'state_card' CONF_MORE_INFO_CARD = 'more_info_card' CONF_CONFIG = 'config' @@ -28,7 +25,7 @@ CONFIG_SCHEMA = vol.Schema({ DOMAIN: vol.Schema({ cv.slug: vol.Any({ - vol.Optional(CONF_HA_CARD): cv.string, + vol.Optional(CONF_FULL_CARD): cv.string, vol.Optional(CONF_STATE_CARD): cv.string, vol.Optional(CONF_MORE_INFO_CARD): cv.string, vol.Optional(CONF_CONFIG): cv.match_all, @@ -40,63 +37,75 @@ @asyncio.coroutine def async_setup(hass, config): """Initialize custom card.""" - component = EntityComponent(_LOGGER, DOMAIN, hass) - entities = [] + card_configs = {} for object_id, cfg in config[DOMAIN].items(): if not cfg: cfg = {} - ha_card = cfg.get(CONF_HA_CARD) + full_card = cfg.get(CONF_FULL_CARD) state_card = cfg.get(CONF_STATE_CARD) more_info_card = cfg.get(CONF_MORE_INFO_CARD) config = cfg.get(CONF_CONFIG) - if ha_card is None and state_card is None: - _LOGGER.error("Entity config must contain ha_card " + + if full_card is None and state_card is None: + _LOGGER.error("Entity config must contain full_card " + "and/or state_card (%s)", object_id) return False - entities.append(CustomCard(object_id, ha_card, state_card, - more_info_card, config)) + if full_card: + entity_id = 'custom_full_card.{}'.format(object_id) + state = full_card + else: + entity_id = 'custom_sate_card.{}'.format(object_id) + state = state_card + + attributes = {} + if full_card: + attributes['full_card'] = full_card + if state_card: + attributes['state_card'] = state_card + if more_info_card: + attributes['more_info_card'] = more_info_card - if not entities: - return False + if config: + card_configs[entity_id] = config - yield from component.async_add_entities(entities) + hass.states.async_set(entity_id, state, attributes) + + hass.http.register_view(CustomCardView(card_configs)) return True -class CustomCard(Entity): - """Representation of a custom card.""" +class CustomCardView(http.HomeAssistantView): + """API to request card config.""" - def __init__(self, object_id, ha_card, state_card, more_info_card, config): - """Initialize a custom card.""" - if ha_card: - self.entity_id = ENTITY_ID_FORMAT_HA_CARD.format(object_id) - self._state = ha_card - else: - self.entity_id = ENTITY_ID_FORMAT_STATE_CARD.format(object_id) - self._state = state_card + url = '/api/custom_card' + name = 'api:custom_card' - self._attributes = {} - if ha_card: - self._attributes['ha_card'] = ha_card - if state_card: - self._attributes['state_card'] = state_card - if more_info_card: - self._attributes['more_info_card'] = more_info_card - if config: - self._attributes['config'] = config + def __init__(self, card_configs): + self._card_configs = card_configs - @property - def state(self): - """Return card as state.""" - return self._state + @http.RequestDataValidator(vol.Schema({ + vol.Required('entity_id'): str, + })) - @property - def device_state_attributes(self): - """Return the state attributes.""" - return self._attributes + @asyncio.coroutine + def post(self, request, data): + """Handle a config request.""" + try: + config = self._card_configs[data['entity_id']] + except KeyError: + res = { "config": None } + state = 400 + else: + res = { "config": config } + state = 200 + + return web.Response( + body = str(res), + status = state, + content_type = 'application/json', + ) From dac1609b2ae40ff62734131142caaafb1b08f9b1 Mon Sep 17 00:00:00 2001 From: c727 Date: Fri, 26 Jan 2018 16:51:49 +0100 Subject: [PATCH 06/13] Hound --- homeassistant/components/custom_card.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/custom_card.py b/homeassistant/components/custom_card.py index 4285375a7b08fa..c39d2d721c8dbf 100644 --- a/homeassistant/components/custom_card.py +++ b/homeassistant/components/custom_card.py @@ -73,7 +73,7 @@ def async_setup(hass, config): card_configs[entity_id] = config hass.states.async_set(entity_id, state, attributes) - + hass.http.register_view(CustomCardView(card_configs)) return True @@ -91,21 +91,20 @@ def __init__(self, card_configs): @http.RequestDataValidator(vol.Schema({ vol.Required('entity_id'): str, })) - @asyncio.coroutine def post(self, request, data): """Handle a config request.""" try: config = self._card_configs[data['entity_id']] except KeyError: - res = { "config": None } + res = {"config": None} state = 400 else: - res = { "config": config } + res = {"config": config} state = 200 return web.Response( - body = str(res), - status = state, - content_type = 'application/json', + body=str(res), + status=state, + content_type='application/json', ) From 2736fca3c1f91ef3da59c06b44e91f8ee7a054e0 Mon Sep 17 00:00:00 2001 From: c727 Date: Fri, 26 Jan 2018 17:16:08 +0100 Subject: [PATCH 07/13] Lint --- homeassistant/components/custom_card.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/custom_card.py b/homeassistant/components/custom_card.py index c39d2d721c8dbf..8d4e3f43c8433e 100644 --- a/homeassistant/components/custom_card.py +++ b/homeassistant/components/custom_card.py @@ -1,5 +1,5 @@ """ -Show custom full-cards (ha-cards) and sate-cards on Home Assistant frontend +Show custom full-cards (ha-cards) and sate-cards on Home Assistant frontend. For more details about this component, please refer to the documentation at https://home-assistant.io/components/custom_card/ @@ -37,7 +37,6 @@ @asyncio.coroutine def async_setup(hass, config): """Initialize custom card.""" - card_configs = {} for object_id, cfg in config[DOMAIN].items(): @@ -86,6 +85,7 @@ class CustomCardView(http.HomeAssistantView): name = 'api:custom_card' def __init__(self, card_configs): + """Initialize a custom card view.""" self._card_configs = card_configs @http.RequestDataValidator(vol.Schema({ From ac915aa5ec6128216b8b3b1c5bdeb9b2ec610777 Mon Sep 17 00:00:00 2001 From: c727 Date: Tue, 30 Jan 2018 01:38:46 +0100 Subject: [PATCH 08/13] Added tests, need help here --- tests/components/test_custom_card.py | 86 ++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 tests/components/test_custom_card.py diff --git a/tests/components/test_custom_card.py b/tests/components/test_custom_card.py new file mode 100644 index 00000000000000..2af9e5d9b77663 --- /dev/null +++ b/tests/components/test_custom_card.py @@ -0,0 +1,86 @@ +"""The tests the custom cards component.""" +# pylint: disable=protected-access +import asyncio +import unittest +import logging + +from homeassistant.core import CoreState, State +from homeassistant.setup import setup_component, async_setup_component +from homeassistant.components.custom_card import DOMAIN + +from tests.common import get_test_home_assistant + +_LOGGER = logging.getLogger(__name__) + + +class TestCustomCard(unittest.TestCase): + """Test the custom card module.""" + + # pylint: disable=invalid-name + def setUp(self): + """Setup things to be run when tests are started.""" + self.hass = get_test_home_assistant() + + # pylint: disable=invalid-name + def tearDown(self): + """Stop everything that was started.""" + self.hass.stop() + + def test_config(self): + """Test config.""" + invalid_configs = [ + None, + 1, + {}, + {'name with space': None}, + {'noCardsDefined': None}, + {'moreInfoOnly': {'more_info_card': 'test-card'}}, + ] + + for cfg in invalid_configs: + self.assertFalse( + setup_component(self.hass, DOMAIN, {DOMAIN: cfg})) + + + def test_config_options(self): + """Test configuration options.""" + count_start = len(self.hass.states.entity_ids()) + + _LOGGER.debug('ENTITIES @ start: %s', self.hass.states.entity_ids()) + + self.assertTrue(setup_component(self.hass, DOMAIN, {DOMAIN: { + 'test_1': { + 'full_card': 'full-card', + }, + 'test_2': { + 'state_card': 'state-card', + }, + 'test_3': { + 'full_card': 'full-card', + 'state_card': 'state-card', + 'more_info_card': 'more-info-card', + }, + }})) + + _LOGGER.debug('ENTITIES: %s', self.hass.states.entity_ids()) + + self.assertEqual(count_start + 3, len(self.hass.states.entity_ids())) + + state_1 = self.hass.states.get('custom_card.test_1') + state_2 = self.hass.states.get('custom_card.test_2') + state_3 = self.hass.states.get('custom_card.test_3') + + self.assertIsNotNone(state_1) + self.assertIsNotNone(state_2) + self.assertIsNotNone(state_3) + + self.assertEqual('full-card', state_1.state) + self.assertEqual('state-card', state_2.state) + self.assertEqual('full-card', state_3.state) + + self.assertEqual('full-card', + state_3.attributes.get('full_card')) + self.assertEqual('state-card', + state_3.attributes.get('state_card')) + self.assertEqual('more-info-card', + state_3.attributes.get('more_info_card')) From 53f7ff02c4c479bc78695380e79f1423bd4ef81e Mon Sep 17 00:00:00 2001 From: c727 Date: Tue, 30 Jan 2018 15:21:21 +0100 Subject: [PATCH 09/13] Improvenents for config --- homeassistant/components/custom_card.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/homeassistant/components/custom_card.py b/homeassistant/components/custom_card.py index 8d4e3f43c8433e..0c263e882a1b3a 100644 --- a/homeassistant/components/custom_card.py +++ b/homeassistant/components/custom_card.py @@ -5,12 +5,13 @@ at https://home-assistant.io/components/custom_card/ """ import asyncio +import json import logging import voluptuous as vol -from aiohttp import web from homeassistant.components import http +from homeassistant.const import HTTP_BAD_REQUEST import homeassistant.helpers.config_validation as cv DOMAIN = 'custom_card' @@ -62,14 +63,14 @@ def async_setup(hass, config): attributes = {} if full_card: - attributes['full_card'] = full_card + attributes['custom_ui_full_card'] = full_card if state_card: - attributes['state_card'] = state_card + attributes['custom_ui_state_card'] = state_card if more_info_card: - attributes['more_info_card'] = more_info_card + attributes['custom_ui_more_info_card'] = more_info_card if config: - card_configs[entity_id] = config + card_configs[entity_id] = json.dumps(config) hass.states.async_set(entity_id, state, attributes) @@ -97,14 +98,6 @@ def post(self, request, data): try: config = self._card_configs[data['entity_id']] except KeyError: - res = {"config": None} - state = 400 + return self.json_message('For this entity is no config available.', HTTP_BAD_REQUEST) else: - res = {"config": config} - state = 200 - - return web.Response( - body=str(res), - status=state, - content_type='application/json', - ) + return '{"config": ' + config + '}' From 5b1abbe25a3e049e279a61130cf769a73dc78faa Mon Sep 17 00:00:00 2001 From: c727 Date: Tue, 30 Jan 2018 15:25:06 +0100 Subject: [PATCH 10/13] Hound --- homeassistant/components/custom_card.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/custom_card.py b/homeassistant/components/custom_card.py index 0c263e882a1b3a..76ecf9c15d2db8 100644 --- a/homeassistant/components/custom_card.py +++ b/homeassistant/components/custom_card.py @@ -98,6 +98,7 @@ def post(self, request, data): try: config = self._card_configs[data['entity_id']] except KeyError: - return self.json_message('For this entity is no config available.', HTTP_BAD_REQUEST) + return self.json_message('For this entity is no config available.', + HTTP_BAD_REQUEST) else: return '{"config": ' + config + '}' From 56e40b4207e726010c939c57866b2a18e0724276 Mon Sep 17 00:00:00 2001 From: c727 Date: Tue, 30 Jan 2018 15:36:22 +0100 Subject: [PATCH 11/13] Update --- tests/components/test_custom_card.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/components/test_custom_card.py b/tests/components/test_custom_card.py index 2af9e5d9b77663..56d8018d3de68a 100644 --- a/tests/components/test_custom_card.py +++ b/tests/components/test_custom_card.py @@ -1,11 +1,9 @@ """The tests the custom cards component.""" # pylint: disable=protected-access -import asyncio import unittest import logging -from homeassistant.core import CoreState, State -from homeassistant.setup import setup_component, async_setup_component +from homeassistant.setup import setup_component from homeassistant.components.custom_card import DOMAIN from tests.common import get_test_home_assistant @@ -41,7 +39,6 @@ def test_config(self): self.assertFalse( setup_component(self.hass, DOMAIN, {DOMAIN: cfg})) - def test_config_options(self): """Test configuration options.""" count_start = len(self.hass.states.entity_ids()) @@ -53,7 +50,7 @@ def test_config_options(self): 'full_card': 'full-card', }, 'test_2': { - 'state_card': 'state-card', + 'state_card': 'state-card', }, 'test_3': { 'full_card': 'full-card', @@ -78,9 +75,9 @@ def test_config_options(self): self.assertEqual('state-card', state_2.state) self.assertEqual('full-card', state_3.state) - self.assertEqual('full-card', + self.assertEqual('custom_ui_full-card', state_3.attributes.get('full_card')) - self.assertEqual('state-card', - state_3.attributes.get('state_card')) - self.assertEqual('more-info-card', + self.assertEqual('custom_ui_state-card', + state_3.attributes.get('state_card')) + self.assertEqual('custom_ui_more-info-card', state_3.attributes.get('more_info_card')) From 7fd87f5a00dbead4ada4b82c6f738c54b31821f2 Mon Sep 17 00:00:00 2001 From: c727 Date: Wed, 31 Jan 2018 00:17:15 +0100 Subject: [PATCH 12/13] Fix component --- homeassistant/components/custom_card.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/custom_card.py b/homeassistant/components/custom_card.py index 76ecf9c15d2db8..2b7fadd174cfc3 100644 --- a/homeassistant/components/custom_card.py +++ b/homeassistant/components/custom_card.py @@ -15,6 +15,7 @@ import homeassistant.helpers.config_validation as cv DOMAIN = 'custom_card' +DEPENDENCIES = ['http'] _LOGGER = logging.getLogger(__name__) @@ -58,7 +59,7 @@ def async_setup(hass, config): entity_id = 'custom_full_card.{}'.format(object_id) state = full_card else: - entity_id = 'custom_sate_card.{}'.format(object_id) + entity_id = 'custom_state_card.{}'.format(object_id) state = state_card attributes = {} @@ -101,4 +102,4 @@ def post(self, request, data): return self.json_message('For this entity is no config available.', HTTP_BAD_REQUEST) else: - return '{"config": ' + config + '}' + return self.json({'config': config}) From 179c3645567daedc1cf0bae817411557d4241f03 Mon Sep 17 00:00:00 2001 From: c727 Date: Wed, 31 Jan 2018 00:17:34 +0100 Subject: [PATCH 13/13] Fix tests --- tests/components/test_custom_card.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/components/test_custom_card.py b/tests/components/test_custom_card.py index 56d8018d3de68a..8c6edd4bcc9337 100644 --- a/tests/components/test_custom_card.py +++ b/tests/components/test_custom_card.py @@ -63,9 +63,9 @@ def test_config_options(self): self.assertEqual(count_start + 3, len(self.hass.states.entity_ids())) - state_1 = self.hass.states.get('custom_card.test_1') - state_2 = self.hass.states.get('custom_card.test_2') - state_3 = self.hass.states.get('custom_card.test_3') + state_1 = self.hass.states.get('custom_full_card.test_1') + state_2 = self.hass.states.get('custom_state_card.test_2') + state_3 = self.hass.states.get('custom_full_card.test_3') self.assertIsNotNone(state_1) self.assertIsNotNone(state_2) @@ -75,9 +75,9 @@ def test_config_options(self): self.assertEqual('state-card', state_2.state) self.assertEqual('full-card', state_3.state) - self.assertEqual('custom_ui_full-card', - state_3.attributes.get('full_card')) - self.assertEqual('custom_ui_state-card', - state_3.attributes.get('state_card')) - self.assertEqual('custom_ui_more-info-card', - state_3.attributes.get('more_info_card')) + self.assertEqual('full-card', + state_3.attributes.get('custom_ui_full_card')) + self.assertEqual('state-card', + state_3.attributes.get('custom_ui_state_card')) + self.assertEqual('more-info-card', + state_3.attributes.get('custom_ui_more_info_card'))