Ensure doorbird events are re-registered when changing options (#46860)
- Fixed the update listener not being unsubscribed - DRY up some of the code - Fix sync code being called in async - Reduce executor jumpspull/47041/head
parent
a43f3c1a0c
commit
72263abfa9
|
@ -34,6 +34,7 @@ from .const import (
|
|||
DOOR_STATION_EVENT_ENTITY_IDS,
|
||||
DOOR_STATION_INFO,
|
||||
PLATFORMS,
|
||||
UNDO_UPDATE_LISTENER,
|
||||
)
|
||||
from .util import get_doorstation_by_token
|
||||
|
||||
|
@ -128,8 +129,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
|
||||
device = DoorBird(device_ip, username, password)
|
||||
try:
|
||||
status = await hass.async_add_executor_job(device.ready)
|
||||
info = await hass.async_add_executor_job(device.info)
|
||||
status, info = await hass.async_add_executor_job(_init_doorbird_device, device)
|
||||
except urllib.error.HTTPError as err:
|
||||
if err.code == HTTP_UNAUTHORIZED:
|
||||
_LOGGER.error(
|
||||
|
@ -154,18 +154,20 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
custom_url = doorstation_config.get(CONF_CUSTOM_URL)
|
||||
name = doorstation_config.get(CONF_NAME)
|
||||
events = doorstation_options.get(CONF_EVENTS, [])
|
||||
doorstation = ConfiguredDoorBird(device, name, events, custom_url, token)
|
||||
doorstation = ConfiguredDoorBird(device, name, custom_url, token)
|
||||
doorstation.update_events(events)
|
||||
# Subscribe to doorbell or motion events
|
||||
if not await _async_register_events(hass, doorstation):
|
||||
raise ConfigEntryNotReady
|
||||
|
||||
undo_listener = entry.add_update_listener(_update_listener)
|
||||
|
||||
hass.data[DOMAIN][config_entry_id] = {
|
||||
DOOR_STATION: doorstation,
|
||||
DOOR_STATION_INFO: info,
|
||||
UNDO_UPDATE_LISTENER: undo_listener,
|
||||
}
|
||||
|
||||
entry.add_update_listener(_update_listener)
|
||||
|
||||
for component in PLATFORMS:
|
||||
hass.async_create_task(
|
||||
hass.config_entries.async_forward_entry_setup(entry, component)
|
||||
|
@ -174,9 +176,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
return True
|
||||
|
||||
|
||||
def _init_doorbird_device(device):
|
||||
return device.ready(), device.info()
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||
"""Unload a config entry."""
|
||||
|
||||
hass.data[DOMAIN][entry.entry_id][UNDO_UPDATE_LISTENER]()
|
||||
|
||||
unload_ok = all(
|
||||
await asyncio.gather(
|
||||
*[
|
||||
|
@ -195,7 +203,7 @@ async def _async_register_events(hass, doorstation):
|
|||
try:
|
||||
await hass.async_add_executor_job(doorstation.register_events, hass)
|
||||
except HTTPError:
|
||||
hass.components.persistent_notification.create(
|
||||
hass.components.persistent_notification.async_create(
|
||||
"Doorbird configuration failed. Please verify that API "
|
||||
"Operator permission is enabled for the Doorbird user. "
|
||||
"A restart will be required once permissions have been "
|
||||
|
@ -212,8 +220,7 @@ async def _update_listener(hass: HomeAssistant, entry: ConfigEntry):
|
|||
"""Handle options update."""
|
||||
config_entry_id = entry.entry_id
|
||||
doorstation = hass.data[DOMAIN][config_entry_id][DOOR_STATION]
|
||||
|
||||
doorstation.events = entry.options[CONF_EVENTS]
|
||||
doorstation.update_events(entry.options[CONF_EVENTS])
|
||||
# Subscribe to doorbell or motion events
|
||||
await _async_register_events(hass, doorstation)
|
||||
|
||||
|
@ -234,14 +241,19 @@ def _async_import_options_from_data_if_missing(hass: HomeAssistant, entry: Confi
|
|||
class ConfiguredDoorBird:
|
||||
"""Attach additional information to pass along with configured device."""
|
||||
|
||||
def __init__(self, device, name, events, custom_url, token):
|
||||
def __init__(self, device, name, custom_url, token):
|
||||
"""Initialize configured device."""
|
||||
self._name = name
|
||||
self._device = device
|
||||
self._custom_url = custom_url
|
||||
self.events = None
|
||||
self.doorstation_events = None
|
||||
self._token = token
|
||||
|
||||
def update_events(self, events):
|
||||
"""Update the doorbird events."""
|
||||
self.events = events
|
||||
self.doorstation_events = [self._get_event_name(event) for event in self.events]
|
||||
self._token = token
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -305,16 +317,7 @@ class ConfiguredDoorBird:
|
|||
|
||||
def webhook_is_registered(self, url, favs=None) -> bool:
|
||||
"""Return whether the given URL is registered as a device favorite."""
|
||||
favs = favs if favs else self.device.favorites()
|
||||
|
||||
if "http" not in favs:
|
||||
return False
|
||||
|
||||
for fav in favs["http"].values():
|
||||
if fav["value"] == url:
|
||||
return True
|
||||
|
||||
return False
|
||||
return self.get_webhook_id(url, favs) is not None
|
||||
|
||||
def get_webhook_id(self, url, favs=None) -> str or None:
|
||||
"""
|
||||
|
|
|
@ -17,3 +17,5 @@ DOORBIRD_INFO_KEY_DEVICE_TYPE = "DEVICE-TYPE"
|
|||
DOORBIRD_INFO_KEY_RELAYS = "RELAYS"
|
||||
DOORBIRD_INFO_KEY_PRIMARY_MAC_ADDR = "PRIMARY_MAC_ADDR"
|
||||
DOORBIRD_INFO_KEY_WIFI_MAC_ADDR = "WIFI_MAC_ADDR"
|
||||
|
||||
UNDO_UPDATE_LISTENER = "undo_update_listener"
|
||||
|
|
|
@ -17,8 +17,9 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
entities = []
|
||||
config_entry_id = config_entry.entry_id
|
||||
|
||||
doorstation = hass.data[DOMAIN][config_entry_id][DOOR_STATION]
|
||||
doorstation_info = hass.data[DOMAIN][config_entry_id][DOOR_STATION_INFO]
|
||||
data = hass.data[DOMAIN][config_entry_id]
|
||||
doorstation = data[DOOR_STATION]
|
||||
doorstation_info = data[DOOR_STATION_INFO]
|
||||
|
||||
relays = doorstation_info["RELAYS"]
|
||||
relays.append(IR_RELAY)
|
||||
|
|
Loading…
Reference in New Issue