Skip to content

Commit

Permalink
Log why a usercode gets cleared (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
raman325 authored Feb 26, 2024
1 parent fb344a0 commit ad77169
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 9 deletions.
1 change: 0 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
Dev:
- Figure out how to add which keys and corresponding states caused the binary sensor state change in the logs
- Reevaluate logging

Test:
Expand Down
47 changes: 39 additions & 8 deletions custom_components/lock_code_manager/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@
from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_NAME, CONF_PIN, MATCH_ALL, STATE_ON, STATE_UNKNOWN
from homeassistant.const import (
CONF_NAME,
CONF_PIN,
MATCH_ALL,
STATE_ON,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
)
from homeassistant.core import HomeAssistant, State, callback
from homeassistant.helpers import entity_registry as er, issue_registry as ir
from homeassistant.helpers.dispatcher import async_dispatcher_connect
Expand Down Expand Up @@ -90,8 +97,24 @@ def __init__(
self._issue_reg: ir.IssueRegistry | None = None
self._call_later_unsub: Callable | None = None

async def async_update_usercodes(self) -> None:
async def async_update_usercodes(
self, states: dict[str, dict[str, str]] | None = None
) -> None:
"""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
)
)
)
for lock in self.locks:
lock_slot_sensor_entity_id = self.ent_reg.async_get_entity_id(
SENSOR_DOMAIN,
Expand Down Expand Up @@ -139,11 +162,15 @@ async def async_update_usercodes(self) -> None:
continue

_LOGGER.info(
"%s (%s): Clearing usercode for lock %s slot %s",
(
"%s (%s): Clearing usercode for lock %s slot %s because the "
"following entities indicate the slot is disabled: %s"
),
self.config_entry.entry_id,
self.config_entry.title,
lock.lock.entity_id,
self.slot_num,
", ".join(disabling_entity_ids),
)

await lock.async_clear_usercode(int(self.slot_num))
Expand Down Expand Up @@ -172,7 +199,7 @@ async def _update_state(self, _: datetime | None = None) -> None:
):
entity_id_map[CONF_CALENDAR] = calendar_entity_id

states = {}
states: dict[str, dict[str, str]] = {}
for key, entity_id in entity_id_map.items():
if key in (EVENT_PIN_USED, CONF_NAME, CONF_PIN):
continue
Expand All @@ -194,15 +221,19 @@ async def _update_state(self, _: datetime | None = None) -> None:
continue
else:
ir.async_delete_issue(self.hass, DOMAIN, issue_id)
states[key] = state.state
states[key] = {"entity_id": entity_id, "state": state.state}

# For the binary sensor to be on, all states must be 'on', or for the number
# of uses, greater than 0
self._attr_is_on = bool(
states
and all(
(key != CONF_NUMBER_OF_USES and state == STATE_ON)
or (key == CONF_NUMBER_OF_USES and int(float(state)) > 0)
(key != CONF_NUMBER_OF_USES and state["state"] == STATE_ON)
or (
key == CONF_NUMBER_OF_USES
and state["state"] not in (STATE_UNAVAILABLE, STATE_UNKNOWN)
and int(float(state["state"])) > 0
)
for key, state in states.items()
)
)
Expand All @@ -211,7 +242,7 @@ async def _update_state(self, _: datetime | None = None) -> None:
state := self.hass.states.get(self.entity_id)
) or state.state != self.state:
try:
await self.async_update_usercodes()
await self.async_update_usercodes(states)
except EntityNotFoundError:
self._call_later_unsub = async_call_later(
self.hass, timedelta(seconds=2), self._update_state
Expand Down

0 comments on commit ad77169

Please sign in to comment.