diff --git a/.coveragerc b/.coveragerc index 6cff79350d2..71a4b652ce1 100644 --- a/.coveragerc +++ b/.coveragerc @@ -139,6 +139,7 @@ omit = homeassistant/components/bosch_shc/sensor.py homeassistant/components/bosch_shc/switch.py homeassistant/components/braviatv/__init__.py + homeassistant/components/braviatv/button.py homeassistant/components/braviatv/const.py homeassistant/components/braviatv/coordinator.py homeassistant/components/braviatv/entity.py diff --git a/homeassistant/components/braviatv/__init__.py b/homeassistant/components/braviatv/__init__.py index 18c1a9a2d89..d06482e5c71 100644 --- a/homeassistant/components/braviatv/__init__.py +++ b/homeassistant/components/braviatv/__init__.py @@ -14,7 +14,11 @@ from homeassistant.helpers.aiohttp_client import async_create_clientsession from .const import CONF_IGNORED_SOURCES, CONF_USE_PSK, DOMAIN from .coordinator import BraviaTVCoordinator -PLATFORMS: Final[list[Platform]] = [Platform.MEDIA_PLAYER, Platform.REMOTE] +PLATFORMS: Final[list[Platform]] = [ + Platform.BUTTON, + Platform.MEDIA_PLAYER, + Platform.REMOTE, +] async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: diff --git a/homeassistant/components/braviatv/button.py b/homeassistant/components/braviatv/button.py new file mode 100644 index 00000000000..6cc0cb393c5 --- /dev/null +++ b/homeassistant/components/braviatv/button.py @@ -0,0 +1,89 @@ +"""Button support for Bravia TV.""" +from __future__ import annotations + +from collections.abc import Callable, Coroutine +from dataclasses import dataclass + +from homeassistant.components.button import ( + ButtonDeviceClass, + ButtonEntity, + ButtonEntityDescription, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN +from .coordinator import BraviaTVCoordinator +from .entity import BraviaTVEntity + + +@dataclass +class BraviaTVButtonDescriptionMixin: + """Mixin to describe a Bravia TV Button entity.""" + + press_action: Callable[[BraviaTVCoordinator], Coroutine] + + +@dataclass +class BraviaTVButtonDescription( + ButtonEntityDescription, BraviaTVButtonDescriptionMixin +): + """Bravia TV Button description.""" + + +BUTTONS: tuple[BraviaTVButtonDescription, ...] = ( + BraviaTVButtonDescription( + key="reboot", + name="Reboot", + device_class=ButtonDeviceClass.RESTART, + entity_category=EntityCategory.CONFIG, + press_action=lambda coordinator: coordinator.async_reboot_device(), + ), + BraviaTVButtonDescription( + key="terminate_apps", + name="Terminate apps", + entity_category=EntityCategory.CONFIG, + press_action=lambda coordinator: coordinator.async_terminate_apps(), + ), +) + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up the Bravia TV Button entities.""" + + coordinator = hass.data[DOMAIN][config_entry.entry_id] + unique_id = config_entry.unique_id + assert unique_id is not None + + async_add_entities( + BraviaTVButton(coordinator, unique_id, config_entry.title, description) + for description in BUTTONS + ) + + +class BraviaTVButton(BraviaTVEntity, ButtonEntity): + """Representation of a Bravia TV Button.""" + + entity_description: BraviaTVButtonDescription + + def __init__( + self, + coordinator: BraviaTVCoordinator, + unique_id: str, + model: str, + description: BraviaTVButtonDescription, + ) -> None: + """Initialize the button.""" + super().__init__(coordinator, unique_id, model) + self._attr_unique_id = f"{unique_id}_{description.key}" + self.entity_description = description + + async def async_press(self) -> None: + """Trigger the button action.""" + await self.entity_description.press_action(self.coordinator) diff --git a/homeassistant/components/braviatv/coordinator.py b/homeassistant/components/braviatv/coordinator.py index 1f134d8e2de..3bfd815f990 100644 --- a/homeassistant/components/braviatv/coordinator.py +++ b/homeassistant/components/braviatv/coordinator.py @@ -287,3 +287,13 @@ class BraviaTVCoordinator(DataUpdateCoordinator[None]): cmd, commands_keys, ) + + @catch_braviatv_errors + async def async_reboot_device(self) -> None: + """Send command to reboot the device.""" + await self.client.reboot() + + @catch_braviatv_errors + async def async_terminate_apps(self) -> None: + """Send command to terminate all applications.""" + await self.client.terminate_apps()