From 12e9241f715245bb3002a01a3d58f887613369c5 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Fri, 23 Jan 2026 14:33:35 +0100 Subject: [PATCH] Move bang_olufsen service registration (#161484) Co-authored-by: Markus Jacobsen --- .../components/bang_olufsen/__init__.py | 12 ++- .../components/bang_olufsen/media_player.py | 68 +-------------- .../components/bang_olufsen/services.py | 83 +++++++++++++++++++ 3 files changed, 96 insertions(+), 67 deletions(-) create mode 100644 homeassistant/components/bang_olufsen/services.py diff --git a/homeassistant/components/bang_olufsen/__init__.py b/homeassistant/components/bang_olufsen/__init__.py index 04566f1a4c3..1668b03b021 100644 --- a/homeassistant/components/bang_olufsen/__init__.py +++ b/homeassistant/components/bang_olufsen/__init__.py @@ -17,10 +17,12 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_MODEL, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady -from homeassistant.helpers import device_registry as dr +from homeassistant.helpers import config_validation as cv, device_registry as dr +from homeassistant.helpers.typing import ConfigType from homeassistant.util.ssl import get_default_context from .const import DOMAIN +from .services import async_setup_services from .websocket import BeoWebsocket @@ -41,6 +43,14 @@ PLATFORMS = [ Platform.SENSOR, ] +CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) + + +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: BeoConfigEntry) -> bool: """Set up from a config entry.""" diff --git a/homeassistant/components/bang_olufsen/media_player.py b/homeassistant/components/bang_olufsen/media_player.py index e7a958502e8..8d2c157c1a3 100644 --- a/homeassistant/components/bang_olufsen/media_player.py +++ b/homeassistant/components/bang_olufsen/media_player.py @@ -38,7 +38,6 @@ from mozart_api.models import ( VolumeState, ) from mozart_api.mozart_client import MozartClient, get_highest_resolution_artwork -import voluptuous as vol from homeassistant.components import media_source from homeassistant.components.media_player import ( @@ -56,17 +55,10 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_MODEL, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError, ServiceValidationError -from homeassistant.helpers import ( - config_validation as cv, - device_registry as dr, - entity_registry as er, -) +from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity_platform import ( - AddConfigEntryEntitiesCallback, - async_get_current_platform, -) +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.dt import utcnow from . import BeoConfigEntry @@ -74,7 +66,6 @@ from .const import ( BEO_REPEAT_FROM_HA, BEO_REPEAT_TO_HA, BEO_STATES, - BEOLINK_JOIN_SOURCES, BEOLINK_JOIN_SOURCES_TO_UPPER, CONF_BEOLINK_JID, CONNECTION_STATUS, @@ -129,61 +120,6 @@ async def async_setup_entry( update_before_add=True, ) - # Register actions. - platform = async_get_current_platform() - - jid_regex = vol.Match( - r"(^\d{4})[.](\d{7})[.](\d{8})(@products\.bang-olufsen\.com)$" - ) - - platform.async_register_entity_service( - name="beolink_join", - schema={ - vol.Optional("beolink_jid"): jid_regex, - vol.Optional("source_id"): vol.In(BEOLINK_JOIN_SOURCES), - }, - func="async_beolink_join", - ) - - platform.async_register_entity_service( - name="beolink_expand", - schema={ - vol.Exclusive("all_discovered", "devices", ""): cv.boolean, - vol.Exclusive( - "beolink_jids", - "devices", - "Define either specific Beolink JIDs or all discovered", - ): vol.All( - cv.ensure_list, - [jid_regex], - ), - }, - func="async_beolink_expand", - ) - - platform.async_register_entity_service( - name="beolink_unexpand", - schema={ - vol.Required("beolink_jids"): vol.All( - cv.ensure_list, - [jid_regex], - ), - }, - func="async_beolink_unexpand", - ) - - platform.async_register_entity_service( - name="beolink_leave", - schema=None, - func="async_beolink_leave", - ) - - platform.async_register_entity_service( - name="beolink_allstandby", - schema=None, - func="async_beolink_allstandby", - ) - class BeoMediaPlayer(BeoEntity, MediaPlayerEntity): """Representation of a media player.""" diff --git a/homeassistant/components/bang_olufsen/services.py b/homeassistant/components/bang_olufsen/services.py new file mode 100644 index 00000000000..a0f9f278ec0 --- /dev/null +++ b/homeassistant/components/bang_olufsen/services.py @@ -0,0 +1,83 @@ +"""Services for Bang & Olufsen integration.""" + +from __future__ import annotations + +import voluptuous as vol + +from homeassistant.components.media_player import DOMAIN as MEDIA_PLAYER_DOMAIN +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers import config_validation as cv, service + +from .const import BEOLINK_JOIN_SOURCES, DOMAIN + + +@callback +def async_setup_services(hass: HomeAssistant) -> None: + """Home Assistant services.""" + + jid_regex = vol.Match( + r"(^\d{4})[.](\d{7})[.](\d{8})(@products\.bang-olufsen\.com)$" + ) + + service.async_register_platform_entity_service( + hass, + DOMAIN, + "beolink_join", + entity_domain=MEDIA_PLAYER_DOMAIN, + schema={ + vol.Optional("beolink_jid"): jid_regex, + vol.Optional("source_id"): vol.In(BEOLINK_JOIN_SOURCES), + }, + func="async_beolink_join", + ) + + service.async_register_platform_entity_service( + hass, + DOMAIN, + "beolink_expand", + entity_domain=MEDIA_PLAYER_DOMAIN, + schema={ + vol.Exclusive("all_discovered", "devices", ""): cv.boolean, + vol.Exclusive( + "beolink_jids", + "devices", + "Define either specific Beolink JIDs or all discovered", + ): vol.All( + cv.ensure_list, + [jid_regex], + ), + }, + func="async_beolink_expand", + ) + + service.async_register_platform_entity_service( + hass, + DOMAIN, + "beolink_unexpand", + entity_domain=MEDIA_PLAYER_DOMAIN, + schema={ + vol.Required("beolink_jids"): vol.All( + cv.ensure_list, + [jid_regex], + ), + }, + func="async_beolink_unexpand", + ) + + service.async_register_platform_entity_service( + hass, + DOMAIN, + "beolink_leave", + entity_domain=MEDIA_PLAYER_DOMAIN, + schema=None, + func="async_beolink_leave", + ) + + service.async_register_platform_entity_service( + hass, + DOMAIN, + "beolink_allstandby", + entity_domain=MEDIA_PLAYER_DOMAIN, + schema=None, + func="async_beolink_allstandby", + )