Add buttons to connect/disconnect the Idasen Desk (#102433)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Abílio Costa 2023-11-03 00:57:48 +00:00 committed by GitHub
parent e7db0bf34d
commit 4a117c0a1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 135 additions and 1 deletions

View File

@ -24,7 +24,7 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import DOMAIN
PLATFORMS: list[Platform] = [Platform.COVER]
PLATFORMS: list[Platform] = [Platform.BUTTON, Platform.COVER]
_LOGGER = logging.getLogger(__name__)

View File

@ -0,0 +1,101 @@
"""Representation of Idasen Desk buttons."""
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
import logging
from typing import Any, Final
from homeassistant.components.button import (
ButtonDeviceClass,
ButtonEntity,
ButtonEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import DeskData, IdasenDeskCoordinator
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
@dataclass
class IdasenDeskButtonDescriptionMixin:
"""Mixin to describe a IdasenDesk button entity."""
press_action: Callable[
[IdasenDeskCoordinator], Callable[[], Coroutine[Any, Any, Any]]
]
@dataclass
class IdasenDeskButtonDescription(
ButtonEntityDescription, IdasenDeskButtonDescriptionMixin
):
"""Class to describe a IdasenDesk button entity."""
BUTTONS: Final = [
IdasenDeskButtonDescription(
key="connect",
name="Connect",
icon="mdi:bluetooth-connect",
device_class=ButtonDeviceClass.RESTART,
entity_category=EntityCategory.CONFIG,
press_action=lambda coordinator: coordinator.async_connect,
),
IdasenDeskButtonDescription(
key="disconnect",
name="Disconnect",
icon="mdi:bluetooth-off",
device_class=ButtonDeviceClass.RESTART,
entity_category=EntityCategory.CONFIG,
press_action=lambda coordinator: coordinator.async_disconnect,
),
]
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set buttons for device."""
data: DeskData = hass.data[DOMAIN][entry.entry_id]
async_add_entities(
IdasenDeskButton(data.address, data.device_info, data.coordinator, button)
for button in BUTTONS
)
class IdasenDeskButton(ButtonEntity):
"""Defines a IdasenDesk button."""
entity_description: IdasenDeskButtonDescription
_attr_has_entity_name = True
def __init__(
self,
address: str,
device_info: DeviceInfo,
coordinator: IdasenDeskCoordinator,
description: IdasenDeskButtonDescription,
) -> None:
"""Initialize the IdasenDesk button entity."""
self.entity_description = description
self._attr_unique_id = f"{self.entity_description.key}-{address}"
self._attr_device_info = device_info
self._address = address
self._coordinator = coordinator
async def async_press(self) -> None:
"""Triggers the IdasenDesk button press service."""
_LOGGER.debug(
"Trigger %s for %s",
self.entity_description.key,
self._address,
)
await self.entity_description.press_action(self._coordinator)()

View File

@ -0,0 +1,33 @@
"""Test the IKEA Idasen Desk connection buttons."""
from unittest.mock import MagicMock
from homeassistant.core import HomeAssistant
from . import init_integration
async def test_connect_button(
hass: HomeAssistant,
mock_desk_api: MagicMock,
) -> None:
"""Test pressing the connect button."""
await init_integration(hass)
await hass.services.async_call(
"button", "press", {"entity_id": "button.test_connect"}, blocking=True
)
assert mock_desk_api.connect.call_count == 2
async def test_disconnect_button(
hass: HomeAssistant,
mock_desk_api: MagicMock,
) -> None:
"""Test pressing the disconnect button."""
await init_integration(hass)
mock_desk_api.is_connected = True
await hass.services.async_call(
"button", "press", {"entity_id": "button.test_disconnect"}, blocking=True
)
mock_desk_api.disconnect.assert_called_once()