mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Move bluesound service registration to separate module (#129086)
This commit is contained in:
parent
7b1d6ddcf6
commit
daf0939f09
@ -14,7 +14,7 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .media_player import setup_services
|
from .services import setup_services
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
|
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
|
||||||
|
|
||||||
|
@ -2,9 +2,5 @@
|
|||||||
|
|
||||||
DOMAIN = "bluesound"
|
DOMAIN = "bluesound"
|
||||||
INTEGRATION_TITLE = "Bluesound"
|
INTEGRATION_TITLE = "Bluesound"
|
||||||
SERVICE_CLEAR_TIMER = "clear_sleep_timer"
|
|
||||||
SERVICE_JOIN = "join"
|
|
||||||
SERVICE_SET_TIMER = "set_sleep_timer"
|
|
||||||
SERVICE_UNJOIN = "unjoin"
|
|
||||||
ATTR_BLUESOUND_GROUP = "bluesound_group"
|
ATTR_BLUESOUND_GROUP = "bluesound_group"
|
||||||
ATTR_MASTER = "master"
|
ATTR_MASTER = "master"
|
||||||
|
@ -7,7 +7,7 @@ from asyncio import CancelledError, Task
|
|||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING, Any, NamedTuple
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from pyblu import Input, Player, Preset, Status, SyncStatus
|
from pyblu import Input, Player, Preset, Status, SyncStatus
|
||||||
from pyblu.errors import PlayerUnreachableError
|
from pyblu.errors import PlayerUnreachableError
|
||||||
@ -24,18 +24,8 @@ from homeassistant.components.media_player import (
|
|||||||
async_process_play_media_url,
|
async_process_play_media_url,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT
|
from homeassistant.config_entries import SOURCE_IMPORT
|
||||||
from homeassistant.const import (
|
from homeassistant.const import CONF_HOST, CONF_HOSTS, CONF_NAME, CONF_PORT
|
||||||
ATTR_ENTITY_ID,
|
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant
|
||||||
CONF_HOST,
|
|
||||||
CONF_HOSTS,
|
|
||||||
CONF_NAME,
|
|
||||||
CONF_PORT,
|
|
||||||
)
|
|
||||||
from homeassistant.core import (
|
|
||||||
DOMAIN as HOMEASSISTANT_DOMAIN,
|
|
||||||
HomeAssistant,
|
|
||||||
ServiceCall,
|
|
||||||
)
|
|
||||||
from homeassistant.data_entry_flow import FlowResultType
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
from homeassistant.exceptions import ServiceValidationError
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
from homeassistant.helpers import config_validation as cv, issue_registry as ir
|
from homeassistant.helpers import config_validation as cv, issue_registry as ir
|
||||||
@ -48,16 +38,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
from .const import (
|
from .const import ATTR_BLUESOUND_GROUP, ATTR_MASTER, DOMAIN, INTEGRATION_TITLE
|
||||||
ATTR_BLUESOUND_GROUP,
|
|
||||||
ATTR_MASTER,
|
|
||||||
DOMAIN,
|
|
||||||
INTEGRATION_TITLE,
|
|
||||||
SERVICE_CLEAR_TIMER,
|
|
||||||
SERVICE_JOIN,
|
|
||||||
SERVICE_SET_TIMER,
|
|
||||||
SERVICE_UNJOIN,
|
|
||||||
)
|
|
||||||
from .utils import format_unique_id
|
from .utils import format_unique_id
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -92,29 +73,6 @@ PLATFORM_SCHEMA = MEDIA_PLAYER_PLATFORM_SCHEMA.extend(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BS_SCHEMA = vol.Schema({vol.Optional(ATTR_ENTITY_ID): cv.entity_ids})
|
|
||||||
|
|
||||||
BS_JOIN_SCHEMA = BS_SCHEMA.extend({vol.Required(ATTR_MASTER): cv.entity_id})
|
|
||||||
|
|
||||||
|
|
||||||
class ServiceMethodDetails(NamedTuple):
|
|
||||||
"""Details for SERVICE_TO_METHOD mapping."""
|
|
||||||
|
|
||||||
method: str
|
|
||||||
schema: vol.Schema
|
|
||||||
|
|
||||||
|
|
||||||
SERVICE_TO_METHOD = {
|
|
||||||
SERVICE_JOIN: ServiceMethodDetails(method="async_join", schema=BS_JOIN_SCHEMA),
|
|
||||||
SERVICE_UNJOIN: ServiceMethodDetails(method="async_unjoin", schema=BS_SCHEMA),
|
|
||||||
SERVICE_SET_TIMER: ServiceMethodDetails(
|
|
||||||
method="async_increase_timer", schema=BS_SCHEMA
|
|
||||||
),
|
|
||||||
SERVICE_CLEAR_TIMER: ServiceMethodDetails(
|
|
||||||
method="async_clear_timer", schema=BS_SCHEMA
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async def _async_import(hass: HomeAssistant, config: ConfigType) -> None:
|
async def _async_import(hass: HomeAssistant, config: ConfigType) -> None:
|
||||||
"""Import config entry from configuration.yaml."""
|
"""Import config entry from configuration.yaml."""
|
||||||
@ -159,33 +117,6 @@ async def _async_import(hass: HomeAssistant, config: ConfigType) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup_services(hass: HomeAssistant) -> None:
|
|
||||||
"""Set up services for Bluesound component."""
|
|
||||||
|
|
||||||
async def async_service_handler(service: ServiceCall) -> None:
|
|
||||||
"""Map services to method of Bluesound devices."""
|
|
||||||
if not (method := SERVICE_TO_METHOD.get(service.service)):
|
|
||||||
return
|
|
||||||
|
|
||||||
params = {
|
|
||||||
key: value for key, value in service.data.items() if key != ATTR_ENTITY_ID
|
|
||||||
}
|
|
||||||
if entity_ids := service.data.get(ATTR_ENTITY_ID):
|
|
||||||
target_players = [
|
|
||||||
player for player in hass.data[DOMAIN] if player.entity_id in entity_ids
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
target_players = hass.data[DOMAIN]
|
|
||||||
|
|
||||||
for player in target_players:
|
|
||||||
await getattr(player, method.method)(**params)
|
|
||||||
|
|
||||||
for service, method in SERVICE_TO_METHOD.items():
|
|
||||||
hass.services.async_register(
|
|
||||||
DOMAIN, service, async_service_handler, schema=method.schema
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: BluesoundConfigEntry,
|
config_entry: BluesoundConfigEntry,
|
||||||
|
68
homeassistant/components/bluesound/services.py
Normal file
68
homeassistant/components/bluesound/services.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
"""Support for Bluesound devices."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import NamedTuple
|
||||||
|
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.const import ATTR_ENTITY_ID
|
||||||
|
from homeassistant.core import HomeAssistant, ServiceCall
|
||||||
|
from homeassistant.helpers import config_validation as cv
|
||||||
|
|
||||||
|
from .const import ATTR_MASTER, DOMAIN
|
||||||
|
|
||||||
|
SERVICE_CLEAR_TIMER = "clear_sleep_timer"
|
||||||
|
SERVICE_JOIN = "join"
|
||||||
|
SERVICE_SET_TIMER = "set_sleep_timer"
|
||||||
|
SERVICE_UNJOIN = "unjoin"
|
||||||
|
|
||||||
|
BS_SCHEMA = vol.Schema({vol.Optional(ATTR_ENTITY_ID): cv.entity_ids})
|
||||||
|
|
||||||
|
BS_JOIN_SCHEMA = BS_SCHEMA.extend({vol.Required(ATTR_MASTER): cv.entity_id})
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceMethodDetails(NamedTuple):
|
||||||
|
"""Details for SERVICE_TO_METHOD mapping."""
|
||||||
|
|
||||||
|
method: str
|
||||||
|
schema: vol.Schema
|
||||||
|
|
||||||
|
|
||||||
|
SERVICE_TO_METHOD = {
|
||||||
|
SERVICE_JOIN: ServiceMethodDetails(method="async_join", schema=BS_JOIN_SCHEMA),
|
||||||
|
SERVICE_UNJOIN: ServiceMethodDetails(method="async_unjoin", schema=BS_SCHEMA),
|
||||||
|
SERVICE_SET_TIMER: ServiceMethodDetails(
|
||||||
|
method="async_increase_timer", schema=BS_SCHEMA
|
||||||
|
),
|
||||||
|
SERVICE_CLEAR_TIMER: ServiceMethodDetails(
|
||||||
|
method="async_clear_timer", schema=BS_SCHEMA
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def setup_services(hass: HomeAssistant) -> None:
|
||||||
|
"""Set up services for Bluesound component."""
|
||||||
|
|
||||||
|
async def async_service_handler(service: ServiceCall) -> None:
|
||||||
|
"""Map services to method of Bluesound devices."""
|
||||||
|
if not (method := SERVICE_TO_METHOD.get(service.service)):
|
||||||
|
return
|
||||||
|
|
||||||
|
params = {
|
||||||
|
key: value for key, value in service.data.items() if key != ATTR_ENTITY_ID
|
||||||
|
}
|
||||||
|
if entity_ids := service.data.get(ATTR_ENTITY_ID):
|
||||||
|
target_players = [
|
||||||
|
player for player in hass.data[DOMAIN] if player.entity_id in entity_ids
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
target_players = hass.data[DOMAIN]
|
||||||
|
|
||||||
|
for player in target_players:
|
||||||
|
await getattr(player, method.method)(**params)
|
||||||
|
|
||||||
|
for service, method in SERVICE_TO_METHOD.items():
|
||||||
|
hass.services.async_register(
|
||||||
|
DOMAIN, service, async_service_handler, schema=method.schema
|
||||||
|
)
|
@ -10,8 +10,8 @@ from syrupy.assertion import SnapshotAssertion
|
|||||||
from syrupy.filters import props
|
from syrupy.filters import props
|
||||||
|
|
||||||
from homeassistant.components.bluesound import DOMAIN as BLUESOUND_DOMAIN
|
from homeassistant.components.bluesound import DOMAIN as BLUESOUND_DOMAIN
|
||||||
from homeassistant.components.bluesound.const import (
|
from homeassistant.components.bluesound.const import ATTR_MASTER
|
||||||
ATTR_MASTER,
|
from homeassistant.components.bluesound.services import (
|
||||||
SERVICE_CLEAR_TIMER,
|
SERVICE_CLEAR_TIMER,
|
||||||
SERVICE_JOIN,
|
SERVICE_JOIN,
|
||||||
SERVICE_SET_TIMER,
|
SERVICE_SET_TIMER,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user