129 lines
3.9 KiB
Python
129 lines
3.9 KiB
Python
"""Button entities for Bluesound."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Awaitable, Callable
|
|
from dataclasses import dataclass
|
|
from typing import TYPE_CHECKING
|
|
|
|
from pyblu import Player
|
|
|
|
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
|
|
from homeassistant.const import CONF_PORT
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.device_registry import (
|
|
CONNECTION_NETWORK_MAC,
|
|
DeviceInfo,
|
|
format_mac,
|
|
)
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|
|
|
from .const import DOMAIN
|
|
from .coordinator import BluesoundCoordinator
|
|
from .media_player import DEFAULT_PORT
|
|
from .utils import format_unique_id
|
|
|
|
if TYPE_CHECKING:
|
|
from . import BluesoundConfigEntry
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: BluesoundConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Set up the Bluesound entry."""
|
|
|
|
async_add_entities(
|
|
BluesoundButton(
|
|
config_entry.runtime_data.coordinator,
|
|
config_entry.runtime_data.player,
|
|
config_entry.data[CONF_PORT],
|
|
description,
|
|
)
|
|
for description in BUTTON_DESCRIPTIONS
|
|
)
|
|
|
|
|
|
@dataclass(kw_only=True, frozen=True)
|
|
class BluesoundButtonEntityDescription(ButtonEntityDescription):
|
|
"""Description for Bluesound button entities."""
|
|
|
|
press_fn: Callable[[Player], Awaitable[None]]
|
|
|
|
|
|
async def clear_sleep_timer(player: Player) -> None:
|
|
"""Clear the sleep timer."""
|
|
sleep = -1
|
|
while sleep != 0:
|
|
sleep = await player.sleep_timer()
|
|
|
|
|
|
async def set_sleep_timer(player: Player) -> None:
|
|
"""Set the sleep timer."""
|
|
await player.sleep_timer()
|
|
|
|
|
|
BUTTON_DESCRIPTIONS = [
|
|
BluesoundButtonEntityDescription(
|
|
key="set_sleep_timer",
|
|
translation_key="set_sleep_timer",
|
|
entity_registry_enabled_default=False,
|
|
press_fn=set_sleep_timer,
|
|
),
|
|
BluesoundButtonEntityDescription(
|
|
key="clear_sleep_timer",
|
|
translation_key="clear_sleep_timer",
|
|
entity_registry_enabled_default=False,
|
|
press_fn=clear_sleep_timer,
|
|
),
|
|
]
|
|
|
|
|
|
class BluesoundButton(CoordinatorEntity[BluesoundCoordinator], ButtonEntity):
|
|
"""Base class for Bluesound buttons."""
|
|
|
|
_attr_has_entity_name = True
|
|
entity_description: BluesoundButtonEntityDescription
|
|
|
|
def __init__(
|
|
self,
|
|
coordinator: BluesoundCoordinator,
|
|
player: Player,
|
|
port: int,
|
|
description: BluesoundButtonEntityDescription,
|
|
) -> None:
|
|
"""Initialize the Bluesound button."""
|
|
super().__init__(coordinator)
|
|
sync_status = coordinator.data.sync_status
|
|
|
|
self.entity_description = description
|
|
self._player = player
|
|
self._attr_unique_id = (
|
|
f"{description.key}-{format_unique_id(sync_status.mac, port)}"
|
|
)
|
|
|
|
if port == DEFAULT_PORT:
|
|
self._attr_device_info = DeviceInfo(
|
|
identifiers={(DOMAIN, format_mac(sync_status.mac))},
|
|
connections={(CONNECTION_NETWORK_MAC, format_mac(sync_status.mac))},
|
|
name=sync_status.name,
|
|
manufacturer=sync_status.brand,
|
|
model=sync_status.model_name,
|
|
model_id=sync_status.model,
|
|
)
|
|
else:
|
|
self._attr_device_info = DeviceInfo(
|
|
identifiers={(DOMAIN, format_unique_id(sync_status.mac, port))},
|
|
name=sync_status.name,
|
|
manufacturer=sync_status.brand,
|
|
model=sync_status.model_name,
|
|
model_id=sync_status.model,
|
|
via_device=(DOMAIN, format_mac(sync_status.mac)),
|
|
)
|
|
|
|
async def async_press(self) -> None:
|
|
"""Handle the button press."""
|
|
await self.entity_description.press_fn(self._player)
|