Skip to content

Commit

Permalink
Coordinator refresh should be successful before syncing PINs (#250)
Browse files Browse the repository at this point in the history
  • Loading branch information
raman325 authored Jun 16, 2024
1 parent e507e40 commit e49fd40
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 38 deletions.
54 changes: 42 additions & 12 deletions custom_components/lock_code_manager/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

import asyncio
import functools
import logging
from pathlib import Path
from typing import Any
Expand All @@ -27,8 +28,16 @@
CONF_NAME,
CONF_PIN,
CONF_URL,
EVENT_HOMEASSISTANT_STARTED,
)
from homeassistant.core import (
Config,
CoreState,
Event,
HomeAssistant,
ServiceCall,
callback,
)
from homeassistant.core import Config, HomeAssistant, ServiceCall
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import (
config_validation as cv,
Expand Down Expand Up @@ -151,6 +160,31 @@ async def _hard_refresh_usercodes(service: ServiceCall) -> None:
return True


@callback
def _setup_entry_after_start(
hass: HomeAssistant, config_entry: ConfigEntry, event: Event | None = None
) -> None:
"""
Set up config entry.
Should only be run once Home Assistant has started.
"""
config_entry.async_on_unload(
config_entry.add_update_listener(async_update_listener)
)

if config_entry.data:
# Move data from data to options so update listener can work
hass.config_entries.async_update_entry(
config_entry, data={}, options={**config_entry.data}
)
else:
hass.async_create_task(
async_update_listener(hass, config_entry),
f"Initial setup for entities for {config_entry.entry_id}",
)


async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Set up is called when Home Assistant is loading our component."""
ent_reg = er.async_get(hass)
Expand Down Expand Up @@ -190,19 +224,15 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS),
"setup_platforms",
)
config_entry.async_on_unload(
config_entry.add_update_listener(async_update_listener)
)

if config_entry.data:
# Move data from data to options so update listener can work
hass.config_entries.async_update_entry(
config_entry, data={}, options={**config_entry.data}
)
if hass.state == CoreState.running:
_setup_entry_after_start(hass, config_entry)
else:
hass.async_create_task(
async_update_listener(hass, config_entry),
f"Initial setup for entities for {entry_id}",
config_entry.async_on_unload(
hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_STARTED,
functools.partial(_setup_entry_after_start, hass, config_entry),
)
)

return True
Expand Down
59 changes: 33 additions & 26 deletions custom_components/lock_code_manager/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
STATE_ON,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
Platform,
)
from homeassistant.core import (
Event,
Expand Down Expand Up @@ -168,7 +169,7 @@ async def async_added_to_hass(self) -> None:
self.async_on_remove(
async_track_state_change_filtered(
self.hass,
TrackStates(True, set(), set()),
TrackStates(False, set(), {Platform.CALENDAR}),
self._handle_calendar_state_changes,
).async_remove
)
Expand Down Expand Up @@ -228,18 +229,20 @@ def available(self) -> bool:
async def async_update(self) -> None:
"""Update entity."""
if (
self._lock
and not self._lock.locked()
and self.is_on is False
and (state := self.hass.states.get(self.lock.lock.entity_id))
and state.state not in (STATE_UNAVAILABLE, STATE_UNKNOWN)
self._lock.locked()
or self.is_on
or not (state := self.hass.states.get(self.lock.lock.entity_id))
or state.state in (STATE_UNAVAILABLE, STATE_UNKNOWN)
or not self.coordinator.last_update_success
):
_LOGGER.error(
"Updating %s code slot %s because it is out of sync",
self.lock.lock.entity_id,
self.slot_num,
)
await self._async_update_state()
return

_LOGGER.error(
"Updating %s code slot %s because it is out of sync",
self.lock.lock.entity_id,
self.slot_num,
)
await self._async_update_state()

def _get_entity_state(self, key: str) -> str | None:
"""Get entity state."""
Expand All @@ -256,19 +259,23 @@ async def _async_update_state(
if event:
entity_id = event.data["entity_id"]
to_state = event.data["new_state"]
if entity_id is not None and (
not (ent_entry := self.ent_reg.async_get(entity_id))
or ent_entry.platform != DOMAIN
or (ent_entry.domain, ent_entry.unique_id)
not in (
(BINARY_SENSOR_DOMAIN, self._active_unique_id),
(TEXT_DOMAIN, self._name_text_unique_id),
(TEXT_DOMAIN, self._pin_text_unique_id),
(SENSOR_DOMAIN, self._lock_slot_sensor_unique_id),
)
or (
to_state is not None
and to_state.state in (STATE_UNAVAILABLE, STATE_UNKNOWN)

if not self.coordinator.last_update_success or (
entity_id is not None
and (
not (ent_entry := self.ent_reg.async_get(entity_id))
or ent_entry.platform != DOMAIN
or (ent_entry.domain, ent_entry.unique_id)
not in (
(BINARY_SENSOR_DOMAIN, self._active_unique_id),
(TEXT_DOMAIN, self._name_text_unique_id),
(TEXT_DOMAIN, self._pin_text_unique_id),
(SENSOR_DOMAIN, self._lock_slot_sensor_unique_id),
)
or (
to_state is not None
and to_state.state in (STATE_UNAVAILABLE, STATE_UNKNOWN)
)
)
):
return
Expand Down Expand Up @@ -338,7 +345,7 @@ async def async_added_to_hass(self) -> None:
"""Handle entity added to hass."""
await BinarySensorEntity.async_added_to_hass(self)
await BaseLockCodeManagerCodeSlotPerLockEntity.async_added_to_hass(self)
# await CoordinatorEntity.async_added_to_hass(self)
await CoordinatorEntity.async_added_to_hass(self)

self.async_on_remove(
async_track_state_change_filtered(
Expand Down

0 comments on commit e49fd40

Please sign in to comment.