Cleanup of core services

This commit is contained in:
Paulus Schoutsen 2014-04-13 12:59:45 -07:00
parent 90769fc0eb
commit 8fdf2d608a
5 changed files with 82 additions and 88 deletions

View File

@ -152,7 +152,7 @@ def from_config_file(config_path):
add_status("Downloader", downloader.setup( add_status("Downloader", downloader.setup(
bus, get_opt("downloader", "download_dir"))) bus, get_opt("downloader", "download_dir")))
add_status("Core components", components.setup(bus)) add_status("Core components", components.setup(bus, statemachine))
if has_section('browser'): if has_section('browser'):
add_status("Browser", load_module('browser').setup(bus)) add_status("Browser", load_module('browser').setup(bus))

View File

@ -14,13 +14,13 @@ format "<DOMAIN>.<OBJECT_ID>".
Each component should publish services only under its own domain. Each component should publish services only under its own domain.
""" """
import itertools as it
import importlib import importlib
import homeassistant as ha import homeassistant as ha
import homeassistant.util as util import homeassistant.util as util
# String that contains an entity id or a comma seperated list of entity ids # Contains one string or a list of strings, each being an entity id
ATTR_ENTITY_ID = 'entity_id' ATTR_ENTITY_ID = 'entity_id'
# String with a friendly name for the entity # String with a friendly name for the entity
@ -69,7 +69,12 @@ def _get_component(component):
def is_on(statemachine, entity_id=None): def is_on(statemachine, entity_id=None):
""" Loads up the module to call the is_on method. """ Loads up the module to call the is_on method.
If there is no entity id given we will check all. """ If there is no entity id given we will check all. """
entity_ids = [entity_id] if entity_id else statemachine.entity_ids if entity_id:
group = _get_component('group')
entity_ids = group.expand_entity_ids([entity_id])
else:
entity_ids = statemachine.entity_ids
for entity_id in entity_ids: for entity_id in entity_ids:
domain = util.split_entity_id(entity_id)[0] domain = util.split_entity_id(entity_id)[0]
@ -87,34 +92,14 @@ def is_on(statemachine, entity_id=None):
return False return False
def turn_on(bus, entity_id=None): def turn_on(bus, **service_data):
""" Turns specified entity on if possible. """ """ Turns specified entity on if possible. """
# If there is no entity_id we do not know which domain to call. bus.call_service(ha.DOMAIN, SERVICE_TURN_ON, service_data)
if not entity_id:
return
domain = util.split_entity_id(entity_id)[0]
try:
bus.call_service(domain, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id})
except ha.ServiceDoesNotExistError:
# turn_on service does not exist
pass
def turn_off(bus, entity_id=None): def turn_off(bus, **service_data):
""" Turns specified entity off. """ """ Turns specified entity off. """
# If there is no entity_id we do not know which domain to call. bus.call_service(ha.DOMAIN, SERVICE_TURN_OFF, service_data)
if not entity_id:
return
domain = util.split_entity_id(entity_id)[0]
try:
bus.call_service(domain, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id})
except ha.ServiceDoesNotExistError:
# turn_off service does not exist
pass
def extract_entity_ids(statemachine, service): def extract_entity_ids(statemachine, service):
@ -134,37 +119,44 @@ def extract_entity_ids(statemachine, service):
else: else:
ent_ids = [service_ent_id] ent_ids = [service_ent_id]
for entity_id in ent_ids: entity_ids.extend(
try: ent_id for ent_id
# If entity_id points at a group, expand it in group.expand_entity_ids(statemachine, ent_ids)
domain, _ = util.split_entity_id(entity_id) if ent_id not in entity_ids)
if domain == group.DOMAIN:
entity_ids.extend(
ent_id for ent_id
in group.get_entity_ids(statemachine, entity_id)
if ent_id not in entity_ids)
else:
if entity_id not in entity_ids:
entity_ids.append(entity_id)
except AttributeError:
# Raised by util.split_entity_id if entity_id is not a string
pass
return entity_ids return entity_ids
def setup(bus): def setup(bus, statemachine):
""" Setup general services related to homeassistant. """ """ Setup general services related to homeassistant. """
bus.register_service(ha.DOMAIN, SERVICE_TURN_OFF, def handle_turn_service(service):
lambda service: """ Method to handle calls to homeassistant.turn_on/off. """
turn_off(bus, service.data.get(ATTR_ENTITY_ID)))
bus.register_service(ha.DOMAIN, SERVICE_TURN_ON, entity_ids = extract_entity_ids(statemachine, service)
lambda service:
turn_on(bus, service.data.get(ATTR_ENTITY_ID))) # Generic turn on/off method requires entity id
if not entity_ids:
return
# Group entity_ids by domain. groupby requires sorted data.
by_domain = it.groupby(sorted(entity_ids),
lambda item: util.split_entity_id(item)[0])
for domain, ent_ids in by_domain:
# Create a new dict for this call
data = dict(service.data)
# ent_ids is a generator, convert it to a list.
data[ATTR_ENTITY_ID] = list(ent_ids)
try:
bus.call_service(domain, service.service, data)
except ha.ServiceDoesNotExistError:
# turn_on service does not exist
pass
bus.register_service(ha.DOMAIN, SERVICE_TURN_OFF, handle_turn_service)
bus.register_service(ha.DOMAIN, SERVICE_TURN_ON, handle_turn_service)
return True return True

View File

@ -45,6 +45,13 @@ def is_on(statemachine, entity_id=None):
for entity_id in entity_ids) for entity_id in entity_ids)
def turn_off(bus, entity_id=None):
""" Will turn off specified Chromecast or all. """
data = {components.ATTR_ENTITY_ID: entity_id} if entity_id else {}
bus.call_service(DOMAIN, components.SERVICE_TURN_OFF, data)
def volume_up(bus, entity_id=None): def volume_up(bus, entity_id=None):
""" Send the chromecast the command for volume up. """ """ Send the chromecast the command for volume up. """
data = {components.ATTR_ENTITY_ID: entity_id} if entity_id else {} data = {components.ATTR_ENTITY_ID: entity_id} if entity_id else {}

View File

@ -117,11 +117,8 @@ def setup(bus, statemachine,
"Home coming event for {}. Turning lights on". "Home coming event for {}. Turning lights on".
format(entity)) format(entity))
# Turn on lights directly instead of calling group.turn_on light.turn_on(bus, light_ids,
# So we skip fetching the entity ids again. profile=light_profile)
for light_id in light_ids:
light.turn_on(bus, light_id,
profile=light_profile)
# Are we in the time span were we would turn on the lights # Are we in the time span were we would turn on the lights
# if someone would be home? # if someone would be home?

View File

@ -8,11 +8,9 @@ Provides functionality to group devices that can be turned on or off.
import logging import logging
import homeassistant as ha import homeassistant as ha
import homeassistant.util as util
from homeassistant.components import (STATE_ON, STATE_OFF, from homeassistant.components import (STATE_ON, STATE_OFF,
STATE_HOME, STATE_NOT_HOME, STATE_HOME, STATE_NOT_HOME,
SERVICE_TURN_ON, SERVICE_TURN_OFF,
turn_on as comp_turn_on,
turn_off as comp_turn_off,
ATTR_ENTITY_ID) ATTR_ENTITY_ID)
DOMAIN = "group" DOMAIN = "group"
@ -50,6 +48,33 @@ def is_on(statemachine, entity_id):
return False return False
def expand_entity_ids(statemachine, entity_ids):
""" Returns the given list of entity ids and expands group ids into
the entity ids it represents if found. """
found_ids = []
for entity_id in entity_ids:
try:
# If entity_id points at a group, expand it
domain, _ = util.split_entity_id(entity_id)
if domain == DOMAIN:
found_ids.extend(
ent_id for ent_id
in get_entity_ids(statemachine, entity_id)
if ent_id not in found_ids)
else:
if entity_id not in found_ids:
found_ids.append(entity_id)
except AttributeError:
# Raised by util.split_entity_id if entity_id is not a string
pass
return found_ids
def get_entity_ids(statemachine, entity_id): def get_entity_ids(statemachine, entity_id):
""" Get the entity ids that make up this group. """ """ Get the entity ids that make up this group. """
try: try:
@ -141,33 +166,6 @@ def setup(bus, statemachine, name, entity_ids):
for entity_id in entity_ids: for entity_id in entity_ids:
ha.track_state_change(bus, entity_id, update_group_state) ha.track_state_change(bus, entity_id, update_group_state)
# group.setup is called to setup each group. Only the first time will we
# register a turn_on and turn_off method for groups.
if not bus.has_service(DOMAIN, SERVICE_TURN_ON):
def turn_group_on_service(service):
""" Call components.turn_on for each entity_id from this group. """
for entity_id in get_entity_ids(statemachine,
service.data.get(
ATTR_ENTITY_ID)):
comp_turn_on(bus, entity_id)
bus.register_service(DOMAIN, SERVICE_TURN_ON,
turn_group_on_service)
if not bus.has_service(DOMAIN, SERVICE_TURN_OFF):
def turn_group_off_service(service):
""" Call components.turn_off for each entity_id in this group. """
for entity_id in get_entity_ids(statemachine,
service.data.get(
ATTR_ENTITY_ID)):
comp_turn_off(bus, entity_id)
bus.register_service(DOMAIN, SERVICE_TURN_OFF,
turn_group_off_service)
statemachine.set_state(group_entity_id, group_state, state_attr) statemachine.set_state(group_entity_id, group_state, state_attr)
return True return True