Skip to content

Commit

Permalink
Refresh coordinators when setting or clearing usercode (#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
raman325 authored Mar 5, 2024
1 parent de4f8d5 commit 4113bc7
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 36 deletions.
71 changes: 39 additions & 32 deletions custom_components/lock_code_manager/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,12 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> bool:
"""Set up config entry."""
coordinators: list[LockUsercodeUpdateCoordinator] = list(
hass.data[DOMAIN][config_entry.entry_id][COORDINATORS].values()
)

@callback
def add_pin_enabled_entity(slot_num: int, ent_reg: er.EntityRegistry) -> None:
"""Add PIN enabled binary sensor entities for slot."""
async_add_entities(
[
LockCodeManagerPINSyncedEntity(
hass, ent_reg, config_entry, coordinators, slot_num
)
],
[LockCodeManagerPINSyncedEntity(hass, ent_reg, config_entry, slot_num)],
True,
)

Expand All @@ -84,14 +77,12 @@ def __init__(
hass: HomeAssistant,
ent_reg: er.EntityRegistry,
config_entry: ConfigEntry,
coordinators: list[LockUsercodeUpdateCoordinator],
slot_num: int,
) -> None:
"""Initialize entity."""
BaseLockCodeManagerEntity.__init__(
self, hass, ent_reg, config_entry, slot_num, ATTR_PIN_SYNCED_TO_LOCKS
)
self.coordinators = coordinators
self._entity_id_map: dict[str, str] = {}
self._issue_reg: ir.IssueRegistry | None = None
self._call_later_unsub: Callable | None = None
Expand All @@ -114,18 +105,7 @@ async def async_update_usercodes(
"""Update usercodes on locks based on state change."""
if not states:
states = {}
disabling_entity_ids = (
state["entity_id"]
for key, state in states.items()
if (key != CONF_NUMBER_OF_USES and state["state"] != STATE_ON)
or (
key == CONF_NUMBER_OF_USES
and (
state["state"] in (STATE_UNAVAILABLE, STATE_UNKNOWN)
or int(float(state["state"])) == 0
)
)
)
coordinators: list[LockUsercodeUpdateCoordinator] = []
for lock in self.locks:
lock_slot_sensor_state = self._lock_slot_sensor_state(lock)
if self.is_on:
Expand All @@ -145,27 +125,52 @@ async def async_update_usercodes(
if lock_slot_sensor_state == pin_state.state:
continue

await lock.async_set_usercode(
int(self.slot_num), pin_state.state, name_state.state
)

_LOGGER.info(
"%s (%s): Setting usercode for %s slot %s",
"%s (%s): Set usercode for %s slot %s",
self.config_entry.entry_id,
self.config_entry.title,
lock.lock.entity_id,
self.slot_num,
)

await lock.async_set_usercode(
int(self.slot_num), pin_state.state, name_state.state
)
else:
if lock_slot_sensor_state in (
"",
STATE_UNKNOWN,
):
continue

if not (
disabling_entity_ids := list(
state["entity_id"]
for key, state in states.items()
if (
key not in (CONF_NUMBER_OF_USES, CONF_PIN)
and state["state"] != STATE_ON
)
or (
key == CONF_NUMBER_OF_USES
and (
state["state"] in (STATE_UNAVAILABLE, STATE_UNKNOWN)
or int(float(state["state"])) == 0
)
)
or (
key == CONF_PIN
and state["state"] != self._lock_slot_sensor_state(lock)
)
)
):
return

await lock.async_clear_usercode(int(self.slot_num))

_LOGGER.info(
(
"%s (%s): Clearing usercode for lock %s slot %s because the "
"%s (%s): Cleared usercode for lock %s slot %s because the "
"following entities indicate the slot is disabled: %s"
),
self.config_entry.entry_id,
Expand All @@ -175,12 +180,14 @@ async def async_update_usercodes(
", ".join(disabling_entity_ids),
)

await lock.async_clear_usercode(int(self.slot_num))

await asyncio.gather(
*[coordinator.async_refresh() for coordinator in self.coordinators]
coordinators.append(
self.hass.data[DOMAIN][COORDINATORS][lock.lock.entity_id]
)

await asyncio.gather(
*[coordinator.async_refresh() for coordinator in coordinators]
)

async def _update_state(self, _: datetime | None = None) -> None:
"""Update binary sensor state by getting dependent states."""
if self._call_later_unsub:
Expand Down
6 changes: 3 additions & 3 deletions tests/test_binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,9 @@ async def test_binary_sensor_entity(
)
await hass.async_block_till_done()

assert hass.data[LOCK_DATA][LOCK_1_ENTITY_ID]["service_calls"]["set_usercode"] == [
(2, "0987", "test2")
]
assert hass.data[LOCK_DATA][LOCK_1_ENTITY_ID]["service_calls"]["set_usercode"][
-1
] == (2, "0987", "test2")

new_config = copy.deepcopy(BASE_CONFIG)
new_config[CONF_SLOTS][2][CONF_CALENDAR] = "calendar.test_2"
Expand Down
3 changes: 2 additions & 1 deletion tests/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import logging

from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant

_LOGGER = logging.getLogger(__name__)
Expand All @@ -13,7 +14,7 @@ async def test_sensor_entity(
lock_code_manager_config_entry,
):
"""Test sensor entity."""
for code_slot, pin in ((1, "1234"), (2, "5678")):
for code_slot, pin in ((1, "1234"), (2, STATE_UNAVAILABLE)):
state = hass.states.get(f"sensor.test_1_code_slot_{code_slot}")
assert state
assert state.state == pin
Expand Down

0 comments on commit 4113bc7

Please sign in to comment.