Skip to content

Component for custom frontend cards#11866

Closed
c727 wants to merge 13 commits intohome-assistant:devfrom
c727:patch-1
Closed

Component for custom frontend cards#11866
c727 wants to merge 13 commits intohome-assistant:devfrom
c727:patch-1

Conversation

@c727
Copy link
Copy Markdown

@c727 c727 commented Jan 23, 2018

Description:

Show custom ha-cards and sate-cards on Home Assistant frontend (custom ui)

For more details or discussion please check the frontend PR.

Frontend PR: home-assistant/frontend#831
Docs PR: home-assistant/home-assistant.io#4552

Checklist:

  • The code change is tested and works locally.

If user exposed functionality or configuration variables are added/changed:

If the code does not interact with devices:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • Tests have been added to verify that the new code works.

Comment thread homeassistant/components/custom_card.py Outdated

return True

class CustomCard(Entity):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected 2 blank lines, found 1

Comment thread homeassistant/components/custom_card.py Outdated


if not entities:
return False
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trailing whitespace

Comment thread homeassistant/components/custom_card.py Outdated
entities.append(CustomCard(object_id, ha_card, state_card, more_info_card, config))


if not entities:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too many blank lines (2)

Comment thread homeassistant/components/custom_card.py Outdated
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))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (91 > 79 characters)

@c727 c727 changed the title Component for custom frontend cards [WIP] Component for custom frontend cards Jan 23, 2018
Comment thread homeassistant/components/custom_card.py Outdated
else:
self.entity_id = ENTITY_ID_FORMAT_STATE_CARD.format(object_id)
self._state = state_card

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank line contains whitespace

Comment thread homeassistant/components/custom_card.py Outdated
"""Representation of a custom card."""

def __init__(self, object_id, ha_card, state_card, more_info_card, config):
"""Initialize a custom card."""
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trailing whitespace

Comment thread homeassistant/components/custom_card.py Outdated
return False

entities.append(CustomCard(object_id, ha_card, state_card,
more_info_card, config))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line over-indented for visual indent

Comment thread homeassistant/components/custom_card.py Outdated
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))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (105 > 79 characters)

Comment thread homeassistant/components/custom_card.py Outdated
more_info_card = cfg.get(CONF_MORE_INFO_CARD)
config = cfg.get(CONF_CONFIG)

if ha_card == None and state_card == None:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comparison to None should be 'if cond is None:'

Comment thread homeassistant/components/custom_card.py Outdated
return False

entities.append(CustomCard(object_id, ha_card, state_card,
more_info_card, config))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

Comment thread homeassistant/components/custom_card.py Outdated

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))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

Comment thread homeassistant/components/custom_card.py Outdated

DOMAIN = 'custom_card'

ENTITY_ID_FORMAT_HA_CARD = 'custom_ha_card' + '.{}'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Components are only allowed to create entities with the domain of the entity equal to the component name.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I should create 2 components instead? The problem is that cards on frontend are domain specific

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm.. let me check the code again...

@balloob
Copy link
Copy Markdown
Member

balloob commented Jan 24, 2018

Great idea!

Don't forget to add tests.

@andrey-git
Copy link
Copy Markdown
Contributor

I think this solution is too partial.

There are a few issue that we want to solve:

  1. Use UI-only component like floorplan. Using this new custom_component for this is no easier than using sensor.template or something similar.
  2. Passing configuration to UI custom components: This solution doesn't address that at all.
  3. Changing a state-card/full-card/more-info - this addresses this for UI-only component, but "real" components still need to use customize.

My proposal (all steps independent):

  1. Make a (core) service instead that can add/remove a dummy entity, like is already implemented for groups.
  2. Implement the proposal from here: RFC: Customization and attributes #10732 (comment) to make a component that hold config data.
  3. The FE PR can still be submitted with minor changes - state/full/more-info cards are controlled via attributes set by customize (and will move to config from (2) once implemented)

@c727
Copy link
Copy Markdown
Author

c727 commented Jan 24, 2018

thanks for the feedback and linking your RFC, I will check it :)

@c727
Copy link
Copy Markdown
Author

c727 commented Jan 24, 2018

@andrey-git

  1. I can't understand your comparison with template.sensor. Custom_card cards use their own entity instead of hijacking another entity's card. Also I don't see an advantage in using a service since I don't want to add/remove/change my entities/cards at runtime
  2. As I suggested in frontend PR I'd like to add an API to load the config. Is there a path to store data in frontend like window.storage.domain[domain].config or window.storage.entity[entity_id].config as I don't want to call the API 3 times (one for every cardtype) for each entity?
  3. Correct, "real" components still should use customize:. Also the config API is only for custom_card UI's and not for "real" component cards or for your state-card-custom-ui.

@balloob
I need 2 domains since full card or state card is bound to domain name. I can create 2/3 (2 services) separate components if you want?

@balloob
Copy link
Copy Markdown
Member

balloob commented Jan 25, 2018

Note that there is already an API to create/update "dummy" entities. It's the StateMachine set_state API.

It's however lower layer and thus shouldn't be linked to services (it's available via Rest API though).

You can always do a custom component like this:

@asyncio.coroutine
def async_setup(hass, config):
    hass.states.async_set('custom_card.bla', 'yay', { 'custom_card': 'slim-camera' })

Comment thread homeassistant/components/custom_card.py Outdated
return web.Response(
body = str(res),
status = state,
content_type = 'application/json',
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unexpected spaces around keyword / parameter equals

Comment thread homeassistant/components/custom_card.py Outdated

return web.Response(
body = str(res),
status = state,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unexpected spaces around keyword / parameter equals

Comment thread homeassistant/components/custom_card.py Outdated
state = 200

return web.Response(
body = str(res),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unexpected spaces around keyword / parameter equals

Comment thread homeassistant/components/custom_card.py Outdated
res = { "config": None }
state = 400
else:
res = { "config": config }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whitespace after '{'
whitespace before '}'

Comment thread homeassistant/components/custom_card.py Outdated
try:
config = self._card_configs[data['entity_id']]
except KeyError:
res = { "config": None }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whitespace after '{'
whitespace before '}'

vol.Required('entity_id'): str,
}))

@asyncio.coroutine
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank lines found after function decorator

Comment thread homeassistant/components/custom_card.py Outdated
card_configs[entity_id] = config

hass.states.async_set(entity_id, state, attributes)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank line contains whitespace

Comment thread tests/components/test_custom_card.py Outdated
self.assertEqual('full-card',
state_3.attributes.get('full_card'))
self.assertEqual('state-card',
state_3.attributes.get('state_card'))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trailing whitespace

Comment thread tests/components/test_custom_card.py Outdated
'full_card': 'full-card',
},
'test_2': {
'state_card': 'state-card',
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trailing whitespace

setup_component(self.hass, DOMAIN, {DOMAIN: cfg}))


def test_config_options(self):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too many blank lines (2)

Comment thread tests/components/test_custom_card.py Outdated
import logging

from homeassistant.core import CoreState, State
from homeassistant.setup import setup_component, async_setup_component
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'homeassistant.setup.async_setup_component' imported but unused

Comment thread tests/components/test_custom_card.py Outdated
import unittest
import logging

from homeassistant.core import CoreState, State
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'homeassistant.core.CoreState' imported but unused
'homeassistant.core.State' imported but unused

Comment thread tests/components/test_custom_card.py Outdated
@@ -0,0 +1,86 @@
"""The tests the custom cards component."""
# pylint: disable=protected-access
import asyncio
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'asyncio' imported but unused

Comment thread homeassistant/components/custom_card.py Outdated
try:
config = self._card_configs[data['entity_id']]
except KeyError:
return self.json_message('For this entity is no config available.', HTTP_BAD_REQUEST)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (97 > 79 characters)

@c727 c727 changed the title [WIP] Component for custom frontend cards Component for custom frontend cards Jan 30, 2018
config = self._card_configs[data['entity_id']]
except KeyError:
return self.json_message('For this entity is no config available.',
HTTP_BAD_REQUEST)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be 404 (not found) instead of 400 (bad request)

more_info_card = cfg.get(CONF_MORE_INFO_CARD)
config = cfg.get(CONF_CONFIG)

if full_card is None and state_card is None:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if config:
card_configs[entity_id] = json.dumps(config)

hass.states.async_set(entity_id, state, attributes)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need 2 components. We can't have 1 component create entities that are under another domain.

@c727
Copy link
Copy Markdown
Author

c727 commented Feb 28, 2018

functionality will be included in frontend entity registry

@c727 c727 closed this Feb 28, 2018
@home-assistant home-assistant locked and limited conversation to collaborators May 29, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants