Add service descriptions

This commit is contained in:
Paulus Schoutsen 2015-09-26 23:17:04 -07:00
parent 9a6b2c1831
commit 4e3bd5f2a9
20 changed files with 180 additions and 49 deletions

View file

@ -4,12 +4,15 @@ homeassistant.components.alarm_control_panel
Component to interface with a alarm control panel.
"""
import logging
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent
import os
from homeassistant.components import verisure
from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_ALARM_DISARM, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY)
from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent
DOMAIN = 'alarm_control_panel'
DEPENDENCIES = []
@ -59,8 +62,12 @@ def setup(hass, config):
for alarm in target_alarms:
getattr(alarm, method)(code)
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
for service in SERVICE_TO_METHOD:
hass.services.register(DOMAIN, service, alarm_service_handler)
hass.services.register(DOMAIN, service, alarm_service_handler,
descriptions.get(service))
return True

View file

@ -60,7 +60,7 @@ def setup(hass, config):
{'camera': {
'platform': 'generic',
'name': 'IP Camera',
'still_image_url': 'http://194.218.96.92/jpg/image.jpg',
'still_image_url': 'http://home-assistant.io/demo/webcam.jpg',
}})
# Setup scripts

View file

@ -175,7 +175,10 @@ def setup(hass, config):
ATTR_GPS, ATTR_GPS_ACCURACY, ATTR_BATTERY)}
tracker.see(**args)
hass.services.register(DOMAIN, SERVICE_SEE, see_service)
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
hass.services.register(DOMAIN, SERVICE_SEE, see_service,
descriptions.get(SERVICE_SEE))
return True

View file

@ -1,2 +1,2 @@
""" DO NOT MODIFY. Auto-generated by build_frontend script """
VERSION = "5ba745608f6271b781fc41c1e8f8deb0"
VERSION = "1dae3a2fb4ea4ff853d0d0c647f0ac51"

File diff suppressed because one or more lines are too long

@ -1 +1 @@
Subproject commit 78cf25f605724ae84d8e23d0e7ab97845f53725a
Subproject commit 72bceff0fcfe7ba440cc1676ec0fe77ac0f6e200

View file

@ -52,14 +52,14 @@ import logging
import os
import csv
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.entity import ToggleEntity
import homeassistant.util as util
import homeassistant.util.color as color_util
from homeassistant.components import group, discovery, wink, isy994
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, ATTR_ENTITY_ID)
from homeassistant.components import group, discovery, wink, isy994
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.helpers.entity_component import EntityComponent
import homeassistant.util as util
import homeassistant.util.color as color_util
DOMAIN = "light"
@ -275,11 +275,13 @@ def setup(hass, config):
light.update_ha_state(True)
# Listen for light on and light off service calls
hass.services.register(DOMAIN, SERVICE_TURN_ON,
handle_light_service)
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_light_service,
descriptions.get(SERVICE_TURN_ON))
hass.services.register(DOMAIN, SERVICE_TURN_OFF,
handle_light_service)
hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_light_service,
descriptions.get(SERVICE_TURN_OFF))
return True

View file

@ -0,0 +1,52 @@
# Describes the format for available light services
turn_on:
description: Turn a light on
fields:
entity_id:
description: Name(s) of entities to turn on
example: 'light.kitchen'
transition:
description: Duration in seconds it takes to get to next state
example: 60
rgb_color:
description: Color for the light in RGB-format
example: '[255, 100, 100]'
xy_color:
description: Color for the light in XY-format
example: '[0.52, 0.43]'
brightness:
description: Number between 0..255 indicating brightness
example: 120
profile:
description: Name of a light profile to use
example: relax
flash:
description: If the light should flash
values:
- short
- long
effect:
description: Light effect
values:
- colorloop
turn_off:
description: Turn a light off
fields:
entity_id:
description: Name(s) of entities to turn off
example: 'light.kitchen'
transition:
description: Duration in seconds it takes to get to next state
example: 60

View file

@ -5,8 +5,10 @@ homeassistant.components.media_player
Component to interface with various media players.
"""
import logging
import os
from homeassistant.components import discovery
from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.const import (
@ -186,6 +188,9 @@ def setup(hass, config):
component.setup(config)
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
def media_player_service_handler(service):
""" Maps services to methods on MediaPlayerDevice. """
target_players = component.extract_from_service(service)
@ -199,7 +204,8 @@ def setup(hass, config):
player.update_ha_state(True)
for service in SERVICE_TO_METHOD:
hass.services.register(DOMAIN, service, media_player_service_handler)
hass.services.register(DOMAIN, service, media_player_service_handler,
descriptions.get(service))
def volume_set_service(service):
""" Set specified volume on the media player. """
@ -216,7 +222,8 @@ def setup(hass, config):
if player.should_poll:
player.update_ha_state(True)
hass.services.register(DOMAIN, SERVICE_VOLUME_SET, volume_set_service)
hass.services.register(DOMAIN, SERVICE_VOLUME_SET, volume_set_service,
descriptions.get(SERVICE_VOLUME_SET))
def volume_mute_service(service):
""" Mute (true) or unmute (false) the media player. """
@ -233,7 +240,8 @@ def setup(hass, config):
if player.should_poll:
player.update_ha_state(True)
hass.services.register(DOMAIN, SERVICE_VOLUME_MUTE, volume_mute_service)
hass.services.register(DOMAIN, SERVICE_VOLUME_MUTE, volume_mute_service,
descriptions.get(SERVICE_VOLUME_MUTE))
def media_seek_service(service):
""" Seek to a position. """
@ -250,7 +258,8 @@ def setup(hass, config):
if player.should_poll:
player.update_ha_state(True)
hass.services.register(DOMAIN, SERVICE_MEDIA_SEEK, media_seek_service)
hass.services.register(DOMAIN, SERVICE_MEDIA_SEEK, media_seek_service,
descriptions.get(SERVICE_MEDIA_SEEK))
def play_youtube_video_service(service, media_id=None):
""" Plays specified media_id on the media player. """
@ -268,14 +277,17 @@ def setup(hass, config):
hass.services.register(
DOMAIN, "start_fireplace",
lambda service: play_youtube_video_service(service, "eyU3bRy2x44"))
lambda service: play_youtube_video_service(service, "eyU3bRy2x44"),
descriptions.get('start_fireplace'))
hass.services.register(
DOMAIN, "start_epic_sax",
lambda service: play_youtube_video_service(service, "kxopViU98Xo"))
lambda service: play_youtube_video_service(service, "kxopViU98Xo"),
descriptions.get('start_epic_sax'))
hass.services.register(
DOMAIN, SERVICE_YOUTUBE_VIDEO, play_youtube_video_service)
DOMAIN, SERVICE_YOUTUBE_VIDEO, play_youtube_video_service,
descriptions.get(SERVICE_YOUTUBE_VIDEO))
return True

View file

@ -6,7 +6,9 @@ Provides functionality to notify people.
"""
from functools import partial
import logging
import os
from homeassistant.config import load_yaml_config_file
from homeassistant.loader import get_component
from homeassistant.helpers import config_per_platform
@ -36,6 +38,9 @@ def setup(hass, config):
""" Sets up notify services. """
success = False
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
for platform, p_config in config_per_platform(config, DOMAIN, _LOGGER):
# get platform
notify_implementation = get_component(
@ -69,7 +74,8 @@ def setup(hass, config):
# register service
service_call_handler = partial(notify_message, notify_service)
service_notify = p_config.get(CONF_NAME, SERVICE_NOTIFY)
hass.services.register(DOMAIN, service_notify, service_call_handler)
hass.services.register(DOMAIN, service_notify, service_call_handler,
descriptions.get(service_notify))
success = True
return success

View file

@ -3,9 +3,11 @@ homeassistant.components.switch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Component to interface with various switches that can be controlled remotely.
"""
import logging
from datetime import timedelta
import logging
import os
from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.entity import ToggleEntity
@ -83,8 +85,12 @@ def setup(hass, config):
if switch.should_poll:
switch.update_ha_state(True)
hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_switch_service)
hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_switch_service)
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_switch_service,
descriptions.get(SERVICE_TURN_OFF))
hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_switch_service,
descriptions.get(SERVICE_TURN_ON))
return True

View file

@ -5,9 +5,11 @@ homeassistant.components.thermostat
Provides functionality to interact with thermostats.
"""
import logging
import os
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.config import load_yaml_config_file
import homeassistant.util as util
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.temperature import convert
@ -101,11 +103,16 @@ def setup(hass, config):
for thermostat in target_thermostats:
thermostat.update_ha_state(True)
hass.services.register(
DOMAIN, SERVICE_SET_AWAY_MODE, thermostat_service)
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
hass.services.register(
DOMAIN, SERVICE_SET_TEMPERATURE, thermostat_service)
DOMAIN, SERVICE_SET_AWAY_MODE, thermostat_service,
descriptions.get(SERVICE_SET_AWAY_MODE))
hass.services.register(
DOMAIN, SERVICE_SET_TEMPERATURE, thermostat_service,
descriptions.get(SERVICE_SET_TEMPERATURE))
return True

View file

@ -525,6 +525,28 @@ class StateMachine(object):
from_state, to_state)
# pylint: disable=too-few-public-methods
class Service(object):
""" Represents a service. """
__slots__ = ['func', 'description', 'fields']
def __init__(self, func, description, fields):
self.func = func
self.description = description or ''
self.fields = fields or {}
def as_dict(self):
""" Return dictionary representation of this service. """
return {
'description': self.description,
'fields': self.fields,
}
def __call__(self, call):
self.func(call)
# pylint: disable=too-few-public-methods
class ServiceCall(object):
""" Represents a call to a service. """
@ -559,20 +581,29 @@ class ServiceRegistry(object):
def services(self):
""" Dict with per domain a list of available services. """
with self._lock:
return {domain: list(self._services[domain].keys())
return {domain: {key: value.as_dict() for key, value
in self._services[domain].items()}
for domain in self._services}
def has_service(self, domain, service):
""" Returns True if specified service exists. """
return service in self._services.get(domain, [])
def register(self, domain, service, service_func):
""" Register a service. """
def register(self, domain, service, service_func, description=None):
"""
Register a service.
Description is a dict containing key 'description' to describe
the service and a key 'fields' to describe the fields.
"""
description = description or {}
service_obj = Service(service_func, description.get('description'),
description.get('fields', {}))
with self._lock:
if domain in self._services:
self._services[domain][service] = service_func
self._services[domain][service] = service_obj
else:
self._services[domain] = {service: service_func}
self._services[domain] = {service: service_obj}
self._bus.fire(
EVENT_SERVICE_REGISTERED,

View file

@ -441,7 +441,7 @@ class TestServiceRegistry(unittest.TestCase):
def test_services(self):
expected = {
'test_domain': ['test_service']
'test_domain': {'test_service': {'description': '', 'fields': {}}}
}
self.assertEqual(expected, self.services.services)