Lazy loading of service descriptions (#11479)

* Lazy loading of service descriptions

* Fix tests

* Load YAML in executor

* Return a copy of available services to allow mutations

* Remove lint

* Add zha/services.yaml

* Only cache descriptions for known services

* Remove lint

* Remove description loading during service registration

* Remove description parameter from async_register

* Test async_get_all_descriptions

* Remove lint

* Fix typos from multi-edit

* Remove unused arguments

* Remove unused import os

* Remove unused import os, part 2

* Remove unneeded coroutine decorator

* Only use executor for loading files

* Cleanups suggested in review

* Increase test coverage

* Fix races in existing tests
This commit is contained in:
Anders Melchiorsen 2018-01-07 23:54:16 +01:00 committed by Paulus Schoutsen
parent 3cbd77f6ac
commit 8267a21bfe
85 changed files with 253 additions and 729 deletions

View File

@ -10,7 +10,6 @@ Component design guidelines:
import asyncio
import itertools as it
import logging
import os
import homeassistant.core as ha
import homeassistant.config as conf_util
@ -111,11 +110,6 @@ def async_reload_core_config(hass):
@asyncio.coroutine
def async_setup(hass, config):
"""Set up general services related to Home Assistant."""
descriptions = yield from hass.async_add_job(
conf_util.load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml')
)
@asyncio.coroutine
def async_handle_turn_service(service):
"""Handle calls to homeassistant.turn_on/off."""
@ -155,14 +149,11 @@ def async_setup(hass, config):
yield from asyncio.wait(tasks, loop=hass.loop)
hass.services.async_register(
ha.DOMAIN, SERVICE_TURN_OFF, async_handle_turn_service,
descriptions[ha.DOMAIN][SERVICE_TURN_OFF])
ha.DOMAIN, SERVICE_TURN_OFF, async_handle_turn_service)
hass.services.async_register(
ha.DOMAIN, SERVICE_TURN_ON, async_handle_turn_service,
descriptions[ha.DOMAIN][SERVICE_TURN_ON])
ha.DOMAIN, SERVICE_TURN_ON, async_handle_turn_service)
hass.services.async_register(
ha.DOMAIN, SERVICE_TOGGLE, async_handle_turn_service,
descriptions[ha.DOMAIN][SERVICE_TOGGLE])
ha.DOMAIN, SERVICE_TOGGLE, async_handle_turn_service)
@asyncio.coroutine
def async_handle_core_service(call):
@ -187,14 +178,11 @@ def async_setup(hass, config):
hass.async_add_job(hass.async_stop(RESTART_EXIT_CODE))
hass.services.async_register(
ha.DOMAIN, SERVICE_HOMEASSISTANT_STOP, async_handle_core_service,
descriptions[ha.DOMAIN][SERVICE_HOMEASSISTANT_STOP])
ha.DOMAIN, SERVICE_HOMEASSISTANT_STOP, async_handle_core_service)
hass.services.async_register(
ha.DOMAIN, SERVICE_HOMEASSISTANT_RESTART, async_handle_core_service,
descriptions[ha.DOMAIN][SERVICE_HOMEASSISTANT_RESTART])
ha.DOMAIN, SERVICE_HOMEASSISTANT_RESTART, async_handle_core_service)
hass.services.async_register(
ha.DOMAIN, SERVICE_CHECK_CONFIG, async_handle_core_service,
descriptions[ha.DOMAIN][SERVICE_CHECK_CONFIG])
ha.DOMAIN, SERVICE_CHECK_CONFIG, async_handle_core_service)
@asyncio.coroutine
def async_handle_reload_config(call):
@ -209,7 +197,6 @@ def async_setup(hass, config):
hass, conf.get(ha.DOMAIN) or {})
hass.services.async_register(
ha.DOMAIN, SERVICE_RELOAD_CORE_CONFIG, async_handle_reload_config,
descriptions[ha.DOMAIN][SERVICE_RELOAD_CORE_CONFIG])
ha.DOMAIN, SERVICE_RELOAD_CORE_CONFIG, async_handle_reload_config)
return True

View File

@ -7,11 +7,9 @@ https://home-assistant.io/components/abode/
import asyncio
import logging
from functools import partial
from os import path
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
ATTR_ATTRIBUTION, ATTR_DATE, ATTR_TIME, ATTR_ENTITY_ID, CONF_USERNAME,
CONF_PASSWORD, CONF_EXCLUDE, CONF_NAME, CONF_LIGHTS,
@ -188,22 +186,16 @@ def setup_hass_services(hass):
for device in target_devices:
device.trigger()
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))[DOMAIN]
hass.services.register(
DOMAIN, SERVICE_SETTINGS, change_setting,
descriptions.get(SERVICE_SETTINGS),
schema=CHANGE_SETTING_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_CAPTURE_IMAGE, capture_image,
descriptions.get(SERVICE_CAPTURE_IMAGE),
schema=CAPTURE_IMAGE_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_TRIGGER, trigger_quick_action,
descriptions.get(SERVICE_TRIGGER),
schema=TRIGGER_SCHEMA)

View File

@ -5,7 +5,6 @@ For more details about this component, please refer to the documentation.
https://home-assistant.io/components/ads/
"""
import os
import threading
import struct
import logging
@ -14,7 +13,6 @@ from collections import namedtuple
import voluptuous as vol
from homeassistant.const import CONF_DEVICE, CONF_PORT, CONF_IP_ADDRESS, \
EVENT_HOMEASSISTANT_STOP
from homeassistant.config import load_yaml_config_file
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['pyads==2.2.6']
@ -107,13 +105,8 @@ def setup(hass, config):
except pyads.ADSError as err:
_LOGGER.error(err)
# load descriptions from services.yaml
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
hass.services.register(
DOMAIN, SERVICE_WRITE_DATA_BY_NAME, handle_write_data_by_name,
descriptions[SERVICE_WRITE_DATA_BY_NAME],
schema=SCHEMA_SERVICE_WRITE_DATA_BY_NAME
)

View File

@ -7,7 +7,6 @@ https://home-assistant.io/components/alarm_control_panel/
import asyncio
from datetime import timedelta
import logging
import os
import voluptuous as vol
@ -15,7 +14,6 @@ from homeassistant.const import (
ATTR_CODE, ATTR_CODE_FORMAT, ATTR_ENTITY_ID, SERVICE_ALARM_TRIGGER,
SERVICE_ALARM_DISARM, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY,
SERVICE_ALARM_ARM_NIGHT, SERVICE_ALARM_ARM_CUSTOM_BYPASS)
from homeassistant.config import load_yaml_config_file
from homeassistant.loader import bind_hass
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
import homeassistant.helpers.config_validation as cv
@ -148,14 +146,10 @@ def async_setup(hass, config):
if update_tasks:
yield from asyncio.wait(update_tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
for service in SERVICE_TO_METHOD:
hass.services.async_register(
DOMAIN, service, async_alarm_service_handler,
descriptions.get(service), schema=ALARM_SERVICE_SCHEMA)
schema=ALARM_SERVICE_SCHEMA)
return True

View File

@ -6,13 +6,11 @@ https://home-assistant.io/components/alarm_control_panel.alarmdecoder/
"""
import asyncio
import logging
from os import path
import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.components.alarmdecoder import (
DATA_AD, SIGNAL_PANEL_MESSAGE)
from homeassistant.const import (
@ -39,12 +37,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
code = service.data.get(ATTR_CODE)
device.alarm_toggle_chime(code)
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
hass.services.register(
alarm.DOMAIN, SERVICE_ALARM_TOGGLE_CHIME, alarm_toggle_chime_handler,
descriptions.get(SERVICE_ALARM_TOGGLE_CHIME),
schema=ALARM_TOGGLE_CHIME_SCHEMA)

View File

@ -6,7 +6,6 @@ https://home-assistant.io/components/alarm_control_panel.envisalink/
"""
import asyncio
import logging
import os
import voluptuous as vol
@ -14,7 +13,6 @@ from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
import homeassistant.components.alarm_control_panel as alarm
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.components.envisalink import (
DATA_EVL, EnvisalinkDevice, PARTITION_SCHEMA, CONF_CODE, CONF_PANIC,
CONF_PARTITIONNAME, SIGNAL_KEYPAD_UPDATE, SIGNAL_PARTITION_UPDATE)
@ -69,14 +67,9 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
for device in target_devices:
device.async_alarm_keypress(keypress)
# Register Envisalink specific services
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
alarm.DOMAIN, SERVICE_ALARM_KEYPRESS, alarm_keypress_handler,
descriptions.get(SERVICE_ALARM_KEYPRESS), schema=ALARM_KEYPRESS_SCHEMA)
schema=ALARM_KEYPRESS_SCHEMA)
return True

View File

@ -7,12 +7,10 @@ https://home-assistant.io/components/alert/
import asyncio
from datetime import datetime, timedelta
import logging
import os
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
CONF_ENTITY_ID, STATE_IDLE, CONF_NAME, CONF_STATE, STATE_ON, STATE_OFF,
SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE, ATTR_ENTITY_ID)
@ -129,22 +127,16 @@ def async_setup(hass, config):
alert[CONF_NOTIFIERS], alert[CONF_CAN_ACK])
all_alerts[entity.entity_id] = entity
# Read descriptions
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
descriptions = descriptions.get(DOMAIN, {})
# Setup service calls
hass.services.async_register(
DOMAIN, SERVICE_TURN_OFF, async_handle_alert_service,
descriptions.get(SERVICE_TURN_OFF), schema=ALERT_SERVICE_SCHEMA)
schema=ALERT_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TURN_ON, async_handle_alert_service,
descriptions.get(SERVICE_TURN_ON), schema=ALERT_SERVICE_SCHEMA)
schema=ALERT_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TOGGLE, async_handle_alert_service,
descriptions.get(SERVICE_TOGGLE), schema=ALERT_SERVICE_SCHEMA)
schema=ALERT_SERVICE_SCHEMA)
tasks = [alert.async_update_ha_state() for alert in all_alerts.values()]
if tasks:

View File

@ -24,6 +24,7 @@ from homeassistant.const import (
__version__)
from homeassistant.exceptions import TemplateError
from homeassistant.helpers.state import AsyncTrackStates
from homeassistant.helpers.service import async_get_all_descriptions
from homeassistant.helpers import template
from homeassistant.components.http import HomeAssistantView
@ -293,10 +294,11 @@ class APIServicesView(HomeAssistantView):
url = URL_API_SERVICES
name = "api:services"
@ha.callback
@asyncio.coroutine
def get(self, request):
"""Get registered services."""
return self.json(async_services_json(request.app['hass']))
services = yield from async_services_json(request.app['hass'])
return self.json(services)
class APIDomainServicesView(HomeAssistantView):
@ -355,10 +357,12 @@ class APITemplateView(HomeAssistantView):
HTTP_BAD_REQUEST)
@asyncio.coroutine
def async_services_json(hass):
"""Generate services data to JSONify."""
descriptions = yield from async_get_all_descriptions(hass)
return [{"domain": key, "services": value}
for key, value in hass.services.async_services().items()]
for key, value in descriptions.items()]
def async_events_json(hass):

View File

@ -4,7 +4,6 @@ Support for Apple TV.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/apple_tv/
"""
import os
import asyncio
import logging
@ -12,7 +11,6 @@ import voluptuous as vol
from typing import Union, TypeVar, Sequence
from homeassistant.const import (CONF_HOST, CONF_NAME, ATTR_ENTITY_ID)
from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers import discovery
from homeassistant.components.discovery import SERVICE_APPLE_TV
@ -183,18 +181,12 @@ def async_setup(hass, config):
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_SCAN, async_service_handler,
descriptions.get(SERVICE_SCAN),
schema=APPLE_TV_SCAN_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_AUTHENTICATE, async_service_handler,
descriptions.get(SERVICE_AUTHENTICATE),
schema=APPLE_TV_AUTHENTICATE_SCHEMA)
return True

View File

@ -7,14 +7,12 @@ https://home-assistant.io/components/automation/
import asyncio
from functools import partial
import logging
import os
import voluptuous as vol
from homeassistant.setup import async_prepare_setup_platform
from homeassistant.core import CoreState
from homeassistant.loader import bind_hass
from homeassistant import config as conf_util
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_PLATFORM, STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF,
SERVICE_TOGGLE, SERVICE_RELOAD, EVENT_HOMEASSISTANT_START, CONF_ID)
@ -166,11 +164,6 @@ def async_setup(hass, config):
yield from _async_process_config(hass, config, component)
descriptions = yield from hass.async_add_job(
conf_util.load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml')
)
@asyncio.coroutine
def trigger_service_handler(service_call):
"""Handle automation triggers."""
@ -216,20 +209,20 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_TRIGGER, trigger_service_handler,
descriptions.get(SERVICE_TRIGGER), schema=TRIGGER_SERVICE_SCHEMA)
schema=TRIGGER_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_RELOAD, reload_service_handler,
descriptions.get(SERVICE_RELOAD), schema=RELOAD_SERVICE_SCHEMA)
schema=RELOAD_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TOGGLE, toggle_service_handler,
descriptions.get(SERVICE_TOGGLE), schema=SERVICE_SCHEMA)
schema=SERVICE_SCHEMA)
for service in (SERVICE_TURN_ON, SERVICE_TURN_OFF):
hass.services.async_register(
DOMAIN, service, turn_onoff_service_handler,
descriptions.get(service), schema=SERVICE_SCHEMA)
schema=SERVICE_SCHEMA)
return True

View File

@ -6,12 +6,10 @@ https://home-assistant.io/components/axis/
"""
import logging
import os
import voluptuous as vol
from homeassistant.components.discovery import SERVICE_AXIS
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (ATTR_LOCATION, ATTR_TRIPPED,
CONF_EVENT, CONF_HOST, CONF_INCLUDE,
CONF_NAME, CONF_PASSWORD, CONF_PORT,
@ -195,10 +193,6 @@ def setup(hass, config):
if not setup_device(hass, config, device_config):
_LOGGER.error("Couldn\'t set up %s", device_config[CONF_NAME])
# Services to communicate with device.
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
def vapix_service(call):
"""Service to send a message."""
for _, device in AXIS_DEVICES.items():
@ -216,7 +210,6 @@ def setup(hass, config):
hass.services.register(DOMAIN,
SERVICE_VAPIX_CALL,
vapix_service,
descriptions[DOMAIN][SERVICE_VAPIX_CALL],
schema=SERVICE_SCHEMA)
return True

View File

@ -9,7 +9,6 @@ https://home-assistant.io/components/calendar.todoist/
from datetime import datetime
from datetime import timedelta
import logging
import os
import voluptuous as vol
@ -17,7 +16,6 @@ from homeassistant.components.calendar import (
CalendarEventDevice, PLATFORM_SCHEMA)
from homeassistant.components.google import (
CONF_DEVICE_ID)
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
CONF_ID, CONF_NAME, CONF_TOKEN)
import homeassistant.helpers.config_validation as cv
@ -178,10 +176,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices(project_devices)
# Services:
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
def handle_new_task(call):
"""Called when a user creates a new Todoist Task from HASS."""
project_name = call.data[PROJECT_NAME]
@ -215,7 +209,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
_LOGGER.debug("Created Todoist task: %s", call.data[CONTENT])
hass.services.register(DOMAIN, SERVICE_NEW_TASK, handle_new_task,
descriptions[DOMAIN][SERVICE_NEW_TASK],
schema=NEW_TASK_SERVICE_SCHEMA)

View File

@ -12,7 +12,6 @@ from datetime import timedelta
import logging
import hashlib
from random import SystemRandom
import os
import aiohttp
from aiohttp import web
@ -21,7 +20,6 @@ import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import (ATTR_ENTITY_ID, ATTR_ENTITY_PICTURE)
from homeassistant.config import load_yaml_config_file
from homeassistant.exceptions import HomeAssistantError
from homeassistant.loader import bind_hass
from homeassistant.helpers.aiohttp_client import async_get_clientsession
@ -190,19 +188,14 @@ def async_setup(hass, config):
except OSError as err:
_LOGGER.error("Can't write image to file: %s", err)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_ENABLE_MOTION, async_handle_camera_service,
descriptions.get(SERVICE_ENABLE_MOTION), schema=CAMERA_SERVICE_SCHEMA)
schema=CAMERA_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_DISABLE_MOTION, async_handle_camera_service,
descriptions.get(SERVICE_DISABLE_MOTION), schema=CAMERA_SERVICE_SCHEMA)
schema=CAMERA_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_SNAPSHOT, async_handle_snapshot_service,
descriptions.get(SERVICE_SNAPSHOT),
schema=CAMERA_SERVICE_SNAPSHOT)
return True

View File

@ -7,12 +7,10 @@ https://home-assistant.io/components/climate/
import asyncio
from datetime import timedelta
import logging
import os
import functools as ft
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
from homeassistant.loader import bind_hass
from homeassistant.helpers.temperature import display_temp as show_temp
from homeassistant.util.temperature import convert as convert_temperature
@ -245,10 +243,6 @@ def async_setup(hass, config):
component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL)
yield from component.async_setup(config)
descriptions = yield from hass.async_add_job(
load_yaml_config_file,
os.path.join(os.path.dirname(__file__), 'services.yaml'))
@asyncio.coroutine
def async_away_mode_set_service(service):
"""Set away mode on target climate devices."""
@ -272,7 +266,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET_AWAY_MODE, async_away_mode_set_service,
descriptions.get(SERVICE_SET_AWAY_MODE),
schema=SET_AWAY_MODE_SCHEMA)
@asyncio.coroutine
@ -295,7 +288,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET_HOLD_MODE, async_hold_mode_set_service,
descriptions.get(SERVICE_SET_HOLD_MODE),
schema=SET_HOLD_MODE_SCHEMA)
@asyncio.coroutine
@ -321,7 +313,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET_AUX_HEAT, async_aux_heat_set_service,
descriptions.get(SERVICE_SET_AUX_HEAT),
schema=SET_AUX_HEAT_SCHEMA)
@asyncio.coroutine
@ -353,7 +344,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET_TEMPERATURE, async_temperature_set_service,
descriptions.get(SERVICE_SET_TEMPERATURE),
schema=SET_TEMPERATURE_SCHEMA)
@asyncio.coroutine
@ -375,7 +365,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET_HUMIDITY, async_humidity_set_service,
descriptions.get(SERVICE_SET_HUMIDITY),
schema=SET_HUMIDITY_SCHEMA)
@asyncio.coroutine
@ -397,7 +386,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET_FAN_MODE, async_fan_mode_set_service,
descriptions.get(SERVICE_SET_FAN_MODE),
schema=SET_FAN_MODE_SCHEMA)
@asyncio.coroutine
@ -419,7 +407,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET_OPERATION_MODE, async_operation_set_service,
descriptions.get(SERVICE_SET_OPERATION_MODE),
schema=SET_OPERATION_MODE_SCHEMA)
@asyncio.coroutine
@ -441,7 +428,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET_SWING_MODE, async_swing_set_service,
descriptions.get(SERVICE_SET_SWING_MODE),
schema=SET_SWING_MODE_SCHEMA)
@asyncio.coroutine
@ -465,10 +451,10 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_TURN_OFF, async_on_off_service,
descriptions.get(SERVICE_TURN_OFF), schema=ON_OFF_SERVICE_SCHEMA)
schema=ON_OFF_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TURN_ON, async_on_off_service,
descriptions.get(SERVICE_TURN_ON), schema=ON_OFF_SERVICE_SCHEMA)
schema=ON_OFF_SERVICE_SCHEMA)
return True

View File

@ -5,7 +5,6 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/climate.ecobee/
"""
import logging
from os import path
import voluptuous as vol
@ -17,7 +16,6 @@ from homeassistant.components.climate import (
SUPPORT_TARGET_HUMIDITY_LOW, SUPPORT_TARGET_HUMIDITY_HIGH)
from homeassistant.const import (
ATTR_ENTITY_ID, STATE_OFF, STATE_ON, ATTR_TEMPERATURE, TEMP_FAHRENHEIT)
from homeassistant.config import load_yaml_config_file
import homeassistant.helpers.config_validation as cv
_CONFIGURING = {}
@ -96,17 +94,12 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
thermostat.schedule_update_ha_state(True)
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
hass.services.register(
DOMAIN, SERVICE_SET_FAN_MIN_ON_TIME, fan_min_on_time_set_service,
descriptions.get(SERVICE_SET_FAN_MIN_ON_TIME),
schema=SET_FAN_MIN_ON_TIME_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_RESUME_PROGRAM, resume_program_set_service,
descriptions.get(SERVICE_RESUME_PROGRAM),
schema=RESUME_PROGRAM_SCHEMA)

View File

@ -6,7 +6,6 @@ https://home-assistant.io/components/climate.econet/
"""
import datetime
import logging
from os import path
import voluptuous as vol
@ -18,7 +17,6 @@ from homeassistant.components.climate import (
STATE_OFF, SUPPORT_TARGET_TEMPERATURE,
SUPPORT_OPERATION_MODE,
ClimateDevice)
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (ATTR_ENTITY_ID,
CONF_PASSWORD, CONF_USERNAME, TEMP_FAHRENHEIT,
ATTR_TEMPERATURE)
@ -107,17 +105,12 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
_water_heater.schedule_update_ha_state(True)
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
hass.services.register(DOMAIN, SERVICE_ADD_VACATION,
service_handle,
descriptions.get(SERVICE_ADD_VACATION),
schema=ADD_VACATION_SCHEMA)
hass.services.register(DOMAIN, SERVICE_DELETE_VACATION,
service_handle,
descriptions.get(SERVICE_DELETE_VACATION),
schema=DELETE_VACATION_SCHEMA)

View File

@ -6,7 +6,6 @@ https://home-assistant.io/components/climate.nuheat/
"""
import logging
from datetime import timedelta
from os import path
import voluptuous as vol
@ -20,7 +19,6 @@ from homeassistant.components.climate import (
STATE_HEAT,
STATE_IDLE)
from homeassistant.components.nuheat import DOMAIN as NUHEAT_DOMAIN
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_TEMPERATURE,
@ -85,12 +83,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
thermostat.schedule_update_ha_state(True)
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), "services.yaml"))
hass.services.register(
DOMAIN, SERVICE_RESUME_PROGRAM, resume_program_set_service,
descriptions.get(SERVICE_RESUME_PROGRAM),
schema=RESUME_PROGRAM_SCHEMA)

View File

@ -6,12 +6,10 @@ at https://home-assistant.io/components/counter/
"""
import asyncio
import logging
import os
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (ATTR_ENTITY_ID, CONF_ICON, CONF_NAME)
from homeassistant.core import callback
from homeassistant.helpers.entity import Entity
@ -133,20 +131,12 @@ def async_setup(hass, config):
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml')
)
hass.services.async_register(
DOMAIN, SERVICE_INCREMENT, async_handler_service,
descriptions[SERVICE_INCREMENT], SERVICE_SCHEMA)
DOMAIN, SERVICE_INCREMENT, async_handler_service)
hass.services.async_register(
DOMAIN, SERVICE_DECREMENT, async_handler_service,
descriptions[SERVICE_DECREMENT], SERVICE_SCHEMA)
DOMAIN, SERVICE_DECREMENT, async_handler_service)
hass.services.async_register(
DOMAIN, SERVICE_RESET, async_handler_service,
descriptions[SERVICE_RESET], SERVICE_SCHEMA)
DOMAIN, SERVICE_RESET, async_handler_service)
yield from component.async_add_entities(entities)
return True

View File

@ -8,11 +8,9 @@ import asyncio
from datetime import timedelta
import functools as ft
import logging
import os
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
from homeassistant.loader import bind_hass
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.entity import Entity
@ -179,16 +177,12 @@ def async_setup(hass, config):
if update_tasks:
yield from asyncio.wait(update_tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
for service_name in SERVICE_TO_METHOD:
schema = SERVICE_TO_METHOD[service_name].get(
'schema', COVER_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, service_name, async_handle_cover_service,
descriptions.get(service_name), schema=schema)
schema=schema)
return True

View File

@ -7,10 +7,8 @@ https://home-assistant.io/components/deconz/
import asyncio
import logging
import os
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
CONF_API_KEY, CONF_HOST, CONF_PORT, EVENT_HOMEASSISTANT_STOP)
from homeassistant.components.discovery import SERVICE_DECONZ
@ -107,10 +105,6 @@ def async_setup_deconz(hass, config, deconz_config):
hass, component, DOMAIN, {}, config))
deconz.start()
descriptions = yield from hass.async_add_job(
load_yaml_config_file,
os.path.join(os.path.dirname(__file__), 'services.yaml'))
@asyncio.coroutine
def async_configure(call):
"""Set attribute of device in deCONZ.
@ -132,7 +126,7 @@ def async_setup_deconz(hass, config, deconz_config):
yield from deconz.async_put_state(field, data)
hass.services.async_register(
DOMAIN, 'configure', async_configure,
descriptions['configure'], schema=SERVICE_SCHEMA)
schema=SERVICE_SCHEMA)
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, deconz.close)
return True

View File

@ -7,7 +7,6 @@ https://home-assistant.io/components/device_tracker/
import asyncio
from datetime import timedelta
import logging
import os
from typing import Any, List, Sequence, Callable
import aiohttp
@ -207,12 +206,7 @@ def async_setup(hass: HomeAssistantType, config: ConfigType):
ATTR_GPS, ATTR_GPS_ACCURACY, ATTR_BATTERY, ATTR_ATTRIBUTES)}
yield from tracker.async_see(**args)
descriptions = yield from hass.async_add_job(
load_yaml_config_file,
os.path.join(os.path.dirname(__file__), 'services.yaml')
)
hass.services.async_register(
DOMAIN, SERVICE_SEE, async_see_service, descriptions.get(SERVICE_SEE))
hass.services.async_register(DOMAIN, SERVICE_SEE, async_see_service)
# restore
yield from tracker.async_setup_tracked_device()

View File

@ -6,13 +6,11 @@ https://home-assistant.io/components/eight_sleep/
"""
import asyncio
import logging
import os
from datetime import timedelta
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
CONF_USERNAME, CONF_PASSWORD, CONF_SENSORS, CONF_BINARY_SENSORS,
ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_STOP)
@ -159,10 +157,6 @@ def async_setup(hass, config):
CONF_BINARY_SENSORS: binary_sensors,
}, config))
descriptions = yield from hass.async_add_job(
load_yaml_config_file,
os.path.join(os.path.dirname(__file__), 'services.yaml'))
@asyncio.coroutine
def async_service_handler(service):
"""Handle eight sleep service calls."""
@ -183,7 +177,6 @@ def async_setup(hass, config):
# Register services
hass.services.async_register(
DOMAIN, SERVICE_HEAT_SET, async_service_handler,
descriptions[DOMAIN].get(SERVICE_HEAT_SET),
schema=SERVICE_EIGHT_SCHEMA)
@asyncio.coroutine

View File

@ -8,12 +8,10 @@ import asyncio
from datetime import timedelta
import functools as ft
import logging
import os
import voluptuous as vol
from homeassistant.components import group
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (SERVICE_TURN_ON, SERVICE_TOGGLE,
SERVICE_TURN_OFF, ATTR_ENTITY_ID,
STATE_UNKNOWN)
@ -225,16 +223,10 @@ def async_setup(hass, config: dict):
if update_tasks:
yield from asyncio.wait(update_tasks, loop=hass.loop)
# Listen for fan service calls.
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
for service_name in SERVICE_TO_METHOD:
schema = SERVICE_TO_METHOD[service_name].get('schema')
hass.services.async_register(
DOMAIN, service_name, async_handle_fan_service,
descriptions.get(service_name), schema=schema)
DOMAIN, service_name, async_handle_fan_service, schema=schema)
return True

View File

@ -5,7 +5,6 @@ https://home-assistant.io/components/fan.dyson/
"""
import logging
import asyncio
from os import path
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.fan import (FanEntity, SUPPORT_OSCILLATE,
@ -13,7 +12,6 @@ from homeassistant.components.fan import (FanEntity, SUPPORT_OSCILLATE,
DOMAIN)
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.components.dyson import DYSON_DEVICES
from homeassistant.config import load_yaml_config_file
DEPENDENCIES = ['dyson']
@ -44,9 +42,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices(hass.data[DYSON_FAN_DEVICES])
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
def service_handle(service):
"""Handle dyson services."""
entity_id = service.data.get('entity_id')
@ -64,7 +59,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
# Register dyson service(s)
hass.services.register(DOMAIN, SERVICE_SET_NIGHT_MODE,
service_handle,
descriptions.get(SERVICE_SET_NIGHT_MODE),
schema=DYSON_SET_NIGHT_MODE_SCHEMA)

View File

@ -7,14 +7,12 @@ https://home-assistant.io/components/fan.xiaomi_miio/
import asyncio
from functools import partial
import logging
import os
import voluptuous as vol
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.components.fan import (FanEntity, PLATFORM_SCHEMA,
SUPPORT_SET_SPEED, DOMAIN)
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (CONF_NAME, CONF_HOST, CONF_TOKEN,
ATTR_ENTITY_ID, )
from homeassistant.exceptions import PlatformNotReady
@ -131,16 +129,11 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
if update_tasks:
yield from asyncio.wait(update_tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'xiaomi_miio_services.yaml'))
for air_purifier_service in SERVICE_TO_METHOD:
schema = SERVICE_TO_METHOD[air_purifier_service].get(
'schema', AIRPURIFIER_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, air_purifier_service, async_service_handler,
description=descriptions.get(air_purifier_service), schema=schema)
DOMAIN, air_purifier_service, async_service_handler, schema=schema)
class XiaomiAirPurifier(FanEntity):

View File

@ -6,14 +6,12 @@ https://home-assistant.io/components/ffmpeg/
"""
import asyncio
import logging
import os
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import (
ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.dispatcher import (
async_dispatcher_send, async_dispatcher_connect)
import homeassistant.helpers.config_validation as cv
@ -89,10 +87,6 @@ def async_setup(hass, config):
conf.get(CONF_RUN_TEST, DEFAULT_RUN_TEST)
)
descriptions = yield from hass.async_add_job(
load_yaml_config_file,
os.path.join(os.path.dirname(__file__), 'services.yaml'))
# Register service
@asyncio.coroutine
def async_service_handle(service):
@ -108,15 +102,14 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_START, async_service_handle,
descriptions[DOMAIN].get(SERVICE_START), schema=SERVICE_FFMPEG_SCHEMA)
schema=SERVICE_FFMPEG_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_STOP, async_service_handle,
descriptions[DOMAIN].get(SERVICE_STOP), schema=SERVICE_FFMPEG_SCHEMA)
schema=SERVICE_FFMPEG_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_RESTART, async_service_handle,
descriptions[DOMAIN].get(SERVICE_RESTART),
schema=SERVICE_FFMPEG_SCHEMA)
hass.data[DATA_FFMPEG] = manager

View File

@ -6,14 +6,12 @@ https://home-assistant.io/components/foursquare/
"""
import asyncio
import logging
import os
import requests
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.const import CONF_ACCESS_TOKEN, HTTP_BAD_REQUEST
from homeassistant.config import load_yaml_config_file
from homeassistant.components.http import HomeAssistantView
_LOGGER = logging.getLogger(__name__)
@ -50,9 +48,6 @@ CONFIG_SCHEMA = vol.Schema({
def setup(hass, config):
"""Set up the Foursquare component."""
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
config = config[DOMAIN]
def checkin_user(call):
@ -72,7 +67,6 @@ def setup(hass, config):
# Register our service with Home Assistant.
hass.services.register(DOMAIN, 'checkin', checkin_user,
descriptions[DOMAIN][SERVICE_CHECKIN],
schema=CHECKIN_SERVICE_SCHEMA)
hass.http.register_view(FoursquarePushReceiver(config[CONF_PUSH_SECRET]))

View File

@ -376,12 +376,11 @@ def async_setup(hass, config):
for url in conf.get(CONF_EXTRA_HTML_URL_ES5, []):
add_extra_html_url(hass, url, True)
yield from async_setup_themes(hass, conf.get(CONF_THEMES))
async_setup_themes(hass, conf.get(CONF_THEMES))
return True
@asyncio.coroutine
def async_setup_themes(hass, themes):
"""Set up themes data and services."""
hass.http.register_view(ThemesView)
@ -428,16 +427,9 @@ def async_setup_themes(hass, themes):
hass.data[DATA_DEFAULT_THEME] = DEFAULT_THEME
update_theme_and_fire_event()
descriptions = yield from hass.async_add_job(
load_yaml_config_file,
os.path.join(os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(DOMAIN, SERVICE_SET_THEME,
set_theme,
descriptions[SERVICE_SET_THEME],
SERVICE_SET_THEME_SCHEMA)
hass.services.async_register(DOMAIN, SERVICE_RELOAD_THEMES, reload_themes,
descriptions[SERVICE_RELOAD_THEMES])
hass.services.async_register(
DOMAIN, SERVICE_SET_THEME, set_theme, schema=SERVICE_SET_THEME_SCHEMA)
hass.services.async_register(DOMAIN, SERVICE_RELOAD_THEMES, reload_themes)
class IndexView(HomeAssistantView):

View File

@ -190,8 +190,7 @@ def setup_services(hass, track_new_found_calendars, calendar_service):
hass.data[DATA_INDEX][calendar[CONF_CAL_ID]])
hass.services.register(
DOMAIN, SERVICE_FOUND_CALENDARS, _found_calendar,
None, schema=None)
DOMAIN, SERVICE_FOUND_CALENDARS, _found_calendar)
def _scan_for_calendars(service):
"""Scan for new calendars."""
@ -204,9 +203,7 @@ def setup_services(hass, track_new_found_calendars, calendar_service):
calendar)
hass.services.register(
DOMAIN, SERVICE_SCAN_CALENDARS,
_scan_for_calendars,
None, schema=None)
DOMAIN, SERVICE_SCAN_CALENDARS, _scan_for_calendars)
return True

View File

@ -4,7 +4,6 @@ Support for Actions on Google Assistant Smart Home Control.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/google_assistant/
"""
import os
import asyncio
import logging
@ -18,7 +17,6 @@ import voluptuous as vol
from homeassistant.core import HomeAssistant # NOQA
from typing import Dict, Any # NOQA
from homeassistant import config as conf_util
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.loader import bind_hass
@ -68,11 +66,6 @@ def async_setup(hass: HomeAssistant, yaml_config: Dict[str, Any]):
config = yaml_config.get(DOMAIN, {})
agent_user_id = config.get(CONF_AGENT_USER_ID)
api_key = config.get(CONF_API_KEY)
if api_key is not None:
descriptions = yield from hass.async_add_job(
conf_util.load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml')
)
hass.http.register_view(GoogleAssistantAuthView(hass, config))
async_register_http(hass, config)
@ -98,7 +91,6 @@ def async_setup(hass: HomeAssistant, yaml_config: Dict[str, Any]):
# Register service only if api key is provided
if api_key is not None:
hass.services.async_register(
DOMAIN, SERVICE_REQUEST_SYNC, request_sync_service_handler,
descriptions.get(SERVICE_REQUEST_SYNC))
DOMAIN, SERVICE_REQUEST_SYNC, request_sync_service_handler)
return True

View File

@ -6,11 +6,10 @@ https://home-assistant.io/components/group/
"""
import asyncio
import logging
import os
import voluptuous as vol
from homeassistant import config as conf_util, core as ha
from homeassistant import core as ha
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_ICON, CONF_NAME, STATE_CLOSED, STATE_HOME,
STATE_NOT_HOME, STATE_OFF, STATE_ON, STATE_OPEN, STATE_LOCKED,
@ -254,11 +253,6 @@ def async_setup(hass, config):
yield from _async_process_config(hass, config, component)
descriptions = yield from hass.async_add_job(
conf_util.load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml')
)
@asyncio.coroutine
def reload_service_handler(service):
"""Remove all groups and load new ones from config."""
@ -269,7 +263,7 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_RELOAD, reload_service_handler,
descriptions[SERVICE_RELOAD], schema=RELOAD_SERVICE_SCHEMA)
schema=RELOAD_SERVICE_SCHEMA)
@asyncio.coroutine
def groups_service_handler(service):
@ -346,11 +340,11 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET, groups_service_handler,
descriptions[SERVICE_SET], schema=SET_SERVICE_SCHEMA)
schema=SET_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_REMOVE, groups_service_handler,
descriptions[SERVICE_REMOVE], schema=REMOVE_SERVICE_SCHEMA)
schema=REMOVE_SERVICE_SCHEMA)
@asyncio.coroutine
def visibility_service_handler(service):
@ -368,7 +362,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET_VISIBILITY, visibility_service_handler,
descriptions[SERVICE_SET_VISIBILITY],
schema=SET_VISIBILITY_SERVICE_SCHEMA)
return True

View File

@ -6,7 +6,6 @@ https://home-assistant.io/components/hdmi_cec/
"""
import logging
import multiprocessing
import os
from collections import defaultdict
from functools import reduce
@ -16,7 +15,6 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers import discovery
from homeassistant.components.media_player import DOMAIN as MEDIA_PLAYER
from homeassistant.components.switch import DOMAIN as SWITCH
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (EVENT_HOMEASSISTANT_START, STATE_UNKNOWN,
EVENT_HOMEASSISTANT_STOP, STATE_ON,
STATE_OFF, CONF_DEVICES, CONF_PLATFORM,
@ -301,17 +299,12 @@ def setup(hass: HomeAssistant, base_config):
def _start_cec(event):
"""Register services and start HDMI network to watch for devices."""
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))[DOMAIN]
hass.services.register(DOMAIN, SERVICE_SEND_COMMAND, _tx,
descriptions[SERVICE_SEND_COMMAND],
SERVICE_SEND_COMMAND_SCHEMA)
hass.services.register(DOMAIN, SERVICE_VOLUME, _volume,
descriptions[SERVICE_VOLUME],
SERVICE_VOLUME_SCHEMA)
schema=SERVICE_VOLUME_SCHEMA)
hass.services.register(DOMAIN, SERVICE_UPDATE_DEVICES, _update,
descriptions[SERVICE_UPDATE_DEVICES],
SERVICE_UPDATE_DEVICES_SCHEMA)
schema=SERVICE_UPDATE_DEVICES_SCHEMA)
hass.services.register(DOMAIN, SERVICE_POWER_ON, _power_on)
hass.services.register(DOMAIN, SERVICE_STANDBY, _standby)
hass.services.register(DOMAIN, SERVICE_SELECT_DEVICE, _select_device)

View File

@ -8,12 +8,10 @@ import asyncio
from datetime import timedelta
from functools import partial
import logging
import os
import socket
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
EVENT_HOMEASSISTANT_STOP, CONF_USERNAME, CONF_PASSWORD, CONF_PLATFORM,
CONF_HOSTS, CONF_HOST, ATTR_ENTITY_ID, STATE_UNKNOWN)
@ -330,10 +328,6 @@ def setup(hass, config):
for hub_name in conf[CONF_HOSTS].keys():
entity_hubs.append(HMHub(hass, homematic, hub_name))
# Register HomeMatic services
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
def _hm_service_virtualkey(service):
"""Service to handle virtualkey servicecalls."""
address = service.data.get(ATTR_ADDRESS)
@ -362,7 +356,7 @@ def setup(hass, config):
hass.services.register(
DOMAIN, SERVICE_VIRTUALKEY, _hm_service_virtualkey,
descriptions[SERVICE_VIRTUALKEY], schema=SCHEMA_SERVICE_VIRTUALKEY)
schema=SCHEMA_SERVICE_VIRTUALKEY)
def _service_handle_value(service):
"""Service to call setValue method for HomeMatic system variable."""
@ -385,7 +379,6 @@ def setup(hass, config):
hass.services.register(
DOMAIN, SERVICE_SET_VARIABLE_VALUE, _service_handle_value,
descriptions[SERVICE_SET_VARIABLE_VALUE],
schema=SCHEMA_SERVICE_SET_VARIABLE_VALUE)
def _service_handle_reconnect(service):
@ -394,7 +387,7 @@ def setup(hass, config):
hass.services.register(
DOMAIN, SERVICE_RECONNECT, _service_handle_reconnect,
descriptions[SERVICE_RECONNECT], schema=SCHEMA_SERVICE_RECONNECT)
schema=SCHEMA_SERVICE_RECONNECT)
def _service_handle_device(service):
"""Service to call setValue method for HomeMatic devices."""
@ -413,7 +406,6 @@ def setup(hass, config):
hass.services.register(
DOMAIN, SERVICE_SET_DEVICE_VALUE, _service_handle_device,
descriptions[SERVICE_SET_DEVICE_VALUE],
schema=SCHEMA_SERVICE_SET_DEVICE_VALUE)
def _service_handle_install_mode(service):
@ -427,7 +419,6 @@ def setup(hass, config):
hass.services.register(
DOMAIN, SERVICE_SET_INSTALL_MODE, _service_handle_install_mode,
descriptions[SERVICE_SET_INSTALL_MODE],
schema=SCHEMA_SERVICE_SET_INSTALL_MODE)
return True

View File

@ -12,7 +12,6 @@ import socket
import voluptuous as vol
from homeassistant.components.discovery import SERVICE_HUE
from homeassistant.config import load_yaml_config_file
from homeassistant.const import CONF_FILENAME, CONF_HOST
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers import discovery
@ -207,11 +206,8 @@ class HueBridge(object):
scene_name = call.data[ATTR_SCENE_NAME]
self.bridge.run_scene(group_name, scene_name)
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
self.hass.services.register(
DOMAIN, SERVICE_HUE_SCENE, hue_activate_scene,
descriptions.get(SERVICE_HUE_SCENE),
schema=SCENE_SCHEMA)
def request_configuration(self):

View File

@ -7,12 +7,10 @@ https://home-assistant.io/components/image_processing/
import asyncio
from datetime import timedelta
import logging
import os
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_NAME, CONF_ENTITY_ID)
from homeassistant.exceptions import HomeAssistantError
@ -74,10 +72,6 @@ def async_setup(hass, config):
yield from component.async_setup(config)
descriptions = yield from hass.async_add_job(
load_yaml_config_file,
os.path.join(os.path.dirname(__file__), 'services.yaml'))
@asyncio.coroutine
def async_scan_service(service):
"""Service handler for scan."""
@ -90,7 +84,7 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SCAN, async_scan_service,
descriptions.get(SERVICE_SCAN), schema=SERVICE_SCAN_SCHEMA)
schema=SERVICE_SCAN_SCHEMA)
return True

View File

@ -6,7 +6,6 @@ at https://home-assistant.io/components/input_boolean/
"""
import asyncio
import logging
import os
import voluptuous as vol
@ -15,7 +14,6 @@ from homeassistant.const import (
SERVICE_TOGGLE, STATE_ON)
from homeassistant.loader import bind_hass
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.entity import ToggleEntity
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.restore_state import async_get_last_state
@ -103,22 +101,14 @@ def async_setup(hass, config):
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml')
)
hass.services.async_register(
DOMAIN, SERVICE_TURN_OFF, async_handler_service,
descriptions[DOMAIN][SERVICE_TURN_OFF],
schema=SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TURN_ON, async_handler_service,
descriptions[DOMAIN][SERVICE_TURN_ON],
schema=SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TOGGLE, async_handler_service,
descriptions[DOMAIN][SERVICE_TOGGLE],
schema=SERVICE_SCHEMA)
yield from component.async_add_entities(entities)

View File

@ -4,14 +4,12 @@ Component to offer a way to set a numeric value from a slider or text box.
For more details about this component, please refer to the documentation
at https://home-assistant.io/components/input_number/
"""
import os
import asyncio
import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_UNIT_OF_MEASUREMENT, CONF_ICON, CONF_NAME, CONF_MODE)
from homeassistant.helpers.entity import Entity
@ -165,14 +163,9 @@ def async_setup(hass, config):
if update_tasks:
yield from asyncio.wait(update_tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
for service, data in SERVICE_TO_METHOD.items():
hass.services.async_register(
DOMAIN, service, async_handle_service,
description=descriptions[DOMAIN][service], schema=data['schema'])
DOMAIN, service, async_handle_service, schema=data['schema'])
yield from component.async_add_entities(entities)
return True

View File

@ -6,14 +6,12 @@ at https://home-assistant.io/components/input_select/
"""
import asyncio
import logging
import os
import voluptuous as vol
from homeassistant.const import ATTR_ENTITY_ID, CONF_ICON, CONF_NAME
from homeassistant.loader import bind_hass
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.restore_state import async_get_last_state
@ -131,11 +129,6 @@ def async_setup(hass, config):
if not entities:
return False
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml')
)
@asyncio.coroutine
def async_select_option_service(call):
"""Handle a calls to the input select option service."""
@ -148,7 +141,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SELECT_OPTION, async_select_option_service,
descriptions[DOMAIN][SERVICE_SELECT_OPTION],
schema=SERVICE_SELECT_OPTION_SCHEMA)
@asyncio.coroutine
@ -163,7 +155,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SELECT_NEXT, async_select_next_service,
descriptions[DOMAIN][SERVICE_SELECT_NEXT],
schema=SERVICE_SELECT_NEXT_SCHEMA)
@asyncio.coroutine
@ -178,7 +169,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SELECT_PREVIOUS, async_select_previous_service,
descriptions[DOMAIN][SERVICE_SELECT_PREVIOUS],
schema=SERVICE_SELECT_PREVIOUS_SCHEMA)
@asyncio.coroutine
@ -193,7 +183,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_SET_OPTIONS, async_set_options_service,
descriptions[DOMAIN][SERVICE_SET_OPTIONS],
schema=SERVICE_SET_OPTIONS_SCHEMA)
yield from component.async_add_entities(entities)

View File

@ -4,14 +4,12 @@ Component to offer a way to enter a value into a text box.
For more details about this component, please refer to the documentation
at https://home-assistant.io/components/input_text/
"""
import os
import asyncio
import logging
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_UNIT_OF_MEASUREMENT, CONF_ICON, CONF_NAME)
from homeassistant.loader import bind_hass
@ -112,13 +110,8 @@ def async_setup(hass, config):
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_SET_VALUE, async_set_value_service,
description=descriptions[DOMAIN][SERVICE_SET_VALUE],
schema=SERVICE_SET_VALUE_SCHEMA)
yield from component.async_add_entities(entities)

View File

@ -15,7 +15,6 @@ import voluptuous as vol
from homeassistant.core import callback
from homeassistant.loader import bind_hass
from homeassistant.components import group
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE,
ATTR_ENTITY_ID)
@ -282,21 +281,17 @@ def async_setup(hass, config):
yield from asyncio.wait(update_tasks, loop=hass.loop)
# Listen for light on and light off service calls.
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_TURN_ON, async_handle_light_service,
descriptions.get(SERVICE_TURN_ON), schema=LIGHT_TURN_ON_SCHEMA)
schema=LIGHT_TURN_ON_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TURN_OFF, async_handle_light_service,
descriptions.get(SERVICE_TURN_OFF), schema=LIGHT_TURN_OFF_SCHEMA)
schema=LIGHT_TURN_OFF_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TOGGLE, async_handle_light_service,
descriptions.get(SERVICE_TOGGLE), schema=LIGHT_TOGGLE_SCHEMA)
schema=LIGHT_TOGGLE_SCHEMA)
return True

View File

@ -8,7 +8,6 @@ import logging
import asyncio
import sys
import math
from os import path
from functools import partial
from datetime import timedelta
@ -22,7 +21,6 @@ from homeassistant.components.light import (
SUPPORT_XY_COLOR, SUPPORT_TRANSITION, SUPPORT_EFFECT,
VALID_BRIGHTNESS, VALID_BRIGHTNESS_PCT,
preprocess_turn_on_alternatives)
from homeassistant.config import load_yaml_config_file
from homeassistant.const import ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_STOP
from homeassistant import util
from homeassistant.core import callback
@ -210,13 +208,10 @@ class LIFXManager(object):
self.async_add_devices = async_add_devices
self.effects_conductor = aiolifx_effects().Conductor(loop=hass.loop)
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
self.register_set_state()
self.register_effects()
self.register_set_state(descriptions)
self.register_effects(descriptions)
def register_set_state(self, descriptions):
def register_set_state(self):
"""Register the LIFX set_state service call."""
@asyncio.coroutine
def async_service_handle(service):
@ -231,10 +226,9 @@ class LIFXManager(object):
self.hass.services.async_register(
DOMAIN, SERVICE_LIFX_SET_STATE, async_service_handle,
descriptions.get(SERVICE_LIFX_SET_STATE),
schema=LIFX_SET_STATE_SCHEMA)
def register_effects(self, descriptions):
def register_effects(self):
"""Register the LIFX effects as hass service calls."""
@asyncio.coroutine
def async_service_handle(service):
@ -246,17 +240,14 @@ class LIFXManager(object):
self.hass.services.async_register(
DOMAIN, SERVICE_EFFECT_PULSE, async_service_handle,
descriptions.get(SERVICE_EFFECT_PULSE),
schema=LIFX_EFFECT_PULSE_SCHEMA)
self.hass.services.async_register(
DOMAIN, SERVICE_EFFECT_COLORLOOP, async_service_handle,
descriptions.get(SERVICE_EFFECT_COLORLOOP),
schema=LIFX_EFFECT_COLORLOOP_SCHEMA)
self.hass.services.async_register(
DOMAIN, SERVICE_EFFECT_STOP, async_service_handle,
descriptions.get(SERVICE_EFFECT_STOP),
schema=LIFX_EFFECT_STOP_SCHEMA)
@asyncio.coroutine

View File

@ -8,11 +8,9 @@ import asyncio
from datetime import timedelta
import functools as ft
import logging
import os
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
from homeassistant.loader import bind_hass
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.entity import Entity
@ -104,16 +102,12 @@ def async_setup(hass, config):
if update_tasks:
yield from asyncio.wait(update_tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_UNLOCK, async_handle_lock_service,
descriptions.get(SERVICE_UNLOCK), schema=LOCK_SERVICE_SCHEMA)
schema=LOCK_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_LOCK, async_handle_lock_service,
descriptions.get(SERVICE_LOCK), schema=LOCK_SERVICE_SCHEMA)
schema=LOCK_SERVICE_SCHEMA)
return True

View File

@ -7,13 +7,11 @@ https://home-assistant.io/components/lock.nuki/
import asyncio
from datetime import timedelta
import logging
from os import path
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components.lock import (DOMAIN, LockDevice, PLATFORM_SCHEMA)
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_HOST, CONF_PORT, CONF_TOKEN)
from homeassistant.helpers.service import extract_entity_ids
@ -75,15 +73,12 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
elif service.service == SERVICE_UNLATCH:
lock.unlatch()
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
hass.services.register(
DOMAIN, SERVICE_LOCK_N_GO, service_handler,
descriptions.get(SERVICE_LOCK_N_GO), schema=LOCK_N_GO_SERVICE_SCHEMA)
schema=LOCK_N_GO_SERVICE_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_UNLATCH, service_handler,
descriptions.get(SERVICE_UNLATCH), schema=UNLATCH_SERVICE_SCHEMA)
schema=UNLATCH_SERVICE_SCHEMA)
class NukiLock(LockDevice):

View File

@ -6,7 +6,6 @@ https://home-assistant.io/components/lock.wink/
"""
import asyncio
import logging
from os import path
import voluptuous as vol
@ -14,7 +13,6 @@ from homeassistant.components.lock import LockDevice
from homeassistant.components.wink import WinkDevice, DOMAIN
import homeassistant.helpers.config_validation as cv
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN, ATTR_CODE
from homeassistant.config import load_yaml_config_file
DEPENDENCIES = ['wink']
@ -99,37 +97,28 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
code = service.data.get(ATTR_CODE)
lock.add_new_key(code, name)
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
hass.services.register(DOMAIN, SERVICE_SET_VACATION_MODE,
service_handle,
descriptions.get(SERVICE_SET_VACATION_MODE),
schema=SET_ENABLED_SCHEMA)
hass.services.register(DOMAIN, SERVICE_SET_ALARM_STATE,
service_handle,
descriptions.get(SERVICE_SET_ALARM_STATE),
schema=SET_ENABLED_SCHEMA)
hass.services.register(DOMAIN, SERVICE_SET_BEEPER_STATE,
service_handle,
descriptions.get(SERVICE_SET_BEEPER_STATE),
schema=SET_ENABLED_SCHEMA)
hass.services.register(DOMAIN, SERVICE_SET_ALARM_MODE,
service_handle,
descriptions.get(SERVICE_SET_ALARM_MODE),
schema=SET_ALARM_MODES_SCHEMA)
hass.services.register(DOMAIN, SERVICE_SET_ALARM_SENSITIVITY,
service_handle,
descriptions.get(SERVICE_SET_ALARM_SENSITIVITY),
schema=SET_SENSITIVITY_SCHEMA)
hass.services.register(DOMAIN, SERVICE_ADD_KEY,
service_handle,
descriptions.get(SERVICE_ADD_KEY),
schema=ADD_KEY_SCHEMA)

View File

@ -8,13 +8,11 @@ https://home-assistant.io/components/lock.zwave/
# pylint: disable=import-error
import asyncio
import logging
from os import path
import voluptuous as vol
from homeassistant.components.lock import DOMAIN, LockDevice
from homeassistant.components import zwave
from homeassistant.config import load_yaml_config_file
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
@ -126,8 +124,6 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
yield from zwave.async_setup_platform(
hass, config, async_add_devices, discovery_info)
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
network = hass.data[zwave.const.DATA_NETWORK]
def set_usercode(service):
@ -184,13 +180,13 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
hass.services.async_register(
DOMAIN, SERVICE_SET_USERCODE, set_usercode,
descriptions.get(SERVICE_SET_USERCODE), schema=SET_USERCODE_SCHEMA)
schema=SET_USERCODE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_GET_USERCODE, get_usercode,
descriptions.get(SERVICE_GET_USERCODE), schema=GET_USERCODE_SCHEMA)
schema=GET_USERCODE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_CLEAR_USERCODE, clear_usercode,
descriptions.get(SERVICE_CLEAR_USERCODE), schema=CLEAR_USERCODE_SCHEMA)
schema=CLEAR_USERCODE_SCHEMA)
def get_device(node, values, **kwargs):

View File

@ -6,12 +6,10 @@ https://home-assistant.io/components/logger/
"""
import asyncio
import logging
import os
from collections import OrderedDict
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
import homeassistant.helpers.config_validation as cv
DOMAIN = 'logger'
@ -123,13 +121,8 @@ def async_setup(hass, config):
"""Handle logger services."""
set_log_levels(service.data)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_SET_LEVEL, async_service_handler,
descriptions[DOMAIN].get(SERVICE_SET_LEVEL),
schema=SERVICE_SET_LEVEL_SCHEMA)
return True

View File

@ -5,7 +5,6 @@ For more details about this component, please refer to the documentation at
https://home-assistant.io/components/media_extractor/
"""
import logging
import os
import voluptuous as vol
@ -13,7 +12,6 @@ from homeassistant.components.media_player import (
ATTR_ENTITY_ID, ATTR_MEDIA_CONTENT_ID, ATTR_MEDIA_CONTENT_TYPE,
DOMAIN as MEDIA_PLAYER_DOMAIN, MEDIA_PLAYER_PLAY_MEDIA_SCHEMA,
SERVICE_PLAY_MEDIA)
from homeassistant.config import load_yaml_config_file
from homeassistant.helpers import config_validation as cv
REQUIREMENTS = ['youtube_dl==2017.12.28']
@ -38,18 +36,11 @@ CONFIG_SCHEMA = vol.Schema({
def setup(hass, config):
"""Set up the media extractor service."""
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__),
'media_player', 'services.yaml'))
def play_media(call):
"""Get stream URL and send it to the play_media service."""
MediaExtractor(hass, config[DOMAIN], call.data).extract_and_send()
hass.services.register(DOMAIN,
SERVICE_PLAY_MEDIA,
play_media,
description=descriptions[SERVICE_PLAY_MEDIA],
hass.services.register(DOMAIN, SERVICE_PLAY_MEDIA, play_media,
schema=MEDIA_PLAYER_PLAY_MEDIA_SCHEMA)
return True

View File

@ -10,7 +10,6 @@ import functools as ft
import collections
import hashlib
import logging
import os
from random import SystemRandom
from aiohttp import web
@ -19,7 +18,6 @@ import async_timeout
import voluptuous as vol
from homeassistant.components.http import KEY_AUTHENTICATED, HomeAssistantView
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
STATE_OFF, STATE_IDLE, STATE_PLAYING, STATE_UNKNOWN, ATTR_ENTITY_ID,
SERVICE_TOGGLE, SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_VOLUME_UP,
@ -372,10 +370,6 @@ def async_setup(hass, config):
yield from component.async_setup(config)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
@asyncio.coroutine
def async_service_handler(service):
"""Map services to methods on MediaPlayerDevice."""
@ -418,7 +412,7 @@ def async_setup(hass, config):
'schema', MEDIA_PLAYER_SCHEMA)
hass.services.async_register(
DOMAIN, service, async_service_handler,
descriptions.get(service), schema=schema)
schema=schema)
return True

View File

@ -10,12 +10,10 @@ from functools import wraps
import logging
import urllib
import re
import os
import aiohttp
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
from homeassistant.components.media_player import (
SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK,
SUPPORT_PLAY_MEDIA, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, SUPPORT_STOP,
@ -207,15 +205,11 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
if hass.services.has_service(DOMAIN, SERVICE_ADD_MEDIA):
return
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
for service in SERVICE_TO_METHOD:
schema = SERVICE_TO_METHOD[service]['schema']
hass.services.async_register(
DOMAIN, service, async_service_handler,
description=descriptions.get(service), schema=schema)
schema=schema)
def cmd(func):

View File

@ -5,13 +5,11 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.monoprice/
"""
import logging
from os import path
import voluptuous as vol
from homeassistant.const import (ATTR_ENTITY_ID, CONF_NAME, CONF_PORT,
STATE_OFF, STATE_ON)
from homeassistant.config import load_yaml_config_file
import homeassistant.helpers.config_validation as cv
from homeassistant.components.media_player import (
DOMAIN, MediaPlayerDevice, MEDIA_PLAYER_SCHEMA, PLATFORM_SCHEMA,
@ -83,9 +81,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices(hass.data[DATA_MONOPRICE], True)
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
def service_handle(service):
"""Handle for services."""
entity_ids = service.data.get(ATTR_ENTITY_ID)
@ -104,11 +99,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
hass.services.register(
DOMAIN, SERVICE_SNAPSHOT, service_handle,
descriptions.get(SERVICE_SNAPSHOT), schema=MEDIA_PLAYER_SCHEMA)
schema=MEDIA_PLAYER_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_RESTORE, service_handle,
descriptions.get(SERVICE_RESTORE), schema=MEDIA_PLAYER_SCHEMA)
schema=MEDIA_PLAYER_SCHEMA)
class MonopriceZone(MediaPlayerDevice):

View File

@ -6,7 +6,6 @@ https://home-assistant.io/components/media_player.snapcast/
"""
import asyncio
import logging
from os import path
import socket
import voluptuous as vol
@ -18,7 +17,6 @@ from homeassistant.const import (
STATE_ON, STATE_OFF, STATE_IDLE, STATE_PLAYING, STATE_UNKNOWN, CONF_HOST,
CONF_PORT, ATTR_ENTITY_ID)
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
REQUIREMENTS = ['snapcast==2.0.8']
@ -69,14 +67,12 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
elif service.service == SERVICE_RESTORE:
yield from device.async_restore()
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_SNAPSHOT, _handle_service,
descriptions.get(SERVICE_SNAPSHOT), schema=SERVICE_SCHEMA)
schema=SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_RESTORE, _handle_service,
descriptions.get(SERVICE_RESTORE), schema=SERVICE_SCHEMA)
schema=SERVICE_SCHEMA)
try:
server = yield from snapcast.control.create_server(

View File

@ -8,7 +8,6 @@ import asyncio
import datetime
import functools as ft
import logging
from os import path
import socket
import urllib
@ -23,7 +22,6 @@ from homeassistant.components.media_player import (
from homeassistant.const import (
STATE_IDLE, STATE_PAUSED, STATE_PLAYING, STATE_OFF, ATTR_ENTITY_ID,
CONF_HOSTS, ATTR_TIME)
from homeassistant.config import load_yaml_config_file
import homeassistant.helpers.config_validation as cv
from homeassistant.util.dt import utcnow
@ -171,9 +169,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices(slaves, True)
_LOGGER.info("Added %s Sonos speakers", len(players))
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
def service_handle(service):
"""Handle for services."""
entity_ids = service.data.get('entity_id')
@ -207,36 +202,34 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
hass.services.register(
DOMAIN, SERVICE_JOIN, service_handle,
descriptions.get(SERVICE_JOIN), schema=SONOS_JOIN_SCHEMA)
schema=SONOS_JOIN_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_UNJOIN, service_handle,
descriptions.get(SERVICE_UNJOIN), schema=SONOS_SCHEMA)
schema=SONOS_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_SNAPSHOT, service_handle,
descriptions.get(SERVICE_SNAPSHOT), schema=SONOS_STATES_SCHEMA)
schema=SONOS_STATES_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_RESTORE, service_handle,
descriptions.get(SERVICE_RESTORE), schema=SONOS_STATES_SCHEMA)
schema=SONOS_STATES_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_SET_TIMER, service_handle,
descriptions.get(SERVICE_SET_TIMER), schema=SONOS_SET_TIMER_SCHEMA)
schema=SONOS_SET_TIMER_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_CLEAR_TIMER, service_handle,
descriptions.get(SERVICE_CLEAR_TIMER), schema=SONOS_SCHEMA)
schema=SONOS_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_UPDATE_ALARM, service_handle,
descriptions.get(SERVICE_UPDATE_ALARM),
schema=SONOS_UPDATE_ALARM_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_SET_OPTION, service_handle,
descriptions.get(SERVICE_SET_OPTION),
schema=SONOS_SET_OPTION_SCHEMA)

View File

@ -6,7 +6,6 @@ https://home-assistant.io/components/media_player.soundtouch/
"""
import logging
from os import path
import re
import voluptuous as vol
@ -16,7 +15,6 @@ from homeassistant.components.media_player import (
SUPPORT_TURN_OFF, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP,
SUPPORT_VOLUME_SET, SUPPORT_TURN_ON, SUPPORT_PLAY, MediaPlayerDevice,
PLATFORM_SCHEMA)
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (CONF_HOST, CONF_NAME, STATE_OFF, CONF_PORT,
STATE_PAUSED, STATE_PLAYING,
STATE_UNAVAILABLE)
@ -107,9 +105,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
hass.data[DATA_SOUNDTOUCH].append(soundtouch_device)
add_devices([soundtouch_device])
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
def service_handle(service):
"""Handle the applying of a service."""
master_device_id = service.data.get('master')
@ -140,19 +135,15 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
hass.services.register(DOMAIN, SERVICE_PLAY_EVERYWHERE,
service_handle,
descriptions.get(SERVICE_PLAY_EVERYWHERE),
schema=SOUNDTOUCH_PLAY_EVERYWHERE)
hass.services.register(DOMAIN, SERVICE_CREATE_ZONE,
service_handle,
descriptions.get(SERVICE_CREATE_ZONE),
schema=SOUNDTOUCH_CREATE_ZONE_SCHEMA)
hass.services.register(DOMAIN, SERVICE_REMOVE_ZONE_SLAVE,
service_handle,
descriptions.get(SERVICE_REMOVE_ZONE_SLAVE),
schema=SOUNDTOUCH_REMOVE_ZONE_SCHEMA)
hass.services.register(DOMAIN, SERVICE_ADD_ZONE_SLAVE,
service_handle,
descriptions.get(SERVICE_ADD_ZONE_SLAVE),
schema=SOUNDTOUCH_ADD_ZONE_SCHEMA)

View File

@ -7,7 +7,6 @@ https://home-assistant.io/components/microsoft_face/
import asyncio
import json
import logging
import os
import aiohttp
from aiohttp.hdrs import CONTENT_TYPE
@ -15,7 +14,6 @@ import async_timeout
import voluptuous as vol
from homeassistant.const import CONF_API_KEY, CONF_TIMEOUT
from homeassistant.config import load_yaml_config_file
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
@ -133,10 +131,6 @@ def async_setup(hass, config):
hass.data[DATA_MICROSOFT_FACE] = face
descriptions = yield from hass.async_add_job(
load_yaml_config_file,
os.path.join(os.path.dirname(__file__), 'services.yaml'))
@asyncio.coroutine
def async_create_group(service):
"""Create a new person group."""
@ -155,7 +149,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_CREATE_GROUP, async_create_group,
descriptions[DOMAIN].get(SERVICE_CREATE_GROUP),
schema=SCHEMA_GROUP_SERVICE)
@asyncio.coroutine
@ -174,7 +167,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_DELETE_GROUP, async_delete_group,
descriptions[DOMAIN].get(SERVICE_DELETE_GROUP),
schema=SCHEMA_GROUP_SERVICE)
@asyncio.coroutine
@ -190,7 +182,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_TRAIN_GROUP, async_train_group,
descriptions[DOMAIN].get(SERVICE_TRAIN_GROUP),
schema=SCHEMA_TRAIN_SERVICE)
@asyncio.coroutine
@ -211,7 +202,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_CREATE_PERSON, async_create_person,
descriptions[DOMAIN].get(SERVICE_CREATE_PERSON),
schema=SCHEMA_PERSON_SERVICE)
@asyncio.coroutine
@ -232,7 +222,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_DELETE_PERSON, async_delete_person,
descriptions[DOMAIN].get(SERVICE_DELETE_PERSON),
schema=SCHEMA_PERSON_SERVICE)
@asyncio.coroutine
@ -259,7 +248,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_FACE_PERSON, async_face_person,
descriptions[DOMAIN].get(SERVICE_FACE_PERSON),
schema=SCHEMA_FACE_SERVICE)
return True

View File

@ -6,12 +6,10 @@ https://home-assistant.io/components/modbus/
"""
import logging
import threading
import os
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP,
CONF_HOST, CONF_METHOD, CONF_PORT, CONF_TYPE, CONF_TIMEOUT, ATTR_STATE)
@ -124,17 +122,12 @@ def setup(hass, config):
HUB.connect()
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_modbus)
descriptions = load_yaml_config_file(os.path.join(
os.path.dirname(__file__), 'services.yaml')).get(DOMAIN)
# Register services for modbus
hass.services.register(
DOMAIN, SERVICE_WRITE_REGISTER, write_register,
descriptions.get(SERVICE_WRITE_REGISTER),
schema=SERVICE_WRITE_REGISTER_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_WRITE_COIL, write_coil,
descriptions.get(SERVICE_WRITE_COIL),
schema=SERVICE_WRITE_COIL_SCHEMA)
def write_register(service):

View File

@ -17,7 +17,6 @@ import voluptuous as vol
from homeassistant.core import callback
from homeassistant.setup import async_prepare_setup_platform
from homeassistant.config import load_yaml_config_file
from homeassistant.exceptions import HomeAssistantError
from homeassistant.loader import bind_hass
from homeassistant.helpers import template, config_validation as cv
@ -423,13 +422,9 @@ def async_setup(hass, config):
yield from hass.data[DATA_MQTT].async_publish(
msg_topic, payload, qos, retain)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_PUBLISH, async_publish_service,
descriptions.get(SERVICE_PUBLISH), schema=MQTT_PUBLISH_SCHEMA)
schema=MQTT_PUBLISH_SCHEMA)
if conf.get(CONF_DISCOVERY):
yield from _async_setup_discovery(hass, config)

View File

@ -6,7 +6,6 @@ https://home-assistant.io/components/notify/
"""
import asyncio
import logging
import os
from functools import partial
import voluptuous as vol
@ -15,7 +14,6 @@ from homeassistant.setup import async_prepare_setup_platform
from homeassistant.exceptions import HomeAssistantError
from homeassistant.loader import bind_hass
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.const import CONF_NAME, CONF_PLATFORM
from homeassistant.helpers import config_per_platform, discovery
from homeassistant.util import slugify
@ -71,10 +69,6 @@ def send_message(hass, message, title=None, data=None):
@asyncio.coroutine
def async_setup(hass, config):
"""Set up the notify services."""
descriptions = yield from hass.async_add_job(
load_yaml_config_file,
os.path.join(os.path.dirname(__file__), 'services.yaml'))
targets = {}
@asyncio.coroutine
@ -151,7 +145,6 @@ def async_setup(hass, config):
targets[target_name] = target
hass.services.async_register(
DOMAIN, target_name, async_notify_message,
descriptions.get(SERVICE_NOTIFY),
schema=NOTIFY_SERVICE_SCHEMA)
platform_name = (
@ -161,7 +154,7 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, platform_name_slug, async_notify_message,
descriptions.get(SERVICE_NOTIFY), schema=NOTIFY_SERVICE_SCHEMA)
schema=NOTIFY_SERVICE_SCHEMA)
return True

View File

@ -45,9 +45,6 @@ REGISTER_SERVICE_SCHEMA = vol.Schema({
def get_service(hass, config, discovery_info=None):
"""Return push service."""
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
name = config.get(CONF_NAME)
cert_file = config.get(CONF_CERTFILE)
topic = config.get(CONF_TOPIC)
@ -56,7 +53,7 @@ def get_service(hass, config, discovery_info=None):
service = ApnsNotificationService(hass, name, topic, sandbox, cert_file)
hass.services.register(
DOMAIN, 'apns_{}'.format(name), service.register,
descriptions.get(SERVICE_REGISTER), schema=REGISTER_SERVICE_SCHEMA)
schema=REGISTER_SERVICE_SCHEMA)
return service

View File

@ -5,7 +5,6 @@ For more details about this component, please refer to the documentation at
https://home-assistant.io/components/persistent_notification/
"""
import asyncio
import os
import logging
import voluptuous as vol
@ -16,7 +15,6 @@ from homeassistant.loader import bind_hass
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.util import slugify
from homeassistant.config import load_yaml_config_file
ATTR_MESSAGE = 'message'
ATTR_NOTIFICATION_ID = 'notification_id'
@ -127,17 +125,10 @@ def async_setup(hass, config):
hass.states.async_remove(entity_id)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml')
)
hass.services.async_register(DOMAIN, SERVICE_CREATE, create_service,
descriptions[SERVICE_CREATE],
SCHEMA_SERVICE_CREATE)
hass.services.async_register(DOMAIN, SERVICE_DISMISS, dismiss_service,
descriptions[SERVICE_DISMISS],
SCHEMA_SERVICE_DISMISS)
return True

View File

@ -10,7 +10,6 @@ https://home-assistant.io/components/recorder/
import asyncio
import concurrent.futures
import logging
from os import path
import queue
import threading
import time
@ -30,7 +29,6 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entityfilter import generate_filter
from homeassistant.helpers.typing import ConfigType
import homeassistant.util.dt as dt_util
from homeassistant import config as conf_util
from . import purge, migration
from .const import DATA_INSTANCE
@ -142,13 +140,8 @@ def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Handle calls to the purge service."""
instance.do_adhoc_purge(service.data[ATTR_KEEP_DAYS])
descriptions = yield from hass.async_add_job(
conf_util.load_yaml_config_file, path.join(
path.dirname(__file__), 'services.yaml'))
hass.services.async_register(DOMAIN, SERVICE_PURGE,
async_handle_purge_service,
descriptions.get(SERVICE_PURGE),
schema=SERVICE_PURGE_SCHEMA)
return (yield from instance.async_db_ready)

View File

@ -14,7 +14,6 @@ import os
import json
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (CONF_API_KEY, STATE_OK, CONF_TOKEN,
CONF_NAME, CONF_ID)
import homeassistant.helpers.config_validation as cv
@ -66,9 +65,6 @@ def setup(hass, config):
component = EntityComponent(_LOGGER, DOMAIN, hass,
group_name=GROUP_NAME_RTM)
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
stored_rtm_config = RememberTheMilkConfiguration(hass)
for rtm_config in config[DOMAIN]:
account_name = rtm_config[CONF_NAME]
@ -80,33 +76,31 @@ def setup(hass, config):
_LOGGER.debug("found token for account %s", account_name)
_create_instance(
hass, account_name, api_key, shared_secret, token,
stored_rtm_config, component, descriptions)
stored_rtm_config, component)
else:
_register_new_account(
hass, account_name, api_key, shared_secret,
stored_rtm_config, component, descriptions)
stored_rtm_config, component)
_LOGGER.debug("Finished adding all Remember the milk accounts")
return True
def _create_instance(hass, account_name, api_key, shared_secret,
token, stored_rtm_config, component, descriptions):
token, stored_rtm_config, component):
entity = RememberTheMilk(account_name, api_key, shared_secret,
token, stored_rtm_config)
component.add_entity(entity)
hass.services.register(
DOMAIN, '{}_create_task'.format(account_name), entity.create_task,
description=descriptions.get(SERVICE_CREATE_TASK),
schema=SERVICE_SCHEMA_CREATE_TASK)
hass.services.register(
DOMAIN, '{}_complete_task'.format(account_name), entity.complete_task,
description=descriptions.get(SERVICE_COMPLETE_TASK),
schema=SERVICE_SCHEMA_COMPLETE_TASK)
def _register_new_account(hass, account_name, api_key, shared_secret,
stored_rtm_config, component, descriptions):
stored_rtm_config, component):
from rtmapi import Rtm
request_id = None
@ -131,7 +125,7 @@ def _register_new_account(hass, account_name, api_key, shared_secret,
_create_instance(
hass, account_name, api_key, shared_secret, token,
stored_rtm_config, component, descriptions)
stored_rtm_config, component)
configurator.request_done(request_id)

View File

@ -8,11 +8,9 @@ import asyncio
from datetime import timedelta
import functools as ft
import logging
import os
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
from homeassistant.loader import bind_hass
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.entity import ToggleEntity
@ -160,24 +158,17 @@ def async_setup(hass, config):
if update_tasks:
yield from asyncio.wait(update_tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_TURN_OFF, async_handle_remote_service,
descriptions.get(SERVICE_TURN_OFF),
schema=REMOTE_SERVICE_ACTIVITY_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TURN_ON, async_handle_remote_service,
descriptions.get(SERVICE_TURN_ON),
schema=REMOTE_SERVICE_ACTIVITY_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TOGGLE, async_handle_remote_service,
descriptions.get(SERVICE_TOGGLE),
schema=REMOTE_SERVICE_ACTIVITY_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_SEND_COMMAND, async_handle_remote_service,
descriptions.get(SERVICE_SEND_COMMAND),
schema=REMOTE_SERVICE_SEND_COMMAND_SCHEMA)
return True

View File

@ -6,7 +6,6 @@ https://home-assistant.io/components/remote.harmony/
"""
import logging
import asyncio
from os import path
import time
import voluptuous as vol
@ -19,7 +18,6 @@ from homeassistant.components.remote import (
PLATFORM_SCHEMA, DOMAIN, ATTR_DEVICE, ATTR_ACTIVITY, ATTR_NUM_REPEATS,
ATTR_DELAY_SECS, DEFAULT_DELAY_SECS)
from homeassistant.util import slugify
from homeassistant.config import load_yaml_config_file
REQUIREMENTS = ['pyharmony==1.0.18']
@ -105,11 +103,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
def register_services(hass):
"""Register all services for harmony devices."""
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
hass.services.register(
DOMAIN, SERVICE_SYNC, _sync_service, descriptions.get(SERVICE_SYNC),
DOMAIN, SERVICE_SYNC, _sync_service,
schema=HARMONY_SYNC_SCHEMA)

View File

@ -8,11 +8,9 @@ import asyncio
from collections import defaultdict
import functools as ft
import logging
import os
import async_timeout
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_COMMAND, CONF_HOST, CONF_PORT,
EVENT_HOMEASSISTANT_STOP, STATE_UNKNOWN)
@ -132,14 +130,9 @@ def async_setup(hass, config):
call.data.get(CONF_COMMAND))):
_LOGGER.error('Failed Rflink command for %s', str(call.data))
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml')
)
hass.services.async_register(
DOMAIN, SERVICE_SEND_COMMAND, async_send_command,
descriptions[DOMAIN][SERVICE_SEND_COMMAND], SEND_COMMAND_SCHEMA)
schema=SEND_COMMAND_SCHEMA)
@callback
def event_callback(event):

View File

@ -0,0 +1,8 @@
# Describes the format for available scene services
turn_on:
description: Activate a scene.
fields:
entity_id:
description: Name(s) of scenes to turn on
example: 'scene.romantic'

View File

@ -7,12 +7,10 @@ at https://home-assistant.io/components/switch/
import asyncio
from datetime import timedelta
import logging
import os
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.config import load_yaml_config_file
from homeassistant.loader import bind_hass
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.entity import ToggleEntity
@ -123,19 +121,15 @@ def async_setup(hass, config):
if update_tasks:
yield from asyncio.wait(update_tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_TURN_OFF, async_handle_switch_service,
descriptions.get(SERVICE_TURN_OFF), schema=SWITCH_SERVICE_SCHEMA)
schema=SWITCH_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TURN_ON, async_handle_switch_service,
descriptions.get(SERVICE_TURN_ON), schema=SWITCH_SERVICE_SCHEMA)
schema=SWITCH_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_TOGGLE, async_handle_switch_service,
descriptions.get(SERVICE_TOGGLE), schema=SWITCH_SERVICE_SCHEMA)
schema=SWITCH_SERVICE_SCHEMA)
return True

View File

@ -4,14 +4,11 @@ Support for MySensors switches.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/switch.mysensors/
"""
import os
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.components import mysensors
from homeassistant.components.switch import DOMAIN, SwitchDevice
from homeassistant.config import load_yaml_config_file
from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON
ATTR_IR_CODE = 'V_IR_SEND'
@ -62,12 +59,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
for device in _devices:
device.turn_on(**kwargs)
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
hass.services.register(DOMAIN, SERVICE_SEND_IR_CODE,
send_ir_code_service,
descriptions.get(SERVICE_SEND_IR_CODE),
schema=SEND_IR_CODE_SERVICE_SCHEMA)

View File

@ -4,7 +4,6 @@ Support for system log.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/system_log/
"""
import os
import re
import asyncio
import logging
@ -15,7 +14,6 @@ from collections import deque
import voluptuous as vol
from homeassistant import __path__ as HOMEASSISTANT_PATH
from homeassistant.config import load_yaml_config_file
import homeassistant.helpers.config_validation as cv
from homeassistant.components.http import HomeAssistantView
@ -84,13 +82,8 @@ def async_setup(hass, config):
# Only one service so far
handler.records.clear()
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_CLEAR, async_service_handler,
descriptions[DOMAIN].get(SERVICE_CLEAR),
schema=SERVICE_CLEAR_SCHEMA)
return True

View File

@ -8,7 +8,6 @@ import asyncio
import io
from functools import partial
import logging
import os
import requests
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
@ -16,7 +15,6 @@ import voluptuous as vol
from homeassistant.components.notify import (
ATTR_DATA, ATTR_MESSAGE, ATTR_TITLE)
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
ATTR_COMMAND, ATTR_LATITUDE, ATTR_LONGITUDE, CONF_API_KEY,
CONF_PLATFORM, CONF_TIMEOUT, HTTP_DIGEST_AUTHENTICATION)
@ -216,9 +214,6 @@ def async_setup(hass, config):
return False
p_config = config[DOMAIN][0]
descriptions = yield from hass.async_add_job(
load_yaml_config_file,
os.path.join(os.path.dirname(__file__), 'services.yaml'))
p_type = p_config.get(CONF_PLATFORM)
@ -301,7 +296,7 @@ def async_setup(hass, config):
for service_notif, schema in SERVICE_MAP.items():
hass.services.async_register(
DOMAIN, service_notif, async_send_telegram_message,
descriptions.get(service_notif), schema=schema)
schema=schema)
return True

View File

@ -6,14 +6,12 @@ at https://home-assistant.io/components/timer/
"""
import asyncio
import logging
import os
from datetime import timedelta
import voluptuous as vol
import homeassistant.util.dt as dt_util
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (ATTR_ENTITY_ID, CONF_ICON, CONF_NAME)
from homeassistant.core import callback
from homeassistant.helpers.entity import Entity
@ -166,23 +164,18 @@ def async_setup(hass, config):
if tasks:
yield from asyncio.wait(tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file,
os.path.join(os.path.dirname(__file__), 'services.yaml')
)
hass.services.async_register(
DOMAIN, SERVICE_START, async_handler_service,
descriptions[SERVICE_START], SERVICE_SCHEMA_DURATION)
schema=SERVICE_SCHEMA_DURATION)
hass.services.async_register(
DOMAIN, SERVICE_PAUSE, async_handler_service,
descriptions[SERVICE_PAUSE], SERVICE_SCHEMA)
schema=SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_CANCEL, async_handler_service,
descriptions[SERVICE_CANCEL], SERVICE_SCHEMA)
schema=SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_FINISH, async_handler_service,
descriptions[SERVICE_FINISH], SERVICE_SCHEMA)
schema=SERVICE_SCHEMA)
yield from component.async_add_entities(entities)
return True

View File

@ -22,7 +22,6 @@ from homeassistant.components.media_player import (
ATTR_MEDIA_CONTENT_ID, ATTR_MEDIA_CONTENT_TYPE, MEDIA_TYPE_MUSIC,
SERVICE_PLAY_MEDIA)
from homeassistant.components.media_player import DOMAIN as DOMAIN_MP
from homeassistant.config import load_yaml_config_file
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
@ -96,10 +95,6 @@ def async_setup(hass, config):
hass.http.register_view(TextToSpeechView(tts))
descriptions = yield from hass.async_add_job(
load_yaml_config_file,
os.path.join(os.path.dirname(__file__), 'services.yaml'))
@asyncio.coroutine
def async_setup_platform(p_type, p_config, disc_info=None):
"""Set up a TTS platform."""
@ -156,7 +151,7 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, "{}_{}".format(p_type, SERVICE_SAY), async_say_handle,
descriptions.get(SERVICE_SAY), schema=SCHEMA_SERVICE_SAY)
schema=SCHEMA_SERVICE_SAY)
setup_tasks = [async_setup_platform(p_type, p_config) for p_type, p_config
in config_per_platform(config, DOMAIN)]
@ -171,7 +166,6 @@ def async_setup(hass, config):
hass.services.async_register(
DOMAIN, SERVICE_CLEAR_CACHE, async_clear_cache_handle,
descriptions.get(SERVICE_CLEAR_CACHE),
schema=SCHEMA_SERVICE_CLEAR_CACHE)
return True

View File

@ -8,12 +8,10 @@ import asyncio
from datetime import timedelta
from functools import partial
import logging
import os
import voluptuous as vol
from homeassistant.components import group
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
ATTR_BATTERY_LEVEL, ATTR_COMMAND, ATTR_ENTITY_ID, SERVICE_TOGGLE,
SERVICE_TURN_OFF, SERVICE_TURN_ON, STATE_ON)
@ -183,10 +181,6 @@ def async_setup(hass, config):
yield from component.async_setup(config)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
@asyncio.coroutine
def async_handle_vacuum_service(service):
"""Map services to methods on VacuumDevice."""
@ -210,7 +204,7 @@ def async_setup(hass, config):
'schema', VACUUM_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, service, async_handle_vacuum_service,
descriptions.get(service), schema=schema)
schema=schema)
return True

View File

@ -7,7 +7,6 @@ https://home-assistant.io/components/vacuum.xiaomi_miio/
import asyncio
from functools import partial
import logging
import os
import voluptuous as vol
@ -16,7 +15,6 @@ from homeassistant.components.vacuum import (
SUPPORT_CLEAN_SPOT, SUPPORT_FAN_SPEED, SUPPORT_LOCATE, SUPPORT_PAUSE,
SUPPORT_RETURN_HOME, SUPPORT_SEND_COMMAND, SUPPORT_STATUS, SUPPORT_STOP,
SUPPORT_TURN_OFF, SUPPORT_TURN_ON, VACUUM_SERVICE_SCHEMA, VacuumDevice)
from homeassistant.config import load_yaml_config_file
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_HOST, CONF_NAME, CONF_TOKEN, STATE_OFF, STATE_ON)
import homeassistant.helpers.config_validation as cv
@ -130,16 +128,12 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
if update_tasks:
yield from asyncio.wait(update_tasks, loop=hass.loop)
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
for vacuum_service in SERVICE_TO_METHOD:
schema = SERVICE_TO_METHOD[vacuum_service].get(
'schema', VACUUM_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, vacuum_service, async_service_handler,
description=descriptions.get(vacuum_service), schema=schema)
schema=schema)
class MiroboVacuum(VacuumDevice):

View File

@ -6,7 +6,6 @@ https://home-assistant.io/components/verisure/
"""
import logging
import threading
import os.path
from datetime import timedelta
import voluptuous as vol
@ -15,7 +14,6 @@ from homeassistant.const import (CONF_PASSWORD, CONF_USERNAME,
EVENT_HOMEASSISTANT_STOP)
from homeassistant.helpers import discovery
from homeassistant.util import Throttle
import homeassistant.config as conf_util
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['vsure==1.3.7', 'jsonpath==0.75']
@ -78,9 +76,6 @@ def setup(hass, config):
'camera', 'binary_sensor'):
discovery.load_platform(hass, component, DOMAIN, {}, config)
descriptions = conf_util.load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
def capture_smartcam(service):
"""Capture a new picture from a smartcam."""
device_id = service.data.get(ATTR_DEVICE_SERIAL)
@ -89,7 +84,6 @@ def setup(hass, config):
hass.services.register(DOMAIN, SERVICE_CAPTURE_SMARTCAM,
capture_smartcam,
descriptions[DOMAIN][SERVICE_CAPTURE_SMARTCAM],
schema=CAPTURE_IMAGE_SCHEMA)
return True

View File

@ -7,11 +7,9 @@ https://home-assistant.io/components/wake_on_lan/
import asyncio
from functools import partial
import logging
import os
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
from homeassistant.const import CONF_MAC
import homeassistant.helpers.config_validation as cv
@ -50,13 +48,8 @@ def async_setup(hass, config):
yield from hass.async_add_job(
partial(wol.send_magic_packet, mac_address))
descriptions = yield from hass.async_add_job(
load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_SEND_MAGIC_PACKET, send_magic_packet,
description=descriptions.get(DOMAIN).get(SERVICE_SEND_MAGIC_PACKET),
schema=WAKE_ON_LAN_SEND_MAGIC_PACKET_SCHEMA)
return True

View File

@ -21,6 +21,7 @@ from homeassistant.components import frontend
from homeassistant.core import callback
from homeassistant.remote import JSONEncoder
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.service import async_get_all_descriptions
from homeassistant.components.http import HomeAssistantView
from homeassistant.components.http.auth import validate_password
from homeassistant.components.http.const import KEY_AUTHENTICATED
@ -436,7 +437,7 @@ class ActiveConnection:
def handle_call_service(self, msg):
"""Handle call service command.
This is a coroutine.
Async friendly.
"""
msg = CALL_SERVICE_MESSAGE_SCHEMA(msg)
@ -466,8 +467,13 @@ class ActiveConnection:
"""
msg = GET_SERVICES_MESSAGE_SCHEMA(msg)
self.to_write.put_nowait(result_message(
msg['id'], self.hass.services.async_services()))
@asyncio.coroutine
def get_services_helper(msg):
"""Get available services and fire complete message."""
descriptions = yield from async_get_all_descriptions(self.hass)
self.send_message_outside(result_message(msg['id'], descriptions))
self.hass.async_add_job(get_services_helper(msg))
def handle_get_config(self, msg):
"""Handle get config command.

View File

@ -25,7 +25,6 @@ from homeassistant.const import (
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent
import homeassistant.helpers.config_validation as cv
from homeassistant.config import load_yaml_config_file
from homeassistant.util.json import load_json, save_json
REQUIREMENTS = ['python-wink==1.7.1', 'pubnubsub-handler==1.0.2']
@ -232,9 +231,6 @@ def setup(hass, config):
import pywink
from pubnubsubhandler import PubNubSubscriptionHandler
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
if hass.data.get(DOMAIN) is None:
hass.data[DOMAIN] = {
'unique_ids': [],
@ -374,8 +370,7 @@ def setup(hass, config):
time.sleep(1)
entity.schedule_update_ha_state(True)
hass.services.register(DOMAIN, SERVICE_REFRESH_STATES, force_update,
descriptions.get(SERVICE_REFRESH_STATES))
hass.services.register(DOMAIN, SERVICE_REFRESH_STATES, force_update)
def pull_new_devices(call):
"""Pull new devices added to users Wink account since startup."""
@ -383,8 +378,7 @@ def setup(hass, config):
for _component in WINK_COMPONENTS:
discovery.load_platform(hass, _component, DOMAIN, {}, config)
hass.services.register(DOMAIN, SERVICE_ADD_NEW_DEVICES, pull_new_devices,
descriptions.get(SERVICE_ADD_NEW_DEVICES))
hass.services.register(DOMAIN, SERVICE_ADD_NEW_DEVICES, pull_new_devices)
def set_pairing_mode(call):
"""Put the hub in provided pairing mode."""
@ -412,7 +406,6 @@ def setup(hass, config):
found_device.wink.set_name(name)
hass.services.register(DOMAIN, SERVICE_RENAME_DEVICE, rename_device,
descriptions.get(SERVICE_RENAME_DEVICE),
schema=RENAME_DEVICE_SCHEMA)
def delete_device(call):
@ -430,7 +423,6 @@ def setup(hass, config):
found_device.wink.remove_device()
hass.services.register(DOMAIN, SERVICE_DELETE_DEVICE, delete_device,
descriptions.get(SERVICE_DELETE_DEVICE),
schema=DELETE_DEVICE_SCHEMA)
hubs = pywink.get_hubs()
@ -441,7 +433,6 @@ def setup(hass, config):
if WINK_HUBS:
hass.services.register(
DOMAIN, SERVICE_SET_PAIRING_MODE, set_pairing_mode,
descriptions.get(SERVICE_SET_PAIRING_MODE),
schema=SET_PAIRING_MODE_SCHEMA)
def service_handle(service):
@ -508,44 +499,36 @@ def setup(hass, config):
hass.services.register(DOMAIN, SERVICE_SET_AUTO_SHUTOFF,
service_handle,
descriptions.get(SERVICE_SET_AUTO_SHUTOFF),
schema=SET_AUTO_SHUTOFF_SCHEMA)
hass.services.register(DOMAIN, SERVICE_ENABLE_SIREN,
service_handle,
descriptions.get(SERVICE_ENABLE_SIREN),
schema=ENABLED_SIREN_SCHEMA)
if has_dome_or_wink_siren:
hass.services.register(DOMAIN, SERVICE_SET_SIREN_TONE,
service_handle,
descriptions.get(SERVICE_SET_SIREN_TONE),
schema=SET_SIREN_TONE_SCHEMA)
hass.services.register(DOMAIN, SERVICE_ENABLE_CHIME,
service_handle,
descriptions.get(SERVICE_ENABLE_CHIME),
schema=SET_CHIME_MODE_SCHEMA)
hass.services.register(DOMAIN, SERVICE_SET_SIREN_VOLUME,
service_handle,
descriptions.get(SERVICE_SET_SIREN_VOLUME),
schema=SET_VOLUME_SCHEMA)
hass.services.register(DOMAIN, SERVICE_SET_CHIME_VOLUME,
service_handle,
descriptions.get(SERVICE_SET_CHIME_VOLUME),
schema=SET_VOLUME_SCHEMA)
hass.services.register(DOMAIN, SERVICE_SIREN_STROBE_ENABLED,
service_handle,
descriptions.get(SERVICE_SIREN_STROBE_ENABLED),
schema=SET_STROBE_ENABLED_SCHEMA)
hass.services.register(DOMAIN, SERVICE_CHIME_STROBE_ENABLED,
service_handle,
descriptions.get(SERVICE_CHIME_STROBE_ENABLED),
schema=SET_STROBE_ENABLED_SCHEMA)
component.add_entities(sirens)

View File

@ -41,17 +41,6 @@ CONFIG_SCHEMA = vol.Schema({
ATTR_DURATION = 'duration'
SERVICE_PERMIT = 'permit'
SERVICE_DESCRIPTIONS = {
SERVICE_PERMIT: {
"description": "Allow nodes to join the ZigBee network",
"fields": {
ATTR_DURATION: {
"description": "Time to permit joins, in seconds",
"example": "60",
},
},
},
}
SERVICE_SCHEMAS = {
SERVICE_PERMIT: vol.Schema({
vol.Optional(ATTR_DURATION, default=60):
@ -103,8 +92,7 @@ def async_setup(hass, config):
yield from APPLICATION_CONTROLLER.permit(duration)
hass.services.async_register(DOMAIN, SERVICE_PERMIT, permit,
SERVICE_DESCRIPTIONS[SERVICE_PERMIT],
SERVICE_SCHEMAS[SERVICE_PERMIT])
schema=SERVICE_SCHEMAS[SERVICE_PERMIT])
return True

View File

@ -0,0 +1,8 @@
# Describes the format for available zha services
permit:
description: Allow nodes to join the ZigBee network.
fields:
duration:
description: Time to permit joins, in seconds
example: 60

View File

@ -7,7 +7,6 @@ https://home-assistant.io/components/zwave/
import asyncio
import copy
import logging
import os.path
import time
from pprint import pprint
@ -23,7 +22,6 @@ from homeassistant.const import (
from homeassistant.helpers.entity_values import EntityValues
from homeassistant.helpers.event import track_time_change
from homeassistant.util import convert, slugify
import homeassistant.config as conf_util
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import (
async_dispatcher_connect, async_dispatcher_send)
@ -249,9 +247,6 @@ def setup(hass, config):
Will automatically load components to support devices found on the network.
"""
descriptions = conf_util.load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
from pydispatch import dispatcher
# pylint: disable=import-error
from openzwave.option import ZWaveOption
@ -627,99 +622,65 @@ def setup(hass, config):
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_network)
# Register node services for Z-Wave network
hass.services.register(DOMAIN, const.SERVICE_ADD_NODE, add_node,
descriptions[const.SERVICE_ADD_NODE])
hass.services.register(DOMAIN, const.SERVICE_ADD_NODE, add_node)
hass.services.register(DOMAIN, const.SERVICE_ADD_NODE_SECURE,
add_node_secure,
descriptions[const.SERVICE_ADD_NODE_SECURE])
hass.services.register(DOMAIN, const.SERVICE_REMOVE_NODE, remove_node,
descriptions[const.SERVICE_REMOVE_NODE])
add_node_secure)
hass.services.register(DOMAIN, const.SERVICE_REMOVE_NODE, remove_node)
hass.services.register(DOMAIN, const.SERVICE_CANCEL_COMMAND,
cancel_command,
descriptions[const.SERVICE_CANCEL_COMMAND])
cancel_command)
hass.services.register(DOMAIN, const.SERVICE_HEAL_NETWORK,
heal_network,
descriptions[const.SERVICE_HEAL_NETWORK])
hass.services.register(DOMAIN, const.SERVICE_SOFT_RESET, soft_reset,
descriptions[const.SERVICE_SOFT_RESET])
heal_network)
hass.services.register(DOMAIN, const.SERVICE_SOFT_RESET, soft_reset)
hass.services.register(DOMAIN, const.SERVICE_TEST_NETWORK,
test_network,
descriptions[const.SERVICE_TEST_NETWORK])
test_network)
hass.services.register(DOMAIN, const.SERVICE_STOP_NETWORK,
stop_network,
descriptions[const.SERVICE_STOP_NETWORK])
stop_network)
hass.services.register(DOMAIN, const.SERVICE_START_NETWORK,
start_zwave,
descriptions[const.SERVICE_START_NETWORK])
start_zwave)
hass.services.register(DOMAIN, const.SERVICE_RENAME_NODE, rename_node,
descriptions[const.SERVICE_RENAME_NODE],
schema=RENAME_NODE_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_RENAME_VALUE,
rename_value,
descriptions[const.SERVICE_RENAME_VALUE],
schema=RENAME_VALUE_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_SET_CONFIG_PARAMETER,
set_config_parameter,
descriptions[
const.SERVICE_SET_CONFIG_PARAMETER],
schema=SET_CONFIG_PARAMETER_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_PRINT_CONFIG_PARAMETER,
print_config_parameter,
descriptions[
const.SERVICE_PRINT_CONFIG_PARAMETER],
schema=PRINT_CONFIG_PARAMETER_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_REMOVE_FAILED_NODE,
remove_failed_node,
descriptions[const.SERVICE_REMOVE_FAILED_NODE],
schema=NODE_SERVICE_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_REPLACE_FAILED_NODE,
replace_failed_node,
descriptions[const.SERVICE_REPLACE_FAILED_NODE],
schema=NODE_SERVICE_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_CHANGE_ASSOCIATION,
change_association,
descriptions[
const.SERVICE_CHANGE_ASSOCIATION],
schema=CHANGE_ASSOCIATION_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_SET_WAKEUP,
set_wakeup,
descriptions[
const.SERVICE_SET_WAKEUP],
schema=SET_WAKEUP_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_PRINT_NODE,
print_node,
descriptions[
const.SERVICE_PRINT_NODE],
schema=NODE_SERVICE_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_REFRESH_ENTITY,
async_refresh_entity,
descriptions[
const.SERVICE_REFRESH_ENTITY],
schema=REFRESH_ENTITY_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_REFRESH_NODE,
refresh_node,
descriptions[
const.SERVICE_REFRESH_NODE],
schema=NODE_SERVICE_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_RESET_NODE_METERS,
reset_node_meters,
descriptions[
const.SERVICE_RESET_NODE_METERS],
schema=RESET_NODE_METERS_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_SET_POLL_INTENSITY,
set_poll_intensity,
descriptions[const.SERVICE_SET_POLL_INTENSITY],
schema=SET_POLL_INTENSITY_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_HEAL_NODE,
heal_node,
descriptions[
const.SERVICE_HEAL_NODE],
schema=HEAL_NODE_SCHEMA)
hass.services.register(DOMAIN, const.SERVICE_TEST_NODE,
test_node,
descriptions[
const.SERVICE_TEST_NODE],
schema=TEST_NODE_SCHEMA)
# Setup autoheal

View File

@ -754,25 +754,15 @@ class StateMachine(object):
class Service(object):
"""Representation of a callable service."""
__slots__ = ['func', 'description', 'fields', 'schema',
'is_callback', 'is_coroutinefunction']
__slots__ = ['func', 'schema', 'is_callback', 'is_coroutinefunction']
def __init__(self, func, description, fields, schema):
def __init__(self, func, schema):
"""Initialize a service."""
self.func = func
self.description = description or ''
self.fields = fields or {}
self.schema = schema
self.is_callback = is_callback(func)
self.is_coroutinefunction = asyncio.iscoroutinefunction(func)
def as_dict(self):
"""Return dictionary representation of this service."""
return {
'description': self.description,
'fields': self.fields,
}
class ServiceCall(object):
"""Representation of a call to a service."""
@ -826,8 +816,7 @@ class ServiceRegistry(object):
This method must be run in the event loop.
"""
return {domain: {key: value.as_dict() for key, value
in self._services[domain].items()}
return {domain: self._services[domain].copy()
for domain in self._services}
def has_service(self, domain, service):
@ -837,40 +826,29 @@ class ServiceRegistry(object):
"""
return service.lower() in self._services.get(domain.lower(), [])
def register(self, domain, service, service_func, description=None,
schema=None):
def register(self, domain, service, service_func, schema=None):
"""
Register a service.
Description is a dict containing key 'description' to describe
the service and a key 'fields' to describe the fields.
Schema is called to coerce and validate the service data.
"""
run_callback_threadsafe(
self._hass.loop,
self.async_register, domain, service, service_func, description,
schema
self.async_register, domain, service, service_func, schema
).result()
@callback
def async_register(self, domain, service, service_func, description=None,
schema=None):
def async_register(self, domain, service, service_func, schema=None):
"""
Register a service.
Description is a dict containing key 'description' to describe
the service and a key 'fields' to describe the fields.
Schema is called to coerce and validate the service data.
This method must be run in the event loop.
"""
domain = domain.lower()
service = service.lower()
description = description or {}
service_obj = Service(service_func, description.get('description'),
description.get('fields', {}), schema)
service_obj = Service(service_func, schema)
if domain in self._services:
self._services[domain][service] = service_obj

View File

@ -3,13 +3,15 @@ import asyncio
import logging
# pylint: disable=unused-import
from typing import Optional # NOQA
from os import path
import voluptuous as vol
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant # NOQA
import homeassistant.core as ha
from homeassistant.exceptions import TemplateError
from homeassistant.loader import get_component, bind_hass
from homeassistant.util.yaml import load_yaml
import homeassistant.helpers.config_validation as cv
from homeassistant.util.async import run_coroutine_threadsafe
@ -21,6 +23,8 @@ CONF_SERVICE_DATA_TEMPLATE = 'data_template'
_LOGGER = logging.getLogger(__name__)
SERVICE_DESCRIPTION_CACHE = 'service_description_cache'
@bind_hass
def call_from_config(hass, config, blocking=False, variables=None,
@ -112,3 +116,76 @@ def extract_entity_ids(hass, service_call, expand_group=True):
return [service_ent_id]
return service_ent_id
@asyncio.coroutine
@bind_hass
def async_get_all_descriptions(hass):
"""Return descriptions (i.e. user documentation) for all service calls."""
if SERVICE_DESCRIPTION_CACHE not in hass.data:
hass.data[SERVICE_DESCRIPTION_CACHE] = {}
description_cache = hass.data[SERVICE_DESCRIPTION_CACHE]
format_cache_key = '{}.{}'.format
def domain_yaml_file(domain):
"""Return the services.yaml location for a domain."""
if domain == ha.DOMAIN:
import homeassistant.components as components
component_path = path.dirname(components.__file__)
else:
component_path = path.dirname(get_component(domain).__file__)
return path.join(component_path, 'services.yaml')
def load_services_file(yaml_file):
"""Load and cache a services.yaml file."""
try:
yaml_cache[yaml_file] = load_yaml(yaml_file)
except FileNotFoundError:
pass
services = hass.services.async_services()
# Load missing files
yaml_cache = {}
loading_tasks = []
for domain in services:
yaml_file = domain_yaml_file(domain)
for service in services[domain]:
if format_cache_key(domain, service) not in description_cache:
if yaml_file not in yaml_cache:
yaml_cache[yaml_file] = {}
task = hass.async_add_job(load_services_file, yaml_file)
loading_tasks.append(task)
if loading_tasks:
yield from asyncio.wait(loading_tasks, loop=hass.loop)
# Build response
catch_all_yaml_file = domain_yaml_file(ha.DOMAIN)
descriptions = {}
for domain in services:
descriptions[domain] = {}
yaml_file = domain_yaml_file(domain)
for service in services[domain]:
cache_key = format_cache_key(domain, service)
description = description_cache.get(cache_key)
# Cache missing descriptions
if description is None:
if yaml_file == catch_all_yaml_file:
yaml_services = yaml_cache[yaml_file].get(domain, {})
else:
yaml_services = yaml_cache[yaml_file]
yaml_description = yaml_services.get(service, {})
description = description_cache[cache_key] = {
'description': yaml_description.get('description', ''),
'fields': yaml_description.get('fields', {})
}
descriptions[domain][service] = description
return descriptions

View File

@ -345,6 +345,7 @@ class TestComponentsDeviceTracker(unittest.TestCase):
CONF_PLATFORM: 'test',
device_tracker.CONF_CONSIDER_HOME: 59,
}})
self.hass.block_till_done()
self.assertEqual(STATE_HOME,
self.hass.states.get('device_tracker.dev1').state)
@ -586,6 +587,7 @@ class TestComponentsDeviceTracker(unittest.TestCase):
CONF_PLATFORM: 'test',
device_tracker.CONF_CONSIDER_HOME: 59,
}})
self.hass.block_till_done()
state = self.hass.states.get('device_tracker.dev1')
attrs = state.attributes

View File

@ -1,4 +1,5 @@
"""Test service helpers."""
import asyncio
from copy import deepcopy
import unittest
from unittest.mock import patch
@ -8,6 +9,7 @@ import homeassistant.components # noqa
from homeassistant import core as ha, loader
from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ENTITY_ID
from homeassistant.helpers import service, template
from homeassistant.setup import async_setup_component
import homeassistant.helpers.config_validation as cv
from tests.common import get_test_home_assistant, mock_service
@ -135,3 +137,27 @@ class TestServiceHelpers(unittest.TestCase):
self.assertEqual(['group.test'], service.extract_entity_ids(
self.hass, call, expand_group=False))
@asyncio.coroutine
def test_async_get_all_descriptions(hass):
"""Test async_get_all_descriptions."""
group = loader.get_component('group')
group_config = {group.DOMAIN: {}}
yield from async_setup_component(hass, group.DOMAIN, group_config)
descriptions = yield from service.async_get_all_descriptions(hass)
assert len(descriptions) == 1
assert 'description' in descriptions['group']['reload']
assert 'fields' in descriptions['group']['reload']
logger = loader.get_component('logger')
logger_config = {logger.DOMAIN: {}}
yield from async_setup_component(hass, logger.DOMAIN, logger_config)
descriptions = yield from service.async_get_all_descriptions(hass)
assert len(descriptions) == 2
assert 'description' in descriptions[logger.DOMAIN]['set_level']
assert 'fields' in descriptions[logger.DOMAIN]['set_level']

View File

@ -640,10 +640,7 @@ class TestServiceRegistry(unittest.TestCase):
def test_services(self):
"""Test services."""
expected = {
'test_domain': {'test_service': {'description': '', 'fields': {}}}
}
self.assertEqual(expected, self.services.services)
assert len(self.services.services) == 1
def test_call_with_blocking_done_in_time(self):
"""Test call with blocking."""