From 02619ca2cd8bc4c7250eabbee28f83d123005698 Mon Sep 17 00:00:00 2001 From: Guillermo Ruffino Date: Wed, 17 Mar 2021 18:50:21 -0300 Subject: [PATCH] Add service schema for ESPHome api services (#47426) --- homeassistant/components/esphome/__init__.py | 73 +++++++++++++++++--- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/esphome/__init__.py b/homeassistant/components/esphome/__init__.py index dee0813007c..650b630e34c 100644 --- a/homeassistant/components/esphome/__init__.py +++ b/homeassistant/components/esphome/__init__.py @@ -22,6 +22,7 @@ from homeassistant.components import zeroconf from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_HOST, + CONF_MODE, CONF_PASSWORD, CONF_PORT, EVENT_HOMEASSISTANT_STOP, @@ -35,6 +36,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.json import JSONEncoder +from homeassistant.helpers.service import async_set_service_schema from homeassistant.helpers.storage import Store from homeassistant.helpers.template import Template from homeassistant.helpers.typing import ConfigType, HomeAssistantType @@ -308,17 +310,63 @@ async def _register_service( ): service_name = f"{entry_data.device_info.name}_{service.name}" schema = {} + fields = {} + for arg in service.args: - schema[vol.Required(arg.name)] = { - UserServiceArgType.BOOL: cv.boolean, - UserServiceArgType.INT: vol.Coerce(int), - UserServiceArgType.FLOAT: vol.Coerce(float), - UserServiceArgType.STRING: cv.string, - UserServiceArgType.BOOL_ARRAY: [cv.boolean], - UserServiceArgType.INT_ARRAY: [vol.Coerce(int)], - UserServiceArgType.FLOAT_ARRAY: [vol.Coerce(float)], - UserServiceArgType.STRING_ARRAY: [cv.string], + metadata = { + UserServiceArgType.BOOL: { + "validator": cv.boolean, + "example": "False", + "selector": {"boolean": None}, + }, + UserServiceArgType.INT: { + "validator": vol.Coerce(int), + "example": "42", + "selector": {"number": {CONF_MODE: "box"}}, + }, + UserServiceArgType.FLOAT: { + "validator": vol.Coerce(float), + "example": "12.3", + "selector": {"number": {CONF_MODE: "box", "step": 1e-3}}, + }, + UserServiceArgType.STRING: { + "validator": cv.string, + "example": "Example text", + "selector": {"text": None}, + }, + UserServiceArgType.BOOL_ARRAY: { + "validator": [cv.boolean], + "description": "A list of boolean values.", + "example": "[True, False]", + "selector": {"object": {}}, + }, + UserServiceArgType.INT_ARRAY: { + "validator": [vol.Coerce(int)], + "description": "A list of integer values.", + "example": "[42, 34]", + "selector": {"object": {}}, + }, + UserServiceArgType.FLOAT_ARRAY: { + "validator": [vol.Coerce(float)], + "description": "A list of floating point numbers.", + "example": "[ 12.3, 34.5 ]", + "selector": {"object": {}}, + }, + UserServiceArgType.STRING_ARRAY: { + "validator": [cv.string], + "description": "A list of strings.", + "example": "['Example text', 'Another example']", + "selector": {"object": {}}, + }, }[arg.type_] + schema[vol.Required(arg.name)] = metadata["validator"] + fields[arg.name] = { + "name": arg.name, + "required": True, + "description": metadata.get("description"), + "example": metadata["example"], + "selector": metadata["selector"], + } async def execute_service(call): await entry_data.client.execute_service(service, call.data) @@ -327,6 +375,13 @@ async def _register_service( DOMAIN, service_name, execute_service, vol.Schema(schema) ) + service_desc = { + "description": f"Calls the service {service.name} of the node {entry_data.device_info.name}", + "fields": fields, + } + + async_set_service_schema(hass, DOMAIN, service_name, service_desc) + async def _setup_services( hass: HomeAssistantType, entry_data: RuntimeEntryData, services: List[UserService]