Skip to content

Commit

Permalink
Cleanup of core services
Browse files Browse the repository at this point in the history
  • Loading branch information
balloob committed Apr 13, 2014
1 parent 90769fc commit 8fdf2d6
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 87 deletions.
2 changes: 1 addition & 1 deletion homeassistant/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def get_opt_safe(section, option, default=None):
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))
Expand Down
94 changes: 43 additions & 51 deletions homeassistant/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
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
Expand Down Expand Up @@ -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]
Expand All @@ -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):
Expand All @@ -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)
entity_ids.extend(
ent_id for ent_id
in group.expand_entity_ids(statemachine, ent_ids)
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)
return 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
def setup(bus, statemachine):
""" Setup general services related to homeassistant. """

return entity_ids
def handle_turn_service(service):
""" Method to handle calls to homeassistant.turn_on/off. """

entity_ids = extract_entity_ids(statemachine, service)

def setup(bus):
""" Setup general services related to homeassistant. """
# Generic turn on/off method requires entity id
if not entity_ids:
return

bus.register_service(ha.DOMAIN, SERVICE_TURN_OFF,
lambda service:
turn_off(bus, service.data.get(ATTR_ENTITY_ID)))
# 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_ON,
lambda service:
turn_on(bus, service.data.get(ATTR_ENTITY_ID)))
bus.register_service(ha.DOMAIN, SERVICE_TURN_OFF, handle_turn_service)
bus.register_service(ha.DOMAIN, SERVICE_TURN_ON, handle_turn_service)

return True
7 changes: 7 additions & 0 deletions homeassistant/components/chromecast.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand Down
7 changes: 2 additions & 5 deletions homeassistant/components/device_sun_light_trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,8 @@ def check_light_on_dev_state_change(entity, old_state, new_state):
"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?
Expand Down
58 changes: 28 additions & 30 deletions homeassistant/components/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
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"
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -141,33 +166,6 @@ def update_group_state(entity_id, old_state, new_state):
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

0 comments on commit 8fdf2d6

Please sign in to comment.