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(
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'):
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.
"""
import itertools as it
import importlib
import homeassistant as ha
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'
# String with a friendly name for the entity
@ -69,7 +69,12 @@ def _get_component(component):
def is_on(statemachine, entity_id=None):
""" Loads up the module to call the is_on method.
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:
domain = util.split_entity_id(entity_id)[0]
@ -87,34 +92,14 @@ def is_on(statemachine, entity_id=None):
return False
def turn_on(bus, entity_id=None):
def turn_on(bus, **service_data):
""" Turns specified entity on if possible. """
# If there is no entity_id we do not know which domain to call.
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
bus.call_service(ha.DOMAIN, SERVICE_TURN_ON, service_data)
def turn_off(bus, entity_id=None):
def turn_off(bus, **service_data):
""" Turns specified entity off. """
# If there is no entity_id we do not know which domain to call.
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
bus.call_service(ha.DOMAIN, SERVICE_TURN_OFF, service_data)
def extract_entity_ids(statemachine, service):
@ -134,37 +119,44 @@ def extract_entity_ids(statemachine, service):
else:
ent_ids = [service_ent_id]
for entity_id in ent_ids:
try:
# If entity_id points at a group, expand it
domain, _ = util.split_entity_id(entity_id)
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
entity_ids.extend(
ent_id for ent_id
in group.expand_entity_ids(statemachine, ent_ids)
if ent_id not in entity_ids)
return entity_ids
def setup(bus):
def setup(bus, statemachine):
""" Setup general services related to homeassistant. """
bus.register_service(ha.DOMAIN, SERVICE_TURN_OFF,
lambda service:
turn_off(bus, service.data.get(ATTR_ENTITY_ID)))
def handle_turn_service(service):
""" Method to handle calls to homeassistant.turn_on/off. """
bus.register_service(ha.DOMAIN, SERVICE_TURN_ON,
lambda service:
turn_on(bus, service.data.get(ATTR_ENTITY_ID)))
entity_ids = extract_entity_ids(statemachine, service)
# 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

View File

@ -45,6 +45,13 @@ def is_on(statemachine, entity_id=None):
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):
""" Send the chromecast the command for volume up. """
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".
format(entity))
# Turn on lights directly instead of calling group.turn_on
# So we skip fetching the entity ids again.
for light_id in light_ids:
light.turn_on(bus, light_id,
profile=light_profile)
light.turn_on(bus, light_ids,
profile=light_profile)
# Are we in the time span were we would turn on the lights
# 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 homeassistant as ha
import homeassistant.util as util
from homeassistant.components import (STATE_ON, STATE_OFF,
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)
DOMAIN = "group"
@ -50,6 +48,33 @@ def is_on(statemachine, entity_id):
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):
""" Get the entity ids that make up this group. """
try:
@ -141,33 +166,6 @@ def setup(bus, statemachine, name, entity_ids):
for entity_id in entity_ids:
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)
return True