From b855f422efb0f8c3f9eb8fa89832232772db76cd Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen <paulus@paulusschoutsen.nl> Date: Thu, 23 Apr 2015 06:41:41 -0700 Subject: [PATCH] Tweak visibility config --- homeassistant/bootstrap.py | 9 +++-- homeassistant/const.py | 1 + homeassistant/helpers/entity.py | 64 +++++++++++++----------------- tests/test_helper_entity.py | 69 +++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 40 deletions(-) create mode 100644 tests/test_helper_entity.py diff --git a/homeassistant/bootstrap.py b/homeassistant/bootstrap.py index 17e8cb3391b..ecd5be36dee 100644 --- a/homeassistant/bootstrap.py +++ b/homeassistant/bootstrap.py @@ -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] diff --git a/homeassistant/const.py b/homeassistant/const.py index a1aa0df40d1..0e859eaf943 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -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" diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 07aaf9a234c..a39d46a29f6 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -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) +# Dict mapping entity_id to a boolean that overwrites the hidden property +_OVERWRITE_HIDDEN = {} -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) - - -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. """ diff --git a/tests/test_helper_entity.py b/tests/test_helper_entity.py new file mode 100644 index 00000000000..9645bbc40c0 --- /dev/null +++ b/tests/test_helper_entity.py @@ -0,0 +1,69 @@ +""" +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() + + def tearDown(self): # pylint: disable=invalid-name + """ Stop down stuff we started. """ + self.hass.stop() + + def test_default_hidden_not_in_attributes(self): + """ Test that the default hidden property is set to False. """ + self.entity.update_ha_state() + + 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)) + + self.entity.hidden = False + + 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)) + + entity.Entity.overwrite_hidden(self.entity.entity_id, None) + + 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) + + entity.Entity.overwrite_hidden(self.entity.entity_id, None) -- GitLab