mirror of
https://github.com/Electric-Special/ha-core.git
synced 2026-03-21 06:05:26 +01:00
Reflect Verisure lock, alarm control panel and switch state immediately without cloud pull (#149479)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
This commit is contained in:
@@ -67,8 +67,13 @@ class VerisureAlarm(
|
||||
)
|
||||
LOGGER.debug("Verisure set arm state %s", state)
|
||||
result = None
|
||||
attempts = 0
|
||||
while result is None:
|
||||
await asyncio.sleep(0.5)
|
||||
if attempts == 30:
|
||||
break
|
||||
if attempts > 1:
|
||||
await asyncio.sleep(0.5)
|
||||
attempts += 1
|
||||
transaction = await self.hass.async_add_executor_job(
|
||||
self.coordinator.verisure.request,
|
||||
self.coordinator.verisure.poll_arm_state(
|
||||
@@ -81,8 +86,10 @@ class VerisureAlarm(
|
||||
.get("armStateChangePollResult", {})
|
||||
.get("result")
|
||||
)
|
||||
|
||||
await self.coordinator.async_refresh()
|
||||
LOGGER.debug("Result is %s", result)
|
||||
if result == "OK":
|
||||
self._attr_alarm_state = ALARM_STATE_TO_HA.get(state)
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def async_alarm_disarm(self, code: str | None = None) -> None:
|
||||
"""Send disarm command."""
|
||||
@@ -108,16 +115,20 @@ class VerisureAlarm(
|
||||
"ARMED_AWAY", self.coordinator.verisure.arm_away(code)
|
||||
)
|
||||
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
def _update_alarm_attributes(self) -> None:
|
||||
"""Update alarm state and changed by from coordinator data."""
|
||||
self._attr_alarm_state = ALARM_STATE_TO_HA.get(
|
||||
self.coordinator.data["alarm"]["statusType"]
|
||||
)
|
||||
self._attr_changed_by = self.coordinator.data["alarm"].get("name")
|
||||
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
self._update_alarm_attributes()
|
||||
super()._handle_coordinator_update()
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""When entity is added to hass."""
|
||||
await super().async_added_to_hass()
|
||||
self._handle_coordinator_update()
|
||||
self._update_alarm_attributes()
|
||||
|
||||
@@ -10,7 +10,7 @@ from verisure import Error as VerisureError
|
||||
from homeassistant.components.lock import LockEntity, LockState
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_CODE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
AddConfigEntryEntitiesCallback,
|
||||
@@ -70,7 +70,9 @@ class VerisureDoorlock(CoordinatorEntity[VerisureDataUpdateCoordinator], LockEnt
|
||||
self._attr_unique_id = serial_number
|
||||
|
||||
self.serial_number = serial_number
|
||||
self._state: str | None = None
|
||||
self._attr_is_locked = None
|
||||
self._attr_changed_by = None
|
||||
self._changed_method: str | None = None
|
||||
|
||||
@property
|
||||
def device_info(self) -> DeviceInfo:
|
||||
@@ -92,20 +94,6 @@ class VerisureDoorlock(CoordinatorEntity[VerisureDataUpdateCoordinator], LockEnt
|
||||
super().available and self.serial_number in self.coordinator.data["locks"]
|
||||
)
|
||||
|
||||
@property
|
||||
def changed_by(self) -> str | None:
|
||||
"""Last change triggered by."""
|
||||
return (
|
||||
self.coordinator.data["locks"][self.serial_number]
|
||||
.get("user", {})
|
||||
.get("name")
|
||||
)
|
||||
|
||||
@property
|
||||
def changed_method(self) -> str:
|
||||
"""Last change method."""
|
||||
return self.coordinator.data["locks"][self.serial_number]["lockMethod"]
|
||||
|
||||
@property
|
||||
def code_format(self) -> str:
|
||||
"""Return the configured code format."""
|
||||
@@ -115,16 +103,9 @@ class VerisureDoorlock(CoordinatorEntity[VerisureDataUpdateCoordinator], LockEnt
|
||||
return f"^\\d{{{digits}}}$"
|
||||
|
||||
@property
|
||||
def is_locked(self) -> bool:
|
||||
"""Return true if lock is locked."""
|
||||
return (
|
||||
self.coordinator.data["locks"][self.serial_number]["lockStatus"] == "LOCKED"
|
||||
)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, str]:
|
||||
def extra_state_attributes(self) -> dict[str, str | None]:
|
||||
"""Return the state attributes."""
|
||||
return {"method": self.changed_method}
|
||||
return {"method": self._changed_method}
|
||||
|
||||
async def async_unlock(self, **kwargs: Any) -> None:
|
||||
"""Send unlock command."""
|
||||
@@ -154,7 +135,7 @@ class VerisureDoorlock(CoordinatorEntity[VerisureDataUpdateCoordinator], LockEnt
|
||||
target_state = "LOCKED" if state == LockState.LOCKED else "UNLOCKED"
|
||||
lock_status = None
|
||||
attempts = 0
|
||||
while lock_status != "OK":
|
||||
while lock_status is None:
|
||||
if attempts == 30:
|
||||
break
|
||||
if attempts > 1:
|
||||
@@ -172,8 +153,10 @@ class VerisureDoorlock(CoordinatorEntity[VerisureDataUpdateCoordinator], LockEnt
|
||||
.get("doorLockStateChangePollResult", {})
|
||||
.get("result")
|
||||
)
|
||||
LOGGER.debug("Lock status is %s", lock_status)
|
||||
if lock_status == "OK":
|
||||
self._state = state
|
||||
self._attr_is_locked = state == LockState.LOCKED
|
||||
self.async_write_ha_state()
|
||||
|
||||
def disable_autolock(self) -> None:
|
||||
"""Disable autolock on a doorlock."""
|
||||
@@ -196,3 +179,21 @@ class VerisureDoorlock(CoordinatorEntity[VerisureDataUpdateCoordinator], LockEnt
|
||||
LOGGER.debug("Enabling autolock on %s", self.serial_number)
|
||||
except VerisureError as ex:
|
||||
LOGGER.error("Could not enable autolock, %s", ex)
|
||||
|
||||
def _update_lock_attributes(self) -> None:
|
||||
"""Update lock state, changed by, and method from coordinator data."""
|
||||
lock_data = self.coordinator.data["locks"][self.serial_number]
|
||||
self._attr_is_locked = lock_data["lockStatus"] == "LOCKED"
|
||||
self._attr_changed_by = lock_data.get("user", {}).get("name")
|
||||
self._changed_method = lock_data["lockMethod"]
|
||||
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
self._update_lock_attributes()
|
||||
super()._handle_coordinator_update()
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""When entity is added to hass."""
|
||||
await super().async_added_to_hass()
|
||||
self._update_lock_attributes()
|
||||
|
||||
@@ -99,4 +99,4 @@ class VerisureSmartplug(CoordinatorEntity[VerisureDataUpdateCoordinator], Switch
|
||||
)
|
||||
self._state = state
|
||||
self._change_timestamp = monotonic()
|
||||
await self.coordinator.async_request_refresh()
|
||||
self.async_write_ha_state()
|
||||
|
||||
Reference in New Issue
Block a user