From 6133cb73cb6359d3935c6654407e0845951dd3d9 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Mon, 5 Oct 2026 09:59:13 +0200 Subject: [PATCH] Move input_number service registration to services module (#184284) Co-authored-by: Claude Opus 5 --- .../components/input_number/__init__.py | 56 ++++++++----------- .../components/input_number/const.py | 16 ++++++ .../components/input_number/services.py | 49 ++++++++++++++++ 3 files changed, 87 insertions(+), 34 deletions(-) create mode 100644 homeassistant/components/input_number/services.py diff --git a/homeassistant/components/input_number/__init__.py b/homeassistant/components/input_number/__init__.py index 8153879ef338..163cf0145126 100644 --- a/homeassistant/components/input_number/__init__.py +++ b/homeassistant/components/input_number/__init__.py @@ -1,6 +1,7 @@ """Support to set a numeric value from a slider or text box.""" from contextlib import suppress +from dataclasses import dataclass import logging from typing import Any, Self, override @@ -16,19 +17,26 @@ from homeassistant.const import ( # noqa: F401 CONF_UNIT_OF_MEASUREMENT, SERVICE_RELOAD, ) -from homeassistant.core import HomeAssistant, ServiceCall, callback +from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import collection, config_validation as cv from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.restore_state import RestoreEntity -import homeassistant.helpers.service from homeassistant.helpers.storage import Store from homeassistant.helpers.typing import ConfigType, VolDictType -from .const import InputNumberEntityStateAttribute +from .const import ( # noqa: F401 + ATTR_VALUE, + DATA_INPUT_NUMBER, + DOMAIN, + SERVICE_DECREMENT, + SERVICE_INCREMENT, + SERVICE_SET_VALUE, + InputNumberEntityStateAttribute, +) +from .services import async_setup_services _LOGGER = logging.getLogger(__name__) -DOMAIN = "input_number" CONF_INITIAL = "initial" CONF_MIN = "min" @@ -39,15 +47,10 @@ MODE_SLIDER = "slider" MODE_BOX = "box" ATTR_INITIAL = "initial" -ATTR_VALUE = "value" ATTR_MIN = "min" ATTR_MAX = "max" ATTR_STEP = "step" -SERVICE_SET_VALUE = "set_value" -SERVICE_INCREMENT = "increment" -SERVICE_DECREMENT = "decrement" - def _cv_input_number(cfg): """Configure validation helper for input number (probatio).""" @@ -104,11 +107,18 @@ CONFIG_SCHEMA = probatio.Schema( }, extra=probatio.ALLOW_EXTRA, ) -RELOAD_SERVICE_SCHEMA = probatio.Schema({}) STORAGE_KEY = DOMAIN STORAGE_VERSION = 1 +@dataclass(slots=True) +class InputNumberData: + """Runtime data for the input_number integration.""" + + component: EntityComponent[InputNumber] + yaml_collection: collection.YamlCollection + + async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up an input slider.""" component = EntityComponent[InputNumber](_LOGGER, DOMAIN, hass) @@ -139,31 +149,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: storage_collection, DOMAIN, DOMAIN, STORAGE_FIELDS, STORAGE_FIELDS ).async_setup(hass) - async def reload_service_handler(service_call: ServiceCall) -> None: - """Reload yaml entities.""" - conf = await component.async_prepare_reload(skip_reset=True) - await yaml_collection.async_load( - [{CONF_ID: id_, **conf} for id_, conf in conf.get(DOMAIN, {}).items()] - ) - - homeassistant.helpers.service.async_register_admin_service( - hass, - DOMAIN, - SERVICE_RELOAD, - reload_service_handler, - schema=RELOAD_SERVICE_SCHEMA, - ) - - component.async_register_entity_service( - SERVICE_SET_VALUE, - {probatio.Required(ATTR_VALUE): probatio.Coerce(float)}, - "async_set_native_value", - ) - - component.async_register_entity_service(SERVICE_INCREMENT, None, "async_increment") - - component.async_register_entity_service(SERVICE_DECREMENT, None, "async_decrement") + hass.data[DATA_INPUT_NUMBER] = InputNumberData(component, yaml_collection) + async_setup_services(hass) return True diff --git a/homeassistant/components/input_number/const.py b/homeassistant/components/input_number/const.py index c052ef8afdaa..ad00cd2c7f03 100644 --- a/homeassistant/components/input_number/const.py +++ b/homeassistant/components/input_number/const.py @@ -1,6 +1,22 @@ """Constants for the input_number integration.""" from enum import StrEnum +from typing import TYPE_CHECKING, Final + +from homeassistant.util.hass_dict import HassKey + +if TYPE_CHECKING: + from . import InputNumberData + +DOMAIN: Final = "input_number" + +DATA_INPUT_NUMBER: HassKey[InputNumberData] = HassKey(DOMAIN) + +ATTR_VALUE: Final = "value" + +SERVICE_SET_VALUE: Final = "set_value" +SERVICE_INCREMENT: Final = "increment" +SERVICE_DECREMENT: Final = "decrement" class InputNumberEntityStateAttribute(StrEnum): diff --git a/homeassistant/components/input_number/services.py b/homeassistant/components/input_number/services.py new file mode 100644 index 000000000000..e70b006cbfbf --- /dev/null +++ b/homeassistant/components/input_number/services.py @@ -0,0 +1,49 @@ +"""Services for the input_number integration.""" + +import probatio + +from homeassistant.const import CONF_ID, SERVICE_RELOAD +from homeassistant.core import HomeAssistant, ServiceCall, callback +from homeassistant.helpers.service import async_register_admin_service + +from .const import ( + ATTR_VALUE, + DATA_INPUT_NUMBER, + DOMAIN, + SERVICE_DECREMENT, + SERVICE_INCREMENT, + SERVICE_SET_VALUE, +) + +RELOAD_SERVICE_SCHEMA = probatio.Schema({}) + + +async def _async_reload_service(service_call: ServiceCall) -> None: + """Reload yaml entities.""" + hass = service_call.hass + data = hass.data[DATA_INPUT_NUMBER] + conf = await data.component.async_prepare_reload(skip_reset=True) + await data.yaml_collection.async_load( + [{CONF_ID: id_, **conf} for id_, conf in conf.get(DOMAIN, {}).items()] + ) + + +@callback +def async_setup_services(hass: HomeAssistant) -> None: + """Register the input_number services.""" + async_register_admin_service( + hass, + DOMAIN, + SERVICE_RELOAD, + _async_reload_service, + schema=RELOAD_SERVICE_SCHEMA, + ) + + component = hass.data[DATA_INPUT_NUMBER].component + component.async_register_entity_service( + SERVICE_SET_VALUE, + {probatio.Required(ATTR_VALUE): probatio.Coerce(float)}, + "async_set_native_value", + ) + component.async_register_entity_service(SERVICE_INCREMENT, None, "async_increment") + component.async_register_entity_service(SERVICE_DECREMENT, None, "async_decrement")