Migrate resetting doorbird favorites to a button (#121720)

This commit is contained in:
J. Nick Koston 2024-07-10 14:34:02 -07:00 committed by GitHub
parent af6c28983d
commit d87bbaa67a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 54 additions and 42 deletions

View file

@ -79,7 +79,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: DoorBirdConfigEntry) ->
name: str | None = door_station_config.get(CONF_NAME)
events = entry.options.get(CONF_EVENTS, [])
event_entity_ids: dict[str, str] = {}
door_station = ConfiguredDoorBird(device, name, custom_url, token, event_entity_ids)
door_station = ConfiguredDoorBird(
hass, device, name, custom_url, token, event_entity_ids
)
door_bird_data = DoorBirdData(door_station, info, event_entity_ids)
door_station.update_events(events)
# Subscribe to doorbell or motion events
@ -103,7 +105,7 @@ async def _async_register_events(
) -> bool:
"""Register events on device."""
try:
await door_station.async_register_events(hass)
await door_station.async_register_events()
except ClientResponseError:
persistent_notification.async_create(
hass,

View file

@ -1,15 +1,15 @@
"""Support for powering relays in a DoorBird video doorbell."""
"""Support for relays and actions in a DoorBird video doorbell."""
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from dataclasses import dataclass, replace
from typing import Any
from doorbirdpy import DoorBird
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .device import ConfiguredDoorBird, async_reset_device_favorites
from .entity import DoorBirdEntity
from .models import DoorBirdConfigEntry, DoorBirdData
@ -20,18 +20,25 @@ IR_RELAY = "__ir_light__"
class DoorbirdButtonEntityDescription(ButtonEntityDescription):
"""Class to describe a Doorbird Button entity."""
press_action: Callable[[DoorBird, str], Coroutine[Any, Any, bool]]
press_action: Callable[[ConfiguredDoorBird, str], Coroutine[Any, Any, bool | None]]
RELAY_ENTITY_DESCRIPTION = DoorbirdButtonEntityDescription(
key="relay",
translation_key="relay",
press_action=lambda device, relay: device.energize_relay(relay),
press_action=lambda door_station, relay: door_station.device.energize_relay(relay),
)
IR_ENTITY_DESCRIPTION = DoorbirdButtonEntityDescription(
key="ir",
translation_key="ir",
press_action=lambda device, _: device.turn_light_on(),
BUTTON_DESCRIPTIONS: tuple[DoorbirdButtonEntityDescription, ...] = (
DoorbirdButtonEntityDescription(
key="__ir_light__",
translation_key="ir",
press_action=lambda door_station, _: door_station.device.turn_light_on(),
),
DoorbirdButtonEntityDescription(
key="reset_favorites",
translation_key="reset_favorites",
press_action=lambda door_station, _: async_reset_device_favorites(door_station),
entity_category=EntityCategory.CONFIG,
),
)
@ -42,40 +49,39 @@ async def async_setup_entry(
) -> None:
"""Set up the DoorBird button platform."""
door_bird_data = config_entry.runtime_data
relays = door_bird_data.door_station_info["RELAYS"]
relays: list[str] = door_bird_data.door_station_info["RELAYS"]
entities = [
DoorBirdButton(door_bird_data, relay, RELAY_ENTITY_DESCRIPTION)
DoorBirdButton(
door_bird_data,
replace(RELAY_ENTITY_DESCRIPTION, name=f"Relay {relay}"),
relay,
)
for relay in relays
]
entities.append(DoorBirdButton(door_bird_data, IR_RELAY, IR_ENTITY_DESCRIPTION))
entities.extend(
DoorBirdButton(door_bird_data, button_description)
for button_description in BUTTON_DESCRIPTIONS
)
async_add_entities(entities)
class DoorBirdButton(DoorBirdEntity, ButtonEntity):
"""A relay in a DoorBird device."""
"""A button for a DoorBird device."""
entity_description: DoorbirdButtonEntityDescription
def __init__(
self,
door_bird_data: DoorBirdData,
relay: str,
entity_description: DoorbirdButtonEntityDescription,
relay: str | None = None,
) -> None:
"""Initialize a relay in a DoorBird device."""
"""Initialize a button for a DoorBird device."""
super().__init__(door_bird_data)
self._relay = relay
self._relay = relay or ""
self.entity_description = entity_description
if self._relay == IR_RELAY:
self._attr_name = "IR"
else:
self._attr_name = f"Relay {self._relay}"
self._attr_unique_id = f"{self._mac_addr}_{self._relay}"
self._attr_unique_id = f"{self._mac_addr}_{relay or entity_description.key}"
async def async_press(self) -> None:
"""Power the relay."""
await self.entity_description.press_action(
self._door_station.device, self._relay
)
"""Call the press action."""
await self.entity_description.press_action(self._door_station, self._relay)

View file

@ -32,6 +32,7 @@ class ConfiguredDoorBird:
def __init__(
self,
hass: HomeAssistant,
device: DoorBird,
name: str | None,
custom_url: str | None,
@ -39,6 +40,7 @@ class ConfiguredDoorBird:
event_entity_ids: dict[str, str],
) -> None:
"""Initialize configured device."""
self._hass = hass
self._name = name
self._device = device
self._custom_url = custom_url
@ -75,8 +77,9 @@ class ConfiguredDoorBird:
"""Get token for device."""
return self._token
async def async_register_events(self, hass: HomeAssistant) -> None:
async def async_register_events(self) -> None:
"""Register events on device."""
hass = self._hass
# Override url if another is specified in the configuration
if custom_url := self.custom_url:
hass_url = custom_url
@ -174,12 +177,11 @@ class ConfiguredDoorBird:
}
async def async_reset_device_favorites(
hass: HomeAssistant, door_station: ConfiguredDoorBird
) -> None:
async def async_reset_device_favorites(door_station: ConfiguredDoorBird) -> None:
"""Handle clearing favorites on device."""
door_bird = door_station.device
favorites: dict[str, dict[str, Any]] = await door_bird.favorites()
favorites = await door_bird.favorites()
for favorite_type, favorite_ids in favorites.items():
for favorite_id in favorite_ids:
await door_bird.delete_favorite(favorite_type, favorite_id)
await door_station.async_register_events()

View file

@ -38,6 +38,14 @@
}
},
"entity": {
"button": {
"reset_favorites": {
"name": "Reset favorites"
},
"ir": {
"name": "IR"
}
},
"camera": {
"live": {
"name": "live"

View file

@ -9,7 +9,6 @@ from aiohttp import web
from homeassistant.components.http import KEY_HASS, HomeAssistantView
from .const import API_URL, DOMAIN
from .device import async_reset_device_favorites
from .util import get_door_station_by_token
@ -38,11 +37,6 @@ class DoorBirdRequestView(HomeAssistantView):
else:
event_data = {}
if event == "clear":
await async_reset_device_favorites(hass, door_station)
message = f"HTTP Favorites cleared for {door_station.slug}"
return web.Response(text=message)
#
# This integration uses a multiple different events.
# It would be a major breaking change to change this to