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) name: str | None = door_station_config.get(CONF_NAME)
events = entry.options.get(CONF_EVENTS, []) events = entry.options.get(CONF_EVENTS, [])
event_entity_ids: dict[str, str] = {} 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_bird_data = DoorBirdData(door_station, info, event_entity_ids)
door_station.update_events(events) door_station.update_events(events)
# Subscribe to doorbell or motion events # Subscribe to doorbell or motion events
@ -103,7 +105,7 @@ async def _async_register_events(
) -> bool: ) -> bool:
"""Register events on device.""" """Register events on device."""
try: try:
await door_station.async_register_events(hass) await door_station.async_register_events()
except ClientResponseError: except ClientResponseError:
persistent_notification.async_create( persistent_notification.async_create(
hass, 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 collections.abc import Callable, Coroutine
from dataclasses import dataclass from dataclasses import dataclass, replace
from typing import Any from typing import Any
from doorbirdpy import DoorBird
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .device import ConfiguredDoorBird, async_reset_device_favorites
from .entity import DoorBirdEntity from .entity import DoorBirdEntity
from .models import DoorBirdConfigEntry, DoorBirdData from .models import DoorBirdConfigEntry, DoorBirdData
@ -20,18 +20,25 @@ IR_RELAY = "__ir_light__"
class DoorbirdButtonEntityDescription(ButtonEntityDescription): class DoorbirdButtonEntityDescription(ButtonEntityDescription):
"""Class to describe a Doorbird Button entity.""" """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( RELAY_ENTITY_DESCRIPTION = DoorbirdButtonEntityDescription(
key="relay", key="relay",
translation_key="relay", press_action=lambda door_station, relay: door_station.device.energize_relay(relay),
press_action=lambda device, relay: device.energize_relay(relay),
) )
IR_ENTITY_DESCRIPTION = DoorbirdButtonEntityDescription( BUTTON_DESCRIPTIONS: tuple[DoorbirdButtonEntityDescription, ...] = (
key="ir", DoorbirdButtonEntityDescription(
translation_key="ir", key="__ir_light__",
press_action=lambda device, _: device.turn_light_on(), 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: ) -> None:
"""Set up the DoorBird button platform.""" """Set up the DoorBird button platform."""
door_bird_data = config_entry.runtime_data 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 = [ 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 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) async_add_entities(entities)
class DoorBirdButton(DoorBirdEntity, ButtonEntity): class DoorBirdButton(DoorBirdEntity, ButtonEntity):
"""A relay in a DoorBird device.""" """A button for a DoorBird device."""
entity_description: DoorbirdButtonEntityDescription entity_description: DoorbirdButtonEntityDescription
def __init__( def __init__(
self, self,
door_bird_data: DoorBirdData, door_bird_data: DoorBirdData,
relay: str,
entity_description: DoorbirdButtonEntityDescription, entity_description: DoorbirdButtonEntityDescription,
relay: str | None = None,
) -> None: ) -> None:
"""Initialize a relay in a DoorBird device.""" """Initialize a button for a DoorBird device."""
super().__init__(door_bird_data) super().__init__(door_bird_data)
self._relay = relay self._relay = relay or ""
self.entity_description = entity_description self.entity_description = entity_description
if self._relay == IR_RELAY: self._attr_unique_id = f"{self._mac_addr}_{relay or entity_description.key}"
self._attr_name = "IR"
else:
self._attr_name = f"Relay {self._relay}"
self._attr_unique_id = f"{self._mac_addr}_{self._relay}"
async def async_press(self) -> None: async def async_press(self) -> None:
"""Power the relay.""" """Call the press action."""
await self.entity_description.press_action( await self.entity_description.press_action(self._door_station, self._relay)
self._door_station.device, self._relay
)

View File

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

View File

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

View File

@ -9,7 +9,6 @@ from aiohttp import web
from homeassistant.components.http import KEY_HASS, HomeAssistantView from homeassistant.components.http import KEY_HASS, HomeAssistantView
from .const import API_URL, DOMAIN from .const import API_URL, DOMAIN
from .device import async_reset_device_favorites
from .util import get_door_station_by_token from .util import get_door_station_by_token
@ -38,11 +37,6 @@ class DoorBirdRequestView(HomeAssistantView):
else: else:
event_data = {} 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. # This integration uses a multiple different events.
# It would be a major breaking change to change this to # It would be a major breaking change to change this to