diff --git a/homeassistant/components/xiaomi_miio/__init__.py b/homeassistant/components/xiaomi_miio/__init__.py index 8db5273174b..05e2fbe6043 100644 --- a/homeassistant/components/xiaomi_miio/__init__.py +++ b/homeassistant/components/xiaomi_miio/__init__.py @@ -38,7 +38,12 @@ from miio.gateway.gateway import GatewayException from homeassistant.const import CONF_DEVICE, CONF_HOST, CONF_MODEL, CONF_TOKEN, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady -from homeassistant.helpers import device_registry as dr, entity_registry as er +from homeassistant.helpers import ( + config_validation as cv, + device_registry as dr, + entity_registry as er, +) +from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import ( @@ -72,10 +77,12 @@ from .const import ( SetupException, ) from .gateway import ConnectXiaomiGateway +from .services import async_setup_services from .typing import XiaomiMiioConfigEntry, XiaomiMiioRuntimeData _LOGGER = logging.getLogger(__name__) +CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN) POLLING_TIMEOUT_SEC = 10 UPDATE_INTERVAL = timedelta(seconds=15) @@ -123,6 +130,12 @@ MODEL_TO_CLASS_MAP = { } +async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: + """Set up the component.""" + async_setup_services(hass) + return True + + async def async_setup_entry(hass: HomeAssistant, entry: XiaomiMiioConfigEntry) -> bool: """Set up the Xiaomi Miio components from a config entry.""" if entry.data[CONF_FLOW_TYPE] == CONF_GATEWAY: diff --git a/homeassistant/components/xiaomi_miio/const.py b/homeassistant/components/xiaomi_miio/const.py index 0c188f20a02..94fbf427367 100644 --- a/homeassistant/components/xiaomi_miio/const.py +++ b/homeassistant/components/xiaomi_miio/const.py @@ -301,14 +301,6 @@ SERVICE_SET_WIFI_LED_OFF = "switch_set_wifi_led_off" SERVICE_SET_POWER_MODE = "switch_set_power_mode" SERVICE_SET_POWER_PRICE = "switch_set_power_price" -# Vacuum Services -SERVICE_MOVE_REMOTE_CONTROL = "vacuum_remote_control_move" -SERVICE_MOVE_REMOTE_CONTROL_STEP = "vacuum_remote_control_move_step" -SERVICE_START_REMOTE_CONTROL = "vacuum_remote_control_start" -SERVICE_STOP_REMOTE_CONTROL = "vacuum_remote_control_stop" -SERVICE_CLEAN_SEGMENT = "vacuum_clean_segment" -SERVICE_CLEAN_ZONE = "vacuum_clean_zone" -SERVICE_GOTO = "vacuum_goto" # Features FEATURE_SET_BUZZER = 1 diff --git a/homeassistant/components/xiaomi_miio/services.py b/homeassistant/components/xiaomi_miio/services.py new file mode 100644 index 00000000000..882cf5b65f6 --- /dev/null +++ b/homeassistant/components/xiaomi_miio/services.py @@ -0,0 +1,130 @@ +"""Xiaomi services.""" + +from __future__ import annotations + +import voluptuous as vol + +from homeassistant.components.vacuum import DOMAIN as VACUUM_DOMAIN +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers import config_validation as cv, service + +from .const import DOMAIN + +ATTR_RC_DURATION = "duration" +ATTR_RC_ROTATION = "rotation" +ATTR_RC_VELOCITY = "velocity" +ATTR_ZONE_ARRAY = "zone" +ATTR_ZONE_REPEATER = "repeats" + +# Vacuum Services +SERVICE_MOVE_REMOTE_CONTROL = "vacuum_remote_control_move" +SERVICE_MOVE_REMOTE_CONTROL_STEP = "vacuum_remote_control_move_step" +SERVICE_START_REMOTE_CONTROL = "vacuum_remote_control_start" +SERVICE_STOP_REMOTE_CONTROL = "vacuum_remote_control_stop" +SERVICE_CLEAN_SEGMENT = "vacuum_clean_segment" +SERVICE_CLEAN_ZONE = "vacuum_clean_zone" +SERVICE_GOTO = "vacuum_goto" + + +@callback +def async_setup_services(hass: HomeAssistant) -> None: + """Set up services.""" + + # Vacuum Services + service.async_register_platform_entity_service( + hass, + DOMAIN, + SERVICE_START_REMOTE_CONTROL, + entity_domain=VACUUM_DOMAIN, + schema=None, + func="async_remote_control_start", + ) + + service.async_register_platform_entity_service( + hass, + DOMAIN, + SERVICE_STOP_REMOTE_CONTROL, + entity_domain=VACUUM_DOMAIN, + schema=None, + func="async_remote_control_stop", + ) + + service.async_register_platform_entity_service( + hass, + DOMAIN, + SERVICE_MOVE_REMOTE_CONTROL, + entity_domain=VACUUM_DOMAIN, + schema={ + vol.Optional(ATTR_RC_VELOCITY): vol.All( + vol.Coerce(float), vol.Clamp(min=-0.29, max=0.29) + ), + vol.Optional(ATTR_RC_ROTATION): vol.All( + vol.Coerce(int), vol.Clamp(min=-179, max=179) + ), + vol.Optional(ATTR_RC_DURATION): cv.positive_int, + }, + func="async_remote_control_move", + ) + + service.async_register_platform_entity_service( + hass, + DOMAIN, + SERVICE_MOVE_REMOTE_CONTROL_STEP, + entity_domain=VACUUM_DOMAIN, + schema={ + vol.Optional(ATTR_RC_VELOCITY): vol.All( + vol.Coerce(float), vol.Clamp(min=-0.29, max=0.29) + ), + vol.Optional(ATTR_RC_ROTATION): vol.All( + vol.Coerce(int), vol.Clamp(min=-179, max=179) + ), + vol.Optional(ATTR_RC_DURATION): cv.positive_int, + }, + func="async_remote_control_move_step", + ) + + service.async_register_platform_entity_service( + hass, + DOMAIN, + SERVICE_CLEAN_ZONE, + entity_domain=VACUUM_DOMAIN, + schema={ + vol.Required(ATTR_ZONE_ARRAY): vol.All( + list, + [ + vol.ExactSequence( + [ + vol.Coerce(int), + vol.Coerce(int), + vol.Coerce(int), + vol.Coerce(int), + ] + ) + ], + ), + vol.Required(ATTR_ZONE_REPEATER): vol.All( + vol.Coerce(int), vol.Clamp(min=1, max=3) + ), + }, + func="async_clean_zone", + ) + + service.async_register_platform_entity_service( + hass, + DOMAIN, + SERVICE_GOTO, + entity_domain=VACUUM_DOMAIN, + schema={ + vol.Required("x_coord"): vol.Coerce(int), + vol.Required("y_coord"): vol.Coerce(int), + }, + func="async_goto", + ) + service.async_register_platform_entity_service( + hass, + DOMAIN, + SERVICE_CLEAN_SEGMENT, + entity_domain=VACUUM_DOMAIN, + schema={vol.Required("segments"): vol.Any(vol.Coerce(int), [vol.Coerce(int)])}, + func="async_clean_segment", + ) diff --git a/homeassistant/components/xiaomi_miio/vacuum.py b/homeassistant/components/xiaomi_miio/vacuum.py index 3b397e9ccfd..5ff31c3bb9e 100644 --- a/homeassistant/components/xiaomi_miio/vacuum.py +++ b/homeassistant/components/xiaomi_miio/vacuum.py @@ -7,7 +7,6 @@ import logging from typing import Any from miio import DeviceException -import voluptuous as vol from homeassistant.components.vacuum import ( StateVacuumEntity, @@ -16,34 +15,19 @@ from homeassistant.components.vacuum import ( ) from homeassistant.const import CONF_DEVICE from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.util.dt import as_utc from . import VacuumCoordinatorData -from .const import ( - CONF_FLOW_TYPE, - SERVICE_CLEAN_SEGMENT, - SERVICE_CLEAN_ZONE, - SERVICE_GOTO, - SERVICE_MOVE_REMOTE_CONTROL, - SERVICE_MOVE_REMOTE_CONTROL_STEP, - SERVICE_START_REMOTE_CONTROL, - SERVICE_STOP_REMOTE_CONTROL, -) +from .const import CONF_FLOW_TYPE from .entity import XiaomiCoordinatedMiioEntity from .typing import XiaomiMiioConfigEntry _LOGGER = logging.getLogger(__name__) ATTR_ERROR = "error" -ATTR_RC_DURATION = "duration" -ATTR_RC_ROTATION = "rotation" -ATTR_RC_VELOCITY = "velocity" ATTR_STATUS = "status" -ATTR_ZONE_ARRAY = "zone" -ATTR_ZONE_REPEATER = "repeats" ATTR_TIMERS = "timers" STATE_CODE_TO_STATE = { @@ -92,85 +76,6 @@ async def async_setup_entry( ) entities.append(mirobo) - platform = entity_platform.async_get_current_platform() - - platform.async_register_entity_service( - SERVICE_START_REMOTE_CONTROL, - None, - MiroboVacuum.async_remote_control_start.__name__, - ) - - platform.async_register_entity_service( - SERVICE_STOP_REMOTE_CONTROL, - None, - MiroboVacuum.async_remote_control_stop.__name__, - ) - - platform.async_register_entity_service( - SERVICE_MOVE_REMOTE_CONTROL, - { - vol.Optional(ATTR_RC_VELOCITY): vol.All( - vol.Coerce(float), vol.Clamp(min=-0.29, max=0.29) - ), - vol.Optional(ATTR_RC_ROTATION): vol.All( - vol.Coerce(int), vol.Clamp(min=-179, max=179) - ), - vol.Optional(ATTR_RC_DURATION): cv.positive_int, - }, - MiroboVacuum.async_remote_control_move.__name__, - ) - - platform.async_register_entity_service( - SERVICE_MOVE_REMOTE_CONTROL_STEP, - { - vol.Optional(ATTR_RC_VELOCITY): vol.All( - vol.Coerce(float), vol.Clamp(min=-0.29, max=0.29) - ), - vol.Optional(ATTR_RC_ROTATION): vol.All( - vol.Coerce(int), vol.Clamp(min=-179, max=179) - ), - vol.Optional(ATTR_RC_DURATION): cv.positive_int, - }, - MiroboVacuum.async_remote_control_move_step.__name__, - ) - - platform.async_register_entity_service( - SERVICE_CLEAN_ZONE, - { - vol.Required(ATTR_ZONE_ARRAY): vol.All( - list, - [ - vol.ExactSequence( - [ - vol.Coerce(int), - vol.Coerce(int), - vol.Coerce(int), - vol.Coerce(int), - ] - ) - ], - ), - vol.Required(ATTR_ZONE_REPEATER): vol.All( - vol.Coerce(int), vol.Clamp(min=1, max=3) - ), - }, - MiroboVacuum.async_clean_zone.__name__, - ) - - platform.async_register_entity_service( - SERVICE_GOTO, - { - vol.Required("x_coord"): vol.Coerce(int), - vol.Required("y_coord"): vol.Coerce(int), - }, - MiroboVacuum.async_goto.__name__, - ) - platform.async_register_entity_service( - SERVICE_CLEAN_SEGMENT, - {vol.Required("segments"): vol.Any(vol.Coerce(int), [vol.Coerce(int)])}, - MiroboVacuum.async_clean_segment.__name__, - ) - async_add_entities(entities, update_before_add=True) diff --git a/tests/components/xiaomi_miio/test_vacuum.py b/tests/components/xiaomi_miio/test_vacuum.py index 385e706f0bf..43820f8e933 100644 --- a/tests/components/xiaomi_miio/test_vacuum.py +++ b/tests/components/xiaomi_miio/test_vacuum.py @@ -28,10 +28,7 @@ from homeassistant.components.xiaomi_miio.const import ( DOMAIN, MODELS_VACUUM, ) -from homeassistant.components.xiaomi_miio.vacuum import ( - ATTR_ERROR, - ATTR_TIMERS, - CONF_DEVICE, +from homeassistant.components.xiaomi_miio.services import ( SERVICE_CLEAN_SEGMENT, SERVICE_CLEAN_ZONE, SERVICE_GOTO, @@ -40,9 +37,11 @@ from homeassistant.components.xiaomi_miio.vacuum import ( SERVICE_START_REMOTE_CONTROL, SERVICE_STOP_REMOTE_CONTROL, ) +from homeassistant.components.xiaomi_miio.vacuum import ATTR_ERROR, ATTR_TIMERS from homeassistant.const import ( ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, + CONF_DEVICE, CONF_HOST, CONF_MAC, CONF_MODEL,