Refactor helper.device to helper.entity
Introduces a minor backwards compatible change: device_component function add_devices is renamed to add_entities.
This commit is contained in:
parent
c8401a3c4d
commit
d3f0210b1a
6 changed files with 297 additions and 274 deletions
|
@ -48,8 +48,8 @@ def setup(hass, config):
|
||||||
|
|
||||||
component = DeviceComponent(logger, DOMAIN, hass)
|
component = DeviceComponent(logger, DOMAIN, hass)
|
||||||
|
|
||||||
component.add_devices(Scene(hass, _process_config(scene_config))
|
component.add_entities(Scene(hass, _process_config(scene_config))
|
||||||
for scene_config in scene_configs)
|
for scene_config in scene_configs)
|
||||||
|
|
||||||
def handle_scene_service(service):
|
def handle_scene_service(service):
|
||||||
""" Handles calls to the switch services. """
|
""" Handles calls to the switch services. """
|
||||||
|
|
|
@ -5,9 +5,9 @@ from homeassistant.loader import get_component
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, CONF_PLATFORM
|
from homeassistant.const import ATTR_ENTITY_ID, CONF_PLATFORM
|
||||||
from homeassistant.util import ensure_unique_string, slugify
|
from homeassistant.util import ensure_unique_string, slugify
|
||||||
|
|
||||||
# Deprecated 3/5/2015 - Moved to homeassistant.helpers.device
|
# Deprecated 3/5/2015 - Moved to homeassistant.helpers.entity
|
||||||
# pylint: disable=unused-import
|
# pylint: disable=unused-import
|
||||||
from .device import Device, ToggleDevice # noqa
|
from .entity import Entity as Device, ToggleEntity as ToggleDevice # noqa
|
||||||
|
|
||||||
|
|
||||||
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):
|
||||||
|
|
|
@ -1,139 +1,10 @@
|
||||||
"""
|
"""
|
||||||
homeassistant.helpers.device
|
Deprecated since 3/21/2015 - please use helpers.entity
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Provides ABC for devices in HA.
|
|
||||||
"""
|
"""
|
||||||
|
import logging
|
||||||
|
|
||||||
from homeassistant import NoEntitySpecifiedError
|
# pylint: disable=unused-import
|
||||||
|
from .entity import Entity as Device, ToggleEntity as ToggleDevice # noqa
|
||||||
|
|
||||||
from homeassistant.const import (
|
logging.getLogger(__name__).warning(
|
||||||
ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT, STATE_ON, STATE_OFF,
|
'This file is deprecated. Please use helpers.entity')
|
||||||
DEVICE_DEFAULT_NAME, TEMP_CELCIUS, TEMP_FAHRENHEIT)
|
|
||||||
|
|
||||||
|
|
||||||
class Device(object):
|
|
||||||
""" ABC for Home Assistant devices. """
|
|
||||||
# pylint: disable=no-self-use
|
|
||||||
|
|
||||||
hass = None
|
|
||||||
entity_id = None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def should_poll(self):
|
|
||||||
"""
|
|
||||||
Return True if device has to be polled for state.
|
|
||||||
False if device pushes its state to HA.
|
|
||||||
"""
|
|
||||||
return True
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unique_id(self):
|
|
||||||
""" Returns a unique id. """
|
|
||||||
return "{}.{}".format(self.__class__, id(self))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
""" Returns the name of the device. """
|
|
||||||
return self.get_name()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def state(self):
|
|
||||||
""" Returns the state of the device. """
|
|
||||||
return self.get_state()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def state_attributes(self):
|
|
||||||
""" Returns the state attributes. """
|
|
||||||
return {}
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unit_of_measurement(self):
|
|
||||||
""" Unit of measurement of this entity if any. """
|
|
||||||
return None
|
|
||||||
|
|
||||||
# DEPRECATION NOTICE:
|
|
||||||
# Device is moving from getters to properties.
|
|
||||||
# For now the new properties will call the old functions
|
|
||||||
# This will be removed in the future.
|
|
||||||
|
|
||||||
def get_name(self):
|
|
||||||
""" Returns the name of the device if any. """
|
|
||||||
return DEVICE_DEFAULT_NAME
|
|
||||||
|
|
||||||
def get_state(self):
|
|
||||||
""" Returns state of the device. """
|
|
||||||
return "Unknown"
|
|
||||||
|
|
||||||
def get_state_attributes(self):
|
|
||||||
""" Returns optional state attributes. """
|
|
||||||
return None
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
""" Retrieve latest state from the real device. """
|
|
||||||
pass
|
|
||||||
|
|
||||||
def update_ha_state(self, force_refresh=False):
|
|
||||||
"""
|
|
||||||
Updates Home Assistant with current state of device.
|
|
||||||
If force_refresh == True will update device before setting state.
|
|
||||||
"""
|
|
||||||
if self.hass is None:
|
|
||||||
raise RuntimeError("Attribute hass is None for {}".format(self))
|
|
||||||
|
|
||||||
if self.entity_id is None:
|
|
||||||
raise NoEntitySpecifiedError(
|
|
||||||
"No entity specified for device {}".format(self.name))
|
|
||||||
|
|
||||||
if force_refresh:
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
state = str(self.state)
|
|
||||||
attr = self.state_attributes or {}
|
|
||||||
|
|
||||||
if ATTR_FRIENDLY_NAME not in attr and self.name:
|
|
||||||
attr[ATTR_FRIENDLY_NAME] = self.name
|
|
||||||
|
|
||||||
if ATTR_UNIT_OF_MEASUREMENT not in attr and self.unit_of_measurement:
|
|
||||||
attr[ATTR_UNIT_OF_MEASUREMENT] = self.unit_of_measurement
|
|
||||||
|
|
||||||
# Convert temperature if we detect one
|
|
||||||
if attr.get(ATTR_UNIT_OF_MEASUREMENT) in (TEMP_CELCIUS,
|
|
||||||
TEMP_FAHRENHEIT):
|
|
||||||
|
|
||||||
state, attr[ATTR_UNIT_OF_MEASUREMENT] = \
|
|
||||||
self.hass.config.temperature(
|
|
||||||
state, attr[ATTR_UNIT_OF_MEASUREMENT])
|
|
||||||
state = str(state)
|
|
||||||
|
|
||||||
return self.hass.states.set(self.entity_id, state, attr)
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
return (isinstance(other, Device) and
|
|
||||||
other.unique_id == self.unique_id)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<Device {}: {}>".format(self.name, self.state)
|
|
||||||
|
|
||||||
|
|
||||||
class ToggleDevice(Device):
|
|
||||||
""" ABC for devices that can be turned on and off. """
|
|
||||||
# pylint: disable=no-self-use
|
|
||||||
|
|
||||||
@property
|
|
||||||
def state(self):
|
|
||||||
""" Returns the state. """
|
|
||||||
return STATE_ON if self.is_on else STATE_OFF
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_on(self):
|
|
||||||
""" True if device is on. """
|
|
||||||
return False
|
|
||||||
|
|
||||||
def turn_on(self, **kwargs):
|
|
||||||
""" Turn the device on. """
|
|
||||||
pass
|
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
|
||||||
""" Turn the device off. """
|
|
||||||
pass
|
|
||||||
|
|
|
@ -1,139 +1,10 @@
|
||||||
"""
|
"""
|
||||||
Provides helpers for components that handle devices.
|
Deprecated since 3/21/2015 - please use helpers.entity_component
|
||||||
"""
|
"""
|
||||||
from homeassistant.loader import get_component
|
import logging
|
||||||
from homeassistant.helpers import (
|
|
||||||
generate_entity_id, config_per_platform, extract_entity_ids)
|
|
||||||
from homeassistant.components import group, discovery
|
|
||||||
from homeassistant.const import ATTR_ENTITY_ID
|
|
||||||
|
|
||||||
DEFAULT_SCAN_INTERVAL = 15
|
# pylint: disable=unused-import
|
||||||
|
from .entity_component import EntityComponent as DeviceComponent # noqa
|
||||||
|
|
||||||
|
logging.getLogger(__name__).warning(
|
||||||
class DeviceComponent(object):
|
'This file is deprecated. Please use helpers.entity_component')
|
||||||
# pylint: disable=too-many-instance-attributes
|
|
||||||
# pylint: disable=too-many-arguments
|
|
||||||
"""
|
|
||||||
Helper class that will help a device component manage its devices.
|
|
||||||
"""
|
|
||||||
def __init__(self, logger, domain, hass,
|
|
||||||
scan_interval=DEFAULT_SCAN_INTERVAL,
|
|
||||||
discovery_platforms=None, group_name=None):
|
|
||||||
self.logger = logger
|
|
||||||
self.hass = hass
|
|
||||||
|
|
||||||
self.domain = domain
|
|
||||||
self.entity_id_format = domain + '.{}'
|
|
||||||
self.scan_interval = scan_interval
|
|
||||||
self.discovery_platforms = discovery_platforms
|
|
||||||
self.group_name = group_name
|
|
||||||
|
|
||||||
self.devices = {}
|
|
||||||
self.group = None
|
|
||||||
self.is_polling = False
|
|
||||||
|
|
||||||
def setup(self, config):
|
|
||||||
"""
|
|
||||||
Sets up a full device component:
|
|
||||||
- Loads the platforms from the config
|
|
||||||
- Will listen for supported discovered platforms
|
|
||||||
"""
|
|
||||||
# Look in config for Domain, Domain 2, Domain 3 etc and load them
|
|
||||||
for p_type, p_config in \
|
|
||||||
config_per_platform(config, self.domain, self.logger):
|
|
||||||
|
|
||||||
self._setup_platform(p_type, p_config)
|
|
||||||
|
|
||||||
if self.discovery_platforms:
|
|
||||||
discovery.listen(self.hass, self.discovery_platforms.keys(),
|
|
||||||
self._device_discovered)
|
|
||||||
|
|
||||||
def add_devices(self, new_devices):
|
|
||||||
"""
|
|
||||||
Takes in a list of new devices. For each device will see if it already
|
|
||||||
exists. If not, will add it, set it up and push the first state.
|
|
||||||
"""
|
|
||||||
for device in new_devices:
|
|
||||||
if device is not None and device not in self.devices.values():
|
|
||||||
device.hass = self.hass
|
|
||||||
|
|
||||||
device.entity_id = generate_entity_id(
|
|
||||||
self.entity_id_format, device.name, self.devices.keys())
|
|
||||||
|
|
||||||
self.devices[device.entity_id] = device
|
|
||||||
|
|
||||||
device.update_ha_state()
|
|
||||||
|
|
||||||
if self.group is None and self.group_name is not None:
|
|
||||||
self.group = group.Group(self.hass, self.group_name,
|
|
||||||
user_defined=False)
|
|
||||||
|
|
||||||
if self.group is not None:
|
|
||||||
self.group.update_tracked_entity_ids(self.devices.keys())
|
|
||||||
|
|
||||||
self._start_polling()
|
|
||||||
|
|
||||||
def extract_from_service(self, service):
|
|
||||||
"""
|
|
||||||
Takes a service and extracts all known devices.
|
|
||||||
Will return all if no entity IDs given in service.
|
|
||||||
"""
|
|
||||||
if ATTR_ENTITY_ID not in service.data:
|
|
||||||
return self.devices.values()
|
|
||||||
else:
|
|
||||||
return [self.devices[entity_id] for entity_id
|
|
||||||
in extract_entity_ids(self.hass, service)
|
|
||||||
if entity_id in self.devices]
|
|
||||||
|
|
||||||
def _update_device_states(self, now):
|
|
||||||
""" Update the states of all the lights. """
|
|
||||||
self.logger.info("Updating %s states", self.domain)
|
|
||||||
|
|
||||||
for device in self.devices.values():
|
|
||||||
if device.should_poll:
|
|
||||||
device.update_ha_state(True)
|
|
||||||
|
|
||||||
def _device_discovered(self, service, info):
|
|
||||||
""" Called when a device is discovered. """
|
|
||||||
if service not in self.discovery_platforms:
|
|
||||||
return
|
|
||||||
|
|
||||||
self._setup_platform(self.discovery_platforms[service], {}, info)
|
|
||||||
|
|
||||||
def _start_polling(self):
|
|
||||||
""" Start polling device states if necessary. """
|
|
||||||
if self.is_polling or \
|
|
||||||
not any(device.should_poll for device in self.devices.values()):
|
|
||||||
return
|
|
||||||
|
|
||||||
self.is_polling = True
|
|
||||||
|
|
||||||
self.hass.track_time_change(
|
|
||||||
self._update_device_states,
|
|
||||||
second=range(0, 60, self.scan_interval))
|
|
||||||
|
|
||||||
def _setup_platform(self, platform_type, config, discovery_info=None):
|
|
||||||
""" Tries to setup a platform for this component. """
|
|
||||||
platform_name = '{}.{}'.format(self.domain, platform_type)
|
|
||||||
platform = get_component(platform_name)
|
|
||||||
|
|
||||||
if platform is None:
|
|
||||||
self.logger.error('Unable to find platform %s', platform_type)
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
platform.setup_platform(
|
|
||||||
self.hass, config, self.add_devices, discovery_info)
|
|
||||||
except AttributeError:
|
|
||||||
# Support old deprecated method for now - 3/1/2015
|
|
||||||
if hasattr(platform, 'get_devices'):
|
|
||||||
self.logger.warning(
|
|
||||||
"Please upgrade %s to return new devices using "
|
|
||||||
"setup_platform. See %s/demo.py for an example.",
|
|
||||||
platform_name, self.domain)
|
|
||||||
self.add_devices(platform.get_devices(self.hass, config))
|
|
||||||
|
|
||||||
else:
|
|
||||||
# AttributeError if setup_platform does not exist
|
|
||||||
self.logger.exception(
|
|
||||||
"Error setting up %s", platform_type)
|
|
||||||
|
|
139
homeassistant/helpers/entity.py
Normal file
139
homeassistant/helpers/entity.py
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
"""
|
||||||
|
homeassistant.helpers.entity
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Provides ABC for entities in HA.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from homeassistant import NoEntitySpecifiedError
|
||||||
|
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT, STATE_ON, STATE_OFF,
|
||||||
|
DEVICE_DEFAULT_NAME, TEMP_CELCIUS, TEMP_FAHRENHEIT)
|
||||||
|
|
||||||
|
|
||||||
|
class Entity(object):
|
||||||
|
""" ABC for Home Assistant entities. """
|
||||||
|
# pylint: disable=no-self-use
|
||||||
|
|
||||||
|
hass = None
|
||||||
|
entity_id = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def should_poll(self):
|
||||||
|
"""
|
||||||
|
Return True if entity has to be polled for state.
|
||||||
|
False if entity pushes its state to HA.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unique_id(self):
|
||||||
|
""" Returns a unique id. """
|
||||||
|
return "{}.{}".format(self.__class__, id(self))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
""" Returns the name of the entity. """
|
||||||
|
return self.get_name()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self):
|
||||||
|
""" Returns the state of the entity. """
|
||||||
|
return self.get_state()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state_attributes(self):
|
||||||
|
""" Returns the state attributes. """
|
||||||
|
return {}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unit_of_measurement(self):
|
||||||
|
""" Unit of measurement of this entity, if any. """
|
||||||
|
return None
|
||||||
|
|
||||||
|
# DEPRECATION NOTICE:
|
||||||
|
# Device is moving from getters to properties.
|
||||||
|
# For now the new properties will call the old functions
|
||||||
|
# This will be removed in the future.
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
""" Returns the name of the entity if any. """
|
||||||
|
return DEVICE_DEFAULT_NAME
|
||||||
|
|
||||||
|
def get_state(self):
|
||||||
|
""" Returns state of the entity. """
|
||||||
|
return "Unknown"
|
||||||
|
|
||||||
|
def get_state_attributes(self):
|
||||||
|
""" Returns optional state attributes. """
|
||||||
|
return None
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
""" Retrieve latest state. """
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update_ha_state(self, force_refresh=False):
|
||||||
|
"""
|
||||||
|
Updates Home Assistant with current state of entity.
|
||||||
|
If force_refresh == True will update entity before setting state.
|
||||||
|
"""
|
||||||
|
if self.hass is None:
|
||||||
|
raise RuntimeError("Attribute hass is None for {}".format(self))
|
||||||
|
|
||||||
|
if self.entity_id is None:
|
||||||
|
raise NoEntitySpecifiedError(
|
||||||
|
"No entity id specified for entity {}".format(self.name))
|
||||||
|
|
||||||
|
if force_refresh:
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
state = str(self.state)
|
||||||
|
attr = self.state_attributes or {}
|
||||||
|
|
||||||
|
if ATTR_FRIENDLY_NAME not in attr and self.name:
|
||||||
|
attr[ATTR_FRIENDLY_NAME] = self.name
|
||||||
|
|
||||||
|
if ATTR_UNIT_OF_MEASUREMENT not in attr and self.unit_of_measurement:
|
||||||
|
attr[ATTR_UNIT_OF_MEASUREMENT] = self.unit_of_measurement
|
||||||
|
|
||||||
|
# Convert temperature if we detect one
|
||||||
|
if attr.get(ATTR_UNIT_OF_MEASUREMENT) in (TEMP_CELCIUS,
|
||||||
|
TEMP_FAHRENHEIT):
|
||||||
|
|
||||||
|
state, attr[ATTR_UNIT_OF_MEASUREMENT] = \
|
||||||
|
self.hass.config.temperature(
|
||||||
|
state, attr[ATTR_UNIT_OF_MEASUREMENT])
|
||||||
|
state = str(state)
|
||||||
|
|
||||||
|
return self.hass.states.set(self.entity_id, state, attr)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return (isinstance(other, Entity) and
|
||||||
|
other.unique_id == self.unique_id)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<Entity {}: {}>".format(self.name, self.state)
|
||||||
|
|
||||||
|
|
||||||
|
class ToggleEntity(Entity):
|
||||||
|
""" ABC for entities that can be turned on and off. """
|
||||||
|
# pylint: disable=no-self-use
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self):
|
||||||
|
""" Returns the state. """
|
||||||
|
return STATE_ON if self.is_on else STATE_OFF
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self):
|
||||||
|
""" True if entity is on. """
|
||||||
|
return False
|
||||||
|
|
||||||
|
def turn_on(self, **kwargs):
|
||||||
|
""" Turn the entity on. """
|
||||||
|
pass
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs):
|
||||||
|
""" Turn the entity off. """
|
||||||
|
pass
|
142
homeassistant/helpers/entity_component.py
Normal file
142
homeassistant/helpers/entity_component.py
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
"""
|
||||||
|
homeassistant.helpers.entity_component
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Provides helpers for components that manage entities.
|
||||||
|
"""
|
||||||
|
from homeassistant.loader import get_component
|
||||||
|
from homeassistant.helpers import (
|
||||||
|
generate_entity_id, config_per_platform, extract_entity_ids)
|
||||||
|
from homeassistant.components import group, discovery
|
||||||
|
from homeassistant.const import ATTR_ENTITY_ID
|
||||||
|
|
||||||
|
DEFAULT_SCAN_INTERVAL = 15
|
||||||
|
|
||||||
|
|
||||||
|
class EntityComponent(object):
|
||||||
|
# pylint: disable=too-many-instance-attributes
|
||||||
|
# pylint: disable=too-many-arguments
|
||||||
|
"""
|
||||||
|
Helper class that will help a component manage its entities.
|
||||||
|
"""
|
||||||
|
def __init__(self, logger, domain, hass,
|
||||||
|
scan_interval=DEFAULT_SCAN_INTERVAL,
|
||||||
|
discovery_platforms=None, group_name=None):
|
||||||
|
self.logger = logger
|
||||||
|
self.hass = hass
|
||||||
|
|
||||||
|
self.domain = domain
|
||||||
|
self.entity_id_format = domain + '.{}'
|
||||||
|
self.scan_interval = scan_interval
|
||||||
|
self.discovery_platforms = discovery_platforms
|
||||||
|
self.group_name = group_name
|
||||||
|
|
||||||
|
self.entities = {}
|
||||||
|
self.group = None
|
||||||
|
self.is_polling = False
|
||||||
|
|
||||||
|
def setup(self, config):
|
||||||
|
"""
|
||||||
|
Sets up a full entity component:
|
||||||
|
- Loads the platforms from the config
|
||||||
|
- Will listen for supported discovered platforms
|
||||||
|
"""
|
||||||
|
# Look in config for Domain, Domain 2, Domain 3 etc and load them
|
||||||
|
for p_type, p_config in \
|
||||||
|
config_per_platform(config, self.domain, self.logger):
|
||||||
|
|
||||||
|
self._setup_platform(p_type, p_config)
|
||||||
|
|
||||||
|
if self.discovery_platforms:
|
||||||
|
discovery.listen(self.hass, self.discovery_platforms.keys(),
|
||||||
|
self._entity_discovered)
|
||||||
|
|
||||||
|
def add_entities(self, new_entities):
|
||||||
|
"""
|
||||||
|
Takes in a list of new entities. For each entity will see if it already
|
||||||
|
exists. If not, will add it, set it up and push the first state.
|
||||||
|
"""
|
||||||
|
for entity in new_entities:
|
||||||
|
if entity is not None and entity not in self.entities.values():
|
||||||
|
entity.hass = self.hass
|
||||||
|
|
||||||
|
entity.entity_id = generate_entity_id(
|
||||||
|
self.entity_id_format, entity.name, self.entities.keys())
|
||||||
|
|
||||||
|
self.entities[entity.entity_id] = entity
|
||||||
|
|
||||||
|
entity.update_ha_state()
|
||||||
|
|
||||||
|
if self.group is None and self.group_name is not None:
|
||||||
|
self.group = group.Group(self.hass, self.group_name,
|
||||||
|
user_defined=False)
|
||||||
|
|
||||||
|
if self.group is not None:
|
||||||
|
self.group.update_tracked_entity_ids(self.entities.keys())
|
||||||
|
|
||||||
|
self._start_polling()
|
||||||
|
|
||||||
|
def extract_from_service(self, service):
|
||||||
|
"""
|
||||||
|
Takes a service and extracts all known entities.
|
||||||
|
Will return all if no entity IDs given in service.
|
||||||
|
"""
|
||||||
|
if ATTR_ENTITY_ID not in service.data:
|
||||||
|
return self.entities.values()
|
||||||
|
else:
|
||||||
|
return [self.entities[entity_id] for entity_id
|
||||||
|
in extract_entity_ids(self.hass, service)
|
||||||
|
if entity_id in self.entities]
|
||||||
|
|
||||||
|
def _update_entity_states(self, now):
|
||||||
|
""" Update the states of all the entities. """
|
||||||
|
self.logger.info("Updating %s entities", self.domain)
|
||||||
|
|
||||||
|
for entity in self.entities.values():
|
||||||
|
if entity.should_poll:
|
||||||
|
entity.update_ha_state(True)
|
||||||
|
|
||||||
|
def _entity_discovered(self, service, info):
|
||||||
|
""" Called when a entity is discovered. """
|
||||||
|
if service not in self.discovery_platforms:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._setup_platform(self.discovery_platforms[service], {}, info)
|
||||||
|
|
||||||
|
def _start_polling(self):
|
||||||
|
""" Start polling entities if necessary. """
|
||||||
|
if self.is_polling or \
|
||||||
|
not any(entity.should_poll for entity in self.entities.values()):
|
||||||
|
return
|
||||||
|
|
||||||
|
self.is_polling = True
|
||||||
|
|
||||||
|
self.hass.track_time_change(
|
||||||
|
self._update_entity_states,
|
||||||
|
second=range(0, 60, self.scan_interval))
|
||||||
|
|
||||||
|
def _setup_platform(self, platform_type, config, discovery_info=None):
|
||||||
|
""" Tries to setup a platform for this component. """
|
||||||
|
platform_name = '{}.{}'.format(self.domain, platform_type)
|
||||||
|
platform = get_component(platform_name)
|
||||||
|
|
||||||
|
if platform is None:
|
||||||
|
self.logger.error('Unable to find platform %s', platform_type)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
platform.setup_platform(
|
||||||
|
self.hass, config, self.add_entities, discovery_info)
|
||||||
|
except AttributeError:
|
||||||
|
# Support old deprecated method for now - 3/1/2015
|
||||||
|
if hasattr(platform, 'get_entities'):
|
||||||
|
self.logger.warning(
|
||||||
|
"Please upgrade %s to return new entities using "
|
||||||
|
"setup_platform. See %s/demo.py for an example.",
|
||||||
|
platform_name, self.domain)
|
||||||
|
self.add_devices(platform.get_entities(self.hass, config))
|
||||||
|
|
||||||
|
else:
|
||||||
|
# AttributeError if setup_platform does not exist
|
||||||
|
self.logger.exception(
|
||||||
|
"Error setting up %s", platform_type)
|
Loading…
Add table
Reference in a new issue