From f7f18627a2a2ea23f70e3136a90c4ef91657ff42 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Tue, 3 Feb 2026 11:15:28 +0100 Subject: [PATCH] Move squeezebox service registration (#162132) --- .../components/squeezebox/__init__.py | 11 ++++- .../components/squeezebox/media_player.py | 32 +------------ .../components/squeezebox/quality_scale.yaml | 4 +- .../components/squeezebox/services.py | 48 +++++++++++++++++++ .../squeezebox/test_media_player.py | 2 +- 5 files changed, 61 insertions(+), 36 deletions(-) create mode 100644 homeassistant/components/squeezebox/services.py diff --git a/homeassistant/components/squeezebox/__init__.py b/homeassistant/components/squeezebox/__init__.py index 25c7aa36d15..3ba320091a6 100644 --- a/homeassistant/components/squeezebox/__init__.py +++ b/homeassistant/components/squeezebox/__init__.py @@ -23,7 +23,7 @@ from homeassistant.exceptions import ( ConfigEntryError, ConfigEntryNotReady, ) -from homeassistant.helpers import device_registry as dr +from homeassistant.helpers import config_validation as cv, device_registry as dr from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.device_registry import ( CONNECTION_NETWORK_MAC, @@ -32,6 +32,7 @@ from homeassistant.helpers.device_registry import ( ) from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.event import async_call_later +from homeassistant.helpers.typing import ConfigType from homeassistant.util.hass_dict import HassKey from .const import ( @@ -53,9 +54,11 @@ from .coordinator import ( LMSStatusDataUpdateCoordinator, SqueezeBoxPlayerUpdateCoordinator, ) +from .services import async_setup_services _LOGGER = logging.getLogger(__name__) +CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) PLATFORMS = [ Platform.BINARY_SENSOR, Platform.BUTTON, @@ -80,6 +83,12 @@ class SqueezeboxData: type SqueezeboxConfigEntry = ConfigEntry[SqueezeboxData] +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: SqueezeboxConfigEntry) -> bool: """Set up an LMS Server from a config entry.""" config = entry.data diff --git a/homeassistant/components/squeezebox/media_player.py b/homeassistant/components/squeezebox/media_player.py index c57d88e1cd0..094f50397a6 100644 --- a/homeassistant/components/squeezebox/media_player.py +++ b/homeassistant/components/squeezebox/media_player.py @@ -10,7 +10,6 @@ from typing import TYPE_CHECKING, Any, cast from lru import LRU from pysqueezebox import Server, async_discover -import voluptuous as vol from homeassistant.components import media_source from homeassistant.components.media_player import ( @@ -29,14 +28,12 @@ from homeassistant.components.media_player import ( async_process_play_media_url, ) from homeassistant.config_entries import SOURCE_INTEGRATION_DISCOVERY -from homeassistant.const import ATTR_COMMAND, CONF_HOST, CONF_PORT, Platform +from homeassistant.const import CONF_HOST, CONF_PORT, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import ( - config_validation as cv, device_registry as dr, discovery_flow, - entity_platform, entity_registry as er, ) from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, format_mac @@ -75,16 +72,12 @@ from .util import safe_library_call if TYPE_CHECKING: from . import SqueezeboxConfigEntry -SERVICE_CALL_METHOD = "call_method" -SERVICE_CALL_QUERY = "call_query" - ATTR_QUERY_RESULT = "query_result" _LOGGER = logging.getLogger(__name__) PARALLEL_UPDATES = 1 -ATTR_PARAMETERS = "parameters" ATTR_OTHER_PLAYER = "other_player" ATTR_TO_PROPERTY = [ @@ -181,29 +174,6 @@ async def async_setup_entry( ) ) - # Register entity services - platform = entity_platform.async_get_current_platform() - platform.async_register_entity_service( - SERVICE_CALL_METHOD, - { - vol.Required(ATTR_COMMAND): cv.string, - vol.Optional(ATTR_PARAMETERS): vol.All( - cv.ensure_list, vol.Length(min=1), [cv.string] - ), - }, - "async_call_method", - ) - platform.async_register_entity_service( - SERVICE_CALL_QUERY, - { - vol.Required(ATTR_COMMAND): cv.string, - vol.Optional(ATTR_PARAMETERS): vol.All( - cv.ensure_list, vol.Length(min=1), [cv.string] - ), - }, - "async_call_query", - ) - # Start server discovery task if not already running entry.async_on_unload(async_at_start(hass, start_server_discovery)) diff --git a/homeassistant/components/squeezebox/quality_scale.yaml b/homeassistant/components/squeezebox/quality_scale.yaml index c9926a6d1ee..0817aead782 100644 --- a/homeassistant/components/squeezebox/quality_scale.yaml +++ b/homeassistant/components/squeezebox/quality_scale.yaml @@ -1,8 +1,6 @@ rules: # Bronze - action-setup: - status: exempt - comment: Integration only has entity_actions, which are setup in the entity async_setup_entry. + action-setup: done appropriate-polling: done brands: done common-modules: done diff --git a/homeassistant/components/squeezebox/services.py b/homeassistant/components/squeezebox/services.py new file mode 100644 index 00000000000..79eb2a687c5 --- /dev/null +++ b/homeassistant/components/squeezebox/services.py @@ -0,0 +1,48 @@ +"""Support for interfacing to the SqueezeBox API.""" + +from __future__ import annotations + +import voluptuous as vol + +from homeassistant.components.media_player import DOMAIN as MEDIA_PLAYER_DOMAIN +from homeassistant.const import ATTR_COMMAND +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers import config_validation as cv, service + +from .const import DOMAIN + +SERVICE_CALL_METHOD = "call_method" +SERVICE_CALL_QUERY = "call_query" + +ATTR_PARAMETERS = "parameters" + + +@callback +def async_setup_services(hass: HomeAssistant) -> None: + """Set up services.""" + service.async_register_platform_entity_service( + hass, + DOMAIN, + SERVICE_CALL_METHOD, + entity_domain=MEDIA_PLAYER_DOMAIN, + schema={ + vol.Required(ATTR_COMMAND): cv.string, + vol.Optional(ATTR_PARAMETERS): vol.All( + cv.ensure_list, vol.Length(min=1), [cv.string] + ), + }, + func="async_call_method", + ) + service.async_register_platform_entity_service( + hass, + DOMAIN, + SERVICE_CALL_QUERY, + entity_domain=MEDIA_PLAYER_DOMAIN, + schema={ + vol.Required(ATTR_COMMAND): cv.string, + vol.Optional(ATTR_PARAMETERS): vol.All( + cv.ensure_list, vol.Length(min=1), [cv.string] + ), + }, + func="async_call_query", + ) diff --git a/tests/components/squeezebox/test_media_player.py b/tests/components/squeezebox/test_media_player.py index 8e889b8c12e..804478dce10 100644 --- a/tests/components/squeezebox/test_media_player.py +++ b/tests/components/squeezebox/test_media_player.py @@ -40,7 +40,7 @@ from homeassistant.components.squeezebox.const import ( PLAYER_UPDATE_INTERVAL, SENSOR_UPDATE_INTERVAL, ) -from homeassistant.components.squeezebox.media_player import ( +from homeassistant.components.squeezebox.services import ( ATTR_PARAMETERS, SERVICE_CALL_METHOD, SERVICE_CALL_QUERY,