Merge pull request #1073 from MartinHjelmare/add-entity-online-prop

Add new 'available' property to entity.py
This commit is contained in:
Paulus Schoutsen 2016-01-31 15:59:28 -08:00
commit 10f79ab45d
2 changed files with 37 additions and 23 deletions

View File

@ -1,5 +1,5 @@
# coding: utf-8 # coding: utf-8
""" Constants used by Home Assistant components. """ """Constants used by Home Assistant components."""
__version__ = "0.13.0.dev0" __version__ = "0.13.0.dev0"
@ -59,6 +59,7 @@ STATE_ALARM_PENDING = 'pending'
STATE_ALARM_TRIGGERED = 'triggered' STATE_ALARM_TRIGGERED = 'triggered'
STATE_LOCKED = 'locked' STATE_LOCKED = 'locked'
STATE_UNLOCKED = 'unlocked' STATE_UNLOCKED = 'unlocked'
STATE_UNAVAILABLE = 'unavailable'
# #### STATE AND EVENT ATTRIBUTES #### # #### STATE AND EVENT ATTRIBUTES ####
# Contains current time for a TIME_CHANGED event # Contains current time for a TIME_CHANGED event

View File

@ -1,6 +1,5 @@
""" """
homeassistant.helpers.entity homeassistant.helpers.entity.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Provides ABC for entities in HA. Provides ABC for entities in HA.
""" """
@ -13,8 +12,8 @@ from homeassistant.util import ensure_unique_string, slugify
from homeassistant.const import ( from homeassistant.const import (
ATTR_FRIENDLY_NAME, ATTR_HIDDEN, ATTR_UNIT_OF_MEASUREMENT, ATTR_ICON, ATTR_FRIENDLY_NAME, ATTR_HIDDEN, ATTR_UNIT_OF_MEASUREMENT, ATTR_ICON,
DEVICE_DEFAULT_NAME, STATE_ON, STATE_OFF, STATE_UNKNOWN, TEMP_CELCIUS, DEVICE_DEFAULT_NAME, STATE_ON, STATE_OFF, STATE_UNKNOWN, STATE_UNAVAILABLE,
TEMP_FAHRENHEIT) TEMP_CELCIUS, TEMP_FAHRENHEIT)
# Dict mapping entity_id to a boolean that overwrites the hidden property # Dict mapping entity_id to a boolean that overwrites the hidden property
_OVERWRITE = defaultdict(dict) _OVERWRITE = defaultdict(dict)
@ -24,7 +23,7 @@ ENTITY_ID_PATTERN = re.compile(r"^(\w+)\.(\w+)$")
def generate_entity_id(entity_id_format, name, current_ids=None, hass=None): def generate_entity_id(entity_id_format, name, current_ids=None, hass=None):
""" Generate a unique entity ID based on given entity IDs or used ids. """ """Generate a unique entity ID based on given entity IDs or used ids."""
name = name.lower() or DEVICE_DEFAULT_NAME.lower() name = name.lower() or DEVICE_DEFAULT_NAME.lower()
if current_ids is None: if current_ids is None:
if hass is None: if hass is None:
@ -37,7 +36,7 @@ def generate_entity_id(entity_id_format, name, current_ids=None, hass=None):
def split_entity_id(entity_id): def split_entity_id(entity_id):
""" Splits a state entity_id into domain, object_id. """ """Split a state entity_id into domain, object_id."""
return entity_id.split(".", 1) return entity_id.split(".", 1)
@ -47,7 +46,8 @@ def valid_entity_id(entity_id):
class Entity(object): class Entity(object):
""" ABC for Home Assistant entities. """ """ABC for Home Assistant entities."""
# pylint: disable=no-self-use # pylint: disable=no-self-use
# SAFE TO OVERWRITE # SAFE TO OVERWRITE
@ -58,47 +58,53 @@ class Entity(object):
def should_poll(self): def should_poll(self):
""" """
Return True if entity has to be polled for state. Return True if entity has to be polled for state.
False if entity pushes its state to HA. False if entity pushes its state to HA.
""" """
return True return True
@property @property
def unique_id(self): def unique_id(self):
""" Returns a unique id. """ """Return a unique id."""
return "{}.{}".format(self.__class__, id(self)) return "{}.{}".format(self.__class__, id(self))
@property @property
def name(self): def name(self):
""" Returns the name of the entity. """ """Return the name of the entity."""
return DEVICE_DEFAULT_NAME return DEVICE_DEFAULT_NAME
@property @property
def state(self): def state(self):
""" Returns the state of the entity. """ """Return the state of the entity."""
return STATE_UNKNOWN return STATE_UNKNOWN
@property @property
def state_attributes(self): def state_attributes(self):
""" Returns the state attributes. """ """Return the state attributes."""
return None return None
@property @property
def unit_of_measurement(self): def unit_of_measurement(self):
""" Unit of measurement of this entity, if any. """ """Return the unit of measurement of this entity, if any."""
return None return None
@property @property
def icon(self): def icon(self):
""" Icon to use in the frontend, if any. """ """Return the icon to use in the frontend, if any."""
return None return None
@property @property
def hidden(self): def hidden(self):
""" Suggestion if the entity should be hidden from UIs. """ """Return True if the entity should be hidden from UIs."""
return False return False
@property
def available(self):
"""Return True if entity is available."""
return True
def update(self): def update(self):
""" Retrieve latest state. """ """Retrieve latest state."""
pass pass
entity_id = None entity_id = None
@ -112,7 +118,8 @@ class Entity(object):
def update_ha_state(self, force_refresh=False): def update_ha_state(self, force_refresh=False):
""" """
Updates Home Assistant with current state of entity. Update Home Assistant with current state of entity.
If force_refresh == True will update entity before setting state. If force_refresh == True will update entity before setting state.
""" """
if self.hass is None: if self.hass is None:
@ -128,6 +135,10 @@ class Entity(object):
state = str(self.state) state = str(self.state)
attr = self.state_attributes or {} attr = self.state_attributes or {}
if not self.available:
state = STATE_UNAVAILABLE
return self.hass.states.set(self.entity_id, state)
if ATTR_FRIENDLY_NAME not in attr and self.name is not None: if ATTR_FRIENDLY_NAME not in attr and self.name is not None:
attr[ATTR_FRIENDLY_NAME] = str(self.name) attr[ATTR_FRIENDLY_NAME] = str(self.name)
@ -170,6 +181,7 @@ class Entity(object):
def overwrite_attribute(entity_id, attrs, vals): def overwrite_attribute(entity_id, attrs, vals):
""" """
Overwrite any attribute of an entity. Overwrite any attribute of an entity.
This function should receive a list of attributes and a This function should receive a list of attributes and a
list of values. Set attribute to None to remove any overwritten list of values. Set attribute to None to remove any overwritten
value in place. value in place.
@ -182,29 +194,30 @@ class Entity(object):
class ToggleEntity(Entity): class ToggleEntity(Entity):
""" ABC for entities that can be turned on and off. """ """ABC for entities that can be turned on and off."""
# pylint: disable=no-self-use # pylint: disable=no-self-use
@property @property
def state(self): def state(self):
""" Returns the state. """ """Return the state."""
return STATE_ON if self.is_on else STATE_OFF return STATE_ON if self.is_on else STATE_OFF
@property @property
def is_on(self): def is_on(self):
""" True if entity is on. """ """True if entity is on."""
return False return False
def turn_on(self, **kwargs): def turn_on(self, **kwargs):
""" Turn the entity on. """ """Turn the entity on."""
pass pass
def turn_off(self, **kwargs): def turn_off(self, **kwargs):
""" Turn the entity off. """ """Turn the entity off."""
pass pass
def toggle(self, **kwargs): def toggle(self, **kwargs):
""" Toggle the entity off. """ """Toggle the entity off."""
if self.is_on: if self.is_on:
self.turn_off(**kwargs) self.turn_off(**kwargs)
else: else: