Skip to content

Retry syncing lock after failure #123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions custom_components/lock_code_manager/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""Sensor for lock_code_manager."""
"""Binary sensor for lock_code_manager."""

from __future__ import annotations

import asyncio
from datetime import datetime
from datetime import datetime, timedelta
import logging

from homeassistant.components.binary_sensor import (
Expand Down Expand Up @@ -46,6 +46,7 @@
from .providers import BaseLock

_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=30)


async def async_setup_entry(
Expand Down Expand Up @@ -256,15 +257,10 @@
)
self._lock = asyncio.Lock()

key_name = ATTR_IN_SYNC.replace("_", " ")
self._attr_name: str | None = f"{super()._attr_name} {key_name}"

@property
def icon(self) -> str | None:
"""Return icon."""
if self.is_on:
return "mdi:sync"
return "mdi:sync-"
def should_poll(self) -> bool:
"""Return whether entity should poll."""
return True

@property
def available(self) -> bool:
Expand All @@ -273,6 +269,22 @@
int(self.slot_num) in self.coordinator.data
)

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)
):
_LOGGER.error(

Check warning on line 281 in custom_components/lock_code_manager/binary_sensor.py

View check run for this annotation

Codecov / codecov/patch

custom_components/lock_code_manager/binary_sensor.py#L281

Added line #L281 was not covered by tests
"Updating %s code slot %s because it is out of sync",
self.lock.lock.entity_id,
self.slot_num,
)
await self._update_state()

Check warning on line 286 in custom_components/lock_code_manager/binary_sensor.py

View check run for this annotation

Codecov / codecov/patch

custom_components/lock_code_manager/binary_sensor.py#L286

Added line #L286 was not covered by tests

def _get_entity_state(self, key: str) -> str | None:
"""Get entity state."""
if (state := self.hass.states.get(self._entity_id_map[key])) is None:
Expand Down Expand Up @@ -338,6 +350,8 @@
self.lock.lock.entity_id,
self.slot_num,
)
elif self._attr_is_on:
return
else:
self._attr_is_on = True
elif self._get_entity_state(ATTR_ACTIVE) == STATE_OFF:
Expand All @@ -352,6 +366,8 @@
self.lock.lock.entity_id,
self.slot_num,
)
elif self._attr_is_on:
return

Check warning on line 370 in custom_components/lock_code_manager/binary_sensor.py

View check run for this annotation

Codecov / codecov/patch

custom_components/lock_code_manager/binary_sensor.py#L369-L370

Added lines #L369 - L370 were not covered by tests
else:
self._attr_is_on = True

Expand Down
9 changes: 2 additions & 7 deletions custom_components/lock_code_manager/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,8 @@ def __init__(
self._uid_cache: dict[str, str] = {}
self._unsub_initial_state: CALLBACK_TYPE | None = None

key_parts = key.lower().split("_")
try:
key_parts[key_parts.index("pin")] = "PIN"
except ValueError:
pass
self._attr_translation_key = key
self._attr_translation_placeholders = {"slot_num": slot_num}

self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, f"{self.entry_id}|{slot_num}")},
Expand All @@ -83,7 +80,6 @@ def __init__(
via_device=(DOMAIN, self.entry_id),
)

self._attr_name: str | None = " ".join(key_parts)
self._attr_unique_id = f"{self.base_unique_id}|{slot_num}|{key}"
self._attr_extra_state_attributes: dict[str, int | list[str]] = {
ATTR_CODE_SLOT: int(slot_num)
Expand Down Expand Up @@ -370,7 +366,6 @@ def __init__(
connections=lock.device_entry.connections,
identifiers=lock.device_entry.identifiers,
)
self._attr_name = f"Code slot {slot_num}"

self._attr_unique_id = (
f"{self.base_unique_id}|{slot_num}|{self.key}|{lock.lock.entity_id}"
Expand Down
1 change: 0 additions & 1 deletion custom_components/lock_code_manager/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ class LockCodeManagerCodeSlotEventEntity(BaseLockCodeManagerEntity, EventEntity)

_attr_entity_category = None
_attr_event_types = [EVENT_PIN_USED]
_attr_icon = "mdi:gesture-tap"
_attr_translation_key = EVENT_PIN_USED

def __init__(
Expand Down
34 changes: 34 additions & 0 deletions custom_components/lock_code_manager/icons.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"entity": {
"binary_sensor": {
"in_sync": {
"default": "mdi:sync-alert",
"state": {
"off": "mdi:sync-off",
"on": "mdi:sync"
}
}
},
"event": {
"pin_used": {
"default": "mdi:gesture-tap"
}
},
"sensor": {
"code": {
"default": "mdi:lock-smart"
}
},
"text": {
"name": {
"default": "mdi:rename"
},
"pin": {
"default": "mdi:form-textbox-password"
}
}
},
"services": {
"hard_refresh_usercodes": "mdi:refresh"
}
}
1 change: 0 additions & 1 deletion custom_components/lock_code_manager/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ class LockCodeManagerCodeSlotSensorEntity(
"""Code slot sensor entity for lock code manager."""

_attr_entity_category = EntityCategory.DIAGNOSTIC
_attr_icon = "mdi:lock-smart"

def __init__(
self,
Expand Down
6 changes: 0 additions & 6 deletions custom_components/lock_code_manager/services.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
---
hard_refresh_usercodes:
name: Hard Refresh Usercodes
description: >
If Lock Code Manager supports the lock's integration, and the lock's
integration supports it, this will query the lock for all usercodes. This
is potentially useful for integrations that cache data from the lock and a
usercode(s) is configured outside of Home Assistant.
target:
entity:
domain: lock
34 changes: 34 additions & 0 deletions custom_components/lock_code_manager/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@
}
},
"entity": {
"binary_sensor": {
"active": {
"name": "active"
},
"in_sync": {
"name": "Code slot {slot_num} in sync"
}
},
"event": {
"pin_used": {
"state_attributes": {
Expand All @@ -72,6 +80,32 @@
}
}
}
},
"number": {
"number_of_uses": {
"name": "number of uses"

}
},
"sensor": {
"code": {
"name": "Code slot {slot_num}"

}
},
"switch": {
"enabled": {
"name": "enabled"

}
},
"text": {
"name": {
"name": "name"
},
"pin": {
"name": "PIN"
}
}
},
"options": {
Expand Down
34 changes: 34 additions & 0 deletions custom_components/lock_code_manager/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@
}
},
"entity": {
"binary_sensor": {
"active": {
"name": "active"
},
"in_sync": {
"name": "Code slot {slot_num} in sync"
}
},
"event": {
"pin_used": {
"state_attributes": {
Expand All @@ -72,6 +80,32 @@
}
}
}
},
"number": {
"number_of_uses": {
"name": "number of uses"

}
},
"sensor": {
"code": {
"name": "Code slot {slot_num}"

}
},
"switch": {
"enabled": {
"name": "enabled"

}
},
"text": {
"name": {
"name": "name"
},
"pin": {
"name": "PIN"
}
}
},
"options": {
Expand Down

Large diffs are not rendered by default.

Loading