Skip to content

Commit

Permalink
Expose last lock/open user as a sensor (Web API)
Browse files Browse the repository at this point in the history
  • Loading branch information
kvj committed Aug 26, 2022
1 parent 7ab5cba commit a2e2da6
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
23 changes: 23 additions & 0 deletions custom_components/nuki_ng/nuki.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,25 @@ def can_web(self):
def can_bridge(self):
return True if self.token and self.bridge else False

async def web_get_last_unlock_log(self, dev_id: str):
actions_map = {
1: "unlock",
3: "unlatch",
5: "lock_n_go_unlatch",
}
response = await self.web_async_json(
lambda r, h: r.get(self.web_url(f"/smartlock/{dev_id}/log"), headers=h)
)
for item in response:
if item.get("action") in (1, 3, 5):
# unlock, unlatch, lock'n'go with unlatch
return {
"name": item.get("name"),
"action": actions_map[item["action"]],
"timestamp": item["date"].replace("Z", "+00:00"),
}
return dict()

async def web_list_all_auths(self, dev_id: str):
result = {}
response = await self.web_async_json(
Expand Down Expand Up @@ -375,6 +394,10 @@ async def _update(self):
item["web_auth"] = await self.api.web_list_all_auths(dev_id)
except ConnectionError:
_LOGGER.exception("Error while fetching auth:")
try:
item["last_log"] = await self.api.web_get_last_unlock_log(dev_id)
except ConnectionError:
_LOGGER.exception("Error while fetching last log entry")
if web_list:
item["config"] = web_list.get(dev_id, {}).get("config")
item["advancedConfig"] = web_list.get(dev_id, {}).get("advancedConfig")
Expand Down
30 changes: 30 additions & 0 deletions custom_components/nuki_ng/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from homeassistant.helpers.entity import EntityCategory

import logging
from datetime import datetime

from . import NukiEntity, NukiBridge
from .constants import DOMAIN
Expand All @@ -28,6 +29,9 @@ async def async_setup_entry(hass, entry, async_add_entities):
if coordinator.device_supports(dev_id, "doorsensorStateName"):
entities.append(DoorSensorState(coordinator, dev_id))
entities.append(DoorSecurityState(coordinator, dev_id))
if coordinator.info_field(dev_id, None, "last_log"):
entities.append(LastUnlockUser(coordinator, dev_id))

async_add_entities(entities)
return True

Expand Down Expand Up @@ -194,3 +198,29 @@ def state(self):
@property
def entity_category(self):
return EntityCategory.DIAGNOSTIC


class LastUnlockUser(NukiEntity, SensorEntity):

def __init__(self, coordinator, device_id):
super().__init__(coordinator, device_id)
self.set_id("sensor", "last_unlock_user")
self.set_name("Last Unlock user")
self._attr_icon = "mdi:account-lock-open"

@property
def state(self):
return self.coordinator.info_field(self.device_id, "Unknown", "last_log", "name")

@property
def extra_state_attributes(self):
timestamp = self.coordinator.info_field(self.device_id, None, "last_log", "timestamp")
action = self.coordinator.info_field(self.device_id, "unknown", "last_log", "action")
return {
"timestamp": datetime.fromisoformat(timestamp) if not None else None,
"action": action,
}

@property
def entity_category(self):
return EntityCategory.DIAGNOSTIC

0 comments on commit a2e2da6

Please sign in to comment.