From 256bb25591b6d7bc406d8ade1069f1be2f51f499 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Mon, 21 Sep 2026 18:41:19 +0200 Subject: [PATCH] Move humidifier service registration to services module (#182825) --- .../components/humidifier/__init__.py | 56 ++----------- homeassistant/components/humidifier/const.py | 10 ++- .../components/humidifier/services.py | 82 +++++++++++++++++++ 3 files changed, 96 insertions(+), 52 deletions(-) create mode 100644 homeassistant/components/humidifier/services.py diff --git a/homeassistant/components/humidifier/__init__.py b/homeassistant/components/humidifier/__init__.py index 10994b43399b..c4d10f6c4eb2 100644 --- a/homeassistant/components/humidifier/__init__.py +++ b/homeassistant/components/humidifier/__init__.py @@ -4,24 +4,21 @@ from datetime import timedelta import logging from typing import Any, final, override -import probatio from propcache.api import cached_property from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ( +from homeassistant.const import ( # noqa: F401 ATTR_MODE, SERVICE_TOGGLE, SERVICE_TURN_OFF, SERVICE_TURN_ON, STATE_ON, ) -from homeassistant.core import HomeAssistant, ServiceCall -from homeassistant.exceptions import ServiceValidationError +from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv from homeassistant.helpers.entity import ToggleEntity, ToggleEntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType -from homeassistant.util.hass_dict import HassKey from .const import ( # noqa: F401 ATTR_ACTION, @@ -31,6 +28,7 @@ from .const import ( # noqa: F401 ATTR_MAX_HUMIDITY, ATTR_MIN_HUMIDITY, ATTR_TARGET_HUMIDITY_STEP, + DATA_COMPONENT, DEFAULT_MAX_HUMIDITY, DEFAULT_MIN_HUMIDITY, DEVICE_CLASSES_SCHEMA, @@ -52,10 +50,10 @@ from .const import ( # noqa: F401 HumidifierEntityFeature, HumidifierEntityStateAttribute, ) +from .services import async_setup_services _LOGGER = logging.getLogger(__name__) -DATA_COMPONENT: HassKey[EntityComponent[HumidifierEntity]] = HassKey(DOMAIN) ENTITY_ID_FORMAT = DOMAIN + ".{}" PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE @@ -84,24 +82,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: ) await component.async_setup(config) - component.async_register_entity_service(SERVICE_TURN_ON, None, "async_turn_on") - component.async_register_entity_service(SERVICE_TURN_OFF, None, "async_turn_off") - component.async_register_entity_service(SERVICE_TOGGLE, None, "async_toggle") - component.async_register_entity_service( - SERVICE_SET_MODE, - {probatio.Required(ATTR_MODE): cv.string}, - "async_set_mode", - [HumidifierEntityFeature.MODES], - ) - component.async_register_entity_service( - SERVICE_SET_HUMIDITY, - { - probatio.Required(ATTR_HUMIDITY): probatio.All( - probatio.Coerce(int), probatio.Range(min=0, max=100) - ) - }, - async_service_humidity_set, - ) + async_setup_services(hass) return True @@ -282,30 +263,3 @@ class HumidifierEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_AT def supported_features(self) -> HumidifierEntityFeature: """Return the list of supported features.""" return self._attr_supported_features - - -async def async_service_humidity_set( - entity: HumidifierEntity, service_call: ServiceCall -) -> None: - """Handle set humidity service.""" - humidity = service_call.data[ATTR_HUMIDITY] - min_humidity = entity.min_humidity - max_humidity = entity.max_humidity - _LOGGER.debug( - "Check valid humidity %d in range %d - %d", - humidity, - min_humidity, - max_humidity, - ) - if humidity < min_humidity or humidity > max_humidity: - raise ServiceValidationError( - translation_domain=DOMAIN, - translation_key="humidity_out_of_range", - translation_placeholders={ - "humidity": str(humidity), - "min_humidity": str(min_humidity), - "max_humidity": str(max_humidity), - }, - ) - - await entity.async_set_humidity(humidity) diff --git a/homeassistant/components/humidifier/const.py b/homeassistant/components/humidifier/const.py index c0e5f77084cf..105cca67076b 100644 --- a/homeassistant/components/humidifier/const.py +++ b/homeassistant/components/humidifier/const.py @@ -1,11 +1,19 @@ """Provides the constants needed for component.""" from enum import IntFlag, StrEnum -from typing import Final +from typing import TYPE_CHECKING, Final import probatio +from homeassistant.util.hass_dict import HassKey + +if TYPE_CHECKING: + from homeassistant.helpers.entity_component import EntityComponent + + from . import HumidifierEntity + DOMAIN: Final = "humidifier" +DATA_COMPONENT: HassKey[EntityComponent[HumidifierEntity]] = HassKey(DOMAIN) MODE_NORMAL = "normal" MODE_ECO = "eco" diff --git a/homeassistant/components/humidifier/services.py b/homeassistant/components/humidifier/services.py new file mode 100644 index 000000000000..9f6b30fd4b16 --- /dev/null +++ b/homeassistant/components/humidifier/services.py @@ -0,0 +1,82 @@ +"""Services for the Humidifier integration.""" + +import logging +from typing import TYPE_CHECKING + +import probatio + +from homeassistant.const import ( + ATTR_MODE, + SERVICE_TOGGLE, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, +) +from homeassistant.core import HomeAssistant, ServiceCall, callback +from homeassistant.exceptions import ServiceValidationError +from homeassistant.helpers import config_validation as cv + +from .const import ( + ATTR_HUMIDITY, + DATA_COMPONENT, + DOMAIN, + SERVICE_SET_HUMIDITY, + SERVICE_SET_MODE, + HumidifierEntityFeature, +) + +if TYPE_CHECKING: + from . import HumidifierEntity + +_LOGGER = logging.getLogger(__name__) + + +async def _async_service_humidity_set( + entity: HumidifierEntity, service_call: ServiceCall +) -> None: + """Handle set humidity service.""" + humidity = service_call.data[ATTR_HUMIDITY] + min_humidity = entity.min_humidity + max_humidity = entity.max_humidity + _LOGGER.debug( + "Check valid humidity %d in range %d - %d", + humidity, + min_humidity, + max_humidity, + ) + if humidity < min_humidity or humidity > max_humidity: + raise ServiceValidationError( + translation_domain=DOMAIN, + translation_key="humidity_out_of_range", + translation_placeholders={ + "humidity": str(humidity), + "min_humidity": str(min_humidity), + "max_humidity": str(max_humidity), + }, + ) + + await entity.async_set_humidity(humidity) + + +@callback +def async_setup_services(hass: HomeAssistant) -> None: + """Register the humidifier services.""" + component = hass.data[DATA_COMPONENT] + + component.async_register_entity_service(SERVICE_TURN_ON, None, "async_turn_on") + component.async_register_entity_service(SERVICE_TURN_OFF, None, "async_turn_off") + component.async_register_entity_service(SERVICE_TOGGLE, None, "async_toggle") + component.async_register_entity_service( + SERVICE_SET_MODE, + {probatio.Required(ATTR_MODE): cv.string}, + "async_set_mode", + [HumidifierEntityFeature.MODES], + ) + component.async_register_entity_service( + SERVICE_SET_HUMIDITY, + { + probatio.Required(ATTR_HUMIDITY): probatio.All( + probatio.Coerce(int), probatio.Range(min=0, max=100) + ) + }, + _async_service_humidity_set, + )