mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 12:47:08 +00:00
Merge pull request #98 from balloob/chore-tweak-visibility-config
Tweak visibility config
This commit is contained in:
commit
44cd5ca15e
@ -33,18 +33,16 @@ These attributes are defined in [homeassistant.components](https://github.com/ba
|
||||
|
||||
## Proper Visibility Handling ##
|
||||
|
||||
Generally, when creating a new entity for Home Assistant you will want it to be a class that inherits the [homeassistant.helpers.entity.Entity](https://github.com/balloob/home-assistant/blob/master/homeassistant/helpers/entity.py] Class. If this is done, visibility will be handled for you.
|
||||
You can set a suggestion for your entitie's visibility by setting the hidden property by doing something similar to the following.
|
||||
Generally, when creating a new entity for Home Assistant you will want it to be a class that inherits the [homeassistant.helpers.entity.Entity](https://github.com/balloob/home-assistant/blob/master/homeassistant/helpers/entity.py) Class. If this is done, visibility will be handled for you.
|
||||
You can set a suggestion for your entity's visibility by setting the hidden property by doing something similar to the following.
|
||||
|
||||
```python
|
||||
self.hidden = True
|
||||
```
|
||||
|
||||
This will SUGGEST that the active frontend hide the entity. This requires that the active frontend support hidden cards (the default frontend does) and that the value of hidden be included in your attributes dictionary (see above). The Entity abstract class will take care of this for you.
|
||||
This will SUGGEST that the active frontend hides the entity. This requires that the active frontend support hidden cards (the default frontend does) and that the value of hidden be included in your attributes dictionary (see above). The Entity abstract class will take care of this for you.
|
||||
|
||||
Remember: The suggestion set by your component's code will always be overwritten by manual settings in the configuration.yaml file. This is why you may set hidden to be False, but the property may remain True (or vice-versa).
|
||||
|
||||
If you would not like to use the Entity Abstract Class, you may also inherity the Visibility Abstract Class which will include the logic for the hidden property but not automatically add the hidden property to the attributes dictionary. If you use this class, ensure that your class correctly adds the hidden property to the attributes.
|
||||
Remember: The suggestion set by your component's code will always be overwritten by user settings in the configuration.yaml file. This is why you may set hidden to be False, but the property may remain True (or vice-versa).
|
||||
|
||||
## Working on the frontend
|
||||
|
||||
|
@ -20,11 +20,11 @@ import homeassistant
|
||||
import homeassistant.loader as loader
|
||||
import homeassistant.components as core_components
|
||||
import homeassistant.components.group as group
|
||||
from homeassistant.helpers.entity import VisibilityABC
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.const import (
|
||||
EVENT_COMPONENT_LOADED, CONF_LATITUDE, CONF_LONGITUDE,
|
||||
CONF_TEMPERATURE_UNIT, CONF_NAME, CONF_TIME_ZONE, TEMP_CELCIUS,
|
||||
TEMP_FAHRENHEIT)
|
||||
CONF_TEMPERATURE_UNIT, CONF_NAME, CONF_TIME_ZONE, CONF_VISIBILITY,
|
||||
TEMP_CELCIUS, TEMP_FAHRENHEIT)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -208,7 +208,8 @@ def process_ha_core_config(hass, config):
|
||||
if key in config:
|
||||
setattr(hass.config, attr, config[key])
|
||||
|
||||
VisibilityABC.visibility.update(config.get('visibility', {}))
|
||||
for entity_id, hidden in config.get(CONF_VISIBILITY, {}).items():
|
||||
Entity.overwrite_hidden(entity_id, hidden == 'hide')
|
||||
|
||||
if CONF_TEMPERATURE_UNIT in config:
|
||||
unit = config[CONF_TEMPERATURE_UNIT]
|
||||
|
@ -11,6 +11,7 @@ CONF_LONGITUDE = "longitude"
|
||||
CONF_TEMPERATURE_UNIT = "temperature_unit"
|
||||
CONF_NAME = "name"
|
||||
CONF_TIME_ZONE = "time_zone"
|
||||
CONF_VISIBILITY = "visibility"
|
||||
|
||||
CONF_PLATFORM = "platform"
|
||||
CONF_HOST = "host"
|
||||
|
@ -11,45 +11,16 @@ from homeassistant.const import (
|
||||
ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT, ATTR_HIDDEN, STATE_ON,
|
||||
STATE_OFF, DEVICE_DEFAULT_NAME, TEMP_CELCIUS, TEMP_FAHRENHEIT)
|
||||
|
||||
|
||||
class VisibilityABC(object):
|
||||
"""
|
||||
Abstract Class for including visibility logic. This class includes the
|
||||
necessary methods and properties to consider a visibility suggestion form
|
||||
the component and then determine visibility based on the options in the
|
||||
configuration file. When using this abstract class, the value for the
|
||||
hidden property must still be included in the attributes disctionary. The
|
||||
Entity class takes care of this automatically.
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
entity_id = None
|
||||
visibility = {}
|
||||
_hidden = False
|
||||
|
||||
@property
|
||||
def hidden(self):
|
||||
"""
|
||||
Returns the official decision of whether the entity should be hidden.
|
||||
Any value set by the user in the configuration file will overwrite
|
||||
whatever the component sets for visibility.
|
||||
"""
|
||||
if self.entity_id is not None and \
|
||||
self.entity_id.lower() in self.visibility:
|
||||
return self.visibility[self.entity_id.lower()] == 'hide'
|
||||
else:
|
||||
return self._hidden
|
||||
|
||||
@hidden.setter
|
||||
def hidden(self, val):
|
||||
""" Sets the suggestion for visibility. """
|
||||
self._hidden = bool(val)
|
||||
# Dict mapping entity_id to a boolean that overwrites the hidden property
|
||||
_OVERWRITE_HIDDEN = {}
|
||||
|
||||
|
||||
class Entity(VisibilityABC):
|
||||
class Entity(object):
|
||||
""" ABC for Home Assistant entities. """
|
||||
# pylint: disable=no-self-use
|
||||
|
||||
_hidden = False
|
||||
|
||||
# SAFE TO OVERWRITE
|
||||
# The properties and methods here are safe to overwrite when inherting this
|
||||
# class. These may be used to customize the behavior of the entity.
|
||||
@ -87,6 +58,16 @@ class Entity(VisibilityABC):
|
||||
""" Unit of measurement of this entity, if any. """
|
||||
return None
|
||||
|
||||
@property
|
||||
def hidden(self):
|
||||
""" Suggestion if the entity should be hidden from UIs. """
|
||||
return self._hidden
|
||||
|
||||
@hidden.setter
|
||||
def hidden(self, val):
|
||||
""" Sets the suggestion for visibility. """
|
||||
self._hidden = bool(val)
|
||||
|
||||
def update(self):
|
||||
""" Retrieve latest state. """
|
||||
pass
|
||||
@ -140,8 +121,8 @@ class Entity(VisibilityABC):
|
||||
if ATTR_UNIT_OF_MEASUREMENT not in attr and self.unit_of_measurement:
|
||||
attr[ATTR_UNIT_OF_MEASUREMENT] = self.unit_of_measurement
|
||||
|
||||
if ATTR_HIDDEN not in attr:
|
||||
attr[ATTR_HIDDEN] = bool(self.hidden)
|
||||
if _OVERWRITE_HIDDEN.get(self.entity_id, self.hidden):
|
||||
attr[ATTR_HIDDEN] = True
|
||||
|
||||
# Convert temperature if we detect one
|
||||
if attr.get(ATTR_UNIT_OF_MEASUREMENT) in (TEMP_CELCIUS,
|
||||
@ -161,6 +142,17 @@ class Entity(VisibilityABC):
|
||||
def __repr__(self):
|
||||
return "<Entity {}: {}>".format(self.name, self.state)
|
||||
|
||||
@staticmethod
|
||||
def overwrite_hidden(entity_id, hidden):
|
||||
"""
|
||||
Overwrite the hidden property of an entity.
|
||||
Set hidden to None to remove any overwritten value in place.
|
||||
"""
|
||||
if hidden is None:
|
||||
_OVERWRITE_HIDDEN.pop(entity_id, None)
|
||||
else:
|
||||
_OVERWRITE_HIDDEN[entity_id.lower()] = hidden
|
||||
|
||||
|
||||
class ToggleEntity(Entity):
|
||||
""" ABC for entities that can be turned on and off. """
|
||||
|
60
tests/test_helper_entity.py
Normal file
60
tests/test_helper_entity.py
Normal file
@ -0,0 +1,60 @@
|
||||
"""
|
||||
tests.test_helper_entity
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Tests the entity helper.
|
||||
"""
|
||||
# pylint: disable=protected-access,too-many-public-methods
|
||||
import unittest
|
||||
|
||||
import homeassistant as ha
|
||||
import homeassistant.helpers.entity as entity
|
||||
from homeassistant.const import ATTR_HIDDEN
|
||||
|
||||
|
||||
class TestHelpersEntity(unittest.TestCase):
|
||||
""" Tests homeassistant.helpers.entity module. """
|
||||
|
||||
def setUp(self): # pylint: disable=invalid-name
|
||||
""" Init needed objects. """
|
||||
self.entity = entity.Entity()
|
||||
self.entity.entity_id = 'test.overwrite_hidden_true'
|
||||
self.hass = self.entity.hass = ha.HomeAssistant()
|
||||
self.entity.update_ha_state()
|
||||
|
||||
def tearDown(self): # pylint: disable=invalid-name
|
||||
""" Stop down stuff we started. """
|
||||
self.hass.stop()
|
||||
entity.Entity.overwrite_hidden(self.entity.entity_id, None)
|
||||
|
||||
def test_default_hidden_not_in_attributes(self):
|
||||
""" Test that the default hidden property is set to False. """
|
||||
self.assertNotIn(
|
||||
ATTR_HIDDEN,
|
||||
self.hass.states.get(self.entity.entity_id).attributes)
|
||||
|
||||
def test_setting_hidden_to_true(self):
|
||||
self.entity.hidden = True
|
||||
self.entity.update_ha_state()
|
||||
|
||||
state = self.hass.states.get(self.entity.entity_id)
|
||||
|
||||
self.assertTrue(state.attributes.get(ATTR_HIDDEN))
|
||||
|
||||
def test_overwriting_hidden_property_to_true(self):
|
||||
""" Test we can overwrite hidden property to True. """
|
||||
entity.Entity.overwrite_hidden(self.entity.entity_id, True)
|
||||
self.entity.update_ha_state()
|
||||
|
||||
state = self.hass.states.get(self.entity.entity_id)
|
||||
self.assertTrue(state.attributes.get(ATTR_HIDDEN))
|
||||
|
||||
def test_overwriting_hidden_property_to_false(self):
|
||||
""" Test we can overwrite hidden property to True. """
|
||||
entity.Entity.overwrite_hidden(self.entity.entity_id, False)
|
||||
self.entity.hidden = True
|
||||
self.entity.update_ha_state()
|
||||
|
||||
self.assertNotIn(
|
||||
ATTR_HIDDEN,
|
||||
self.hass.states.get(self.entity.entity_id).attributes)
|
Loading…
x
Reference in New Issue
Block a user