hass-core/homeassistant/components/loqed/coordinator.py
Mike Woudenberg ab50069918
Quality improvement on LOQED integration (#95725)
Remove generated translation
Raise error correctly
Remove obsolete consts
Remove callback, hass assignment and info log
Use name from LOQED API instead of default name
Correct entity name for assertion
2023-07-02 21:52:52 -04:00

151 lines
4.3 KiB
Python

"""Provides the coordinator for a LOQED lock."""
import logging
from typing import TypedDict
from aiohttp.web import Request
import async_timeout
from loqedAPI import loqed
from homeassistant.components import webhook
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_NAME, CONF_WEBHOOK_ID
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
class BatteryMessage(TypedDict):
"""Properties in a battery update message."""
mac_wifi: str
mac_ble: str
battery_type: str
battery_percentage: int
class StateReachedMessage(TypedDict):
"""Properties in a battery update message."""
requested_state: str
requested_state_numeric: int
event_type: str
key_local_id: int
mac_wifi: str
mac_ble: str
class TransitionMessage(TypedDict):
"""Properties in a battery update message."""
go_to_state: str
go_to_state_numeric: int
event_type: str
key_local_id: int
mac_wifi: str
mac_ble: str
class StatusMessage(TypedDict):
"""Properties returned by the status endpoint of the bridhge."""
battery_percentage: int
battery_type: str
battery_type_numeric: int
battery_voltage: float
bolt_state: str
bolt_state_numeric: int
bridge_mac_wifi: str
bridge_mac_ble: str
lock_online: int
webhooks_number: int
ip_address: str
up_timestamp: int
wifi_strength: int
ble_strength: int
class LoqedDataCoordinator(DataUpdateCoordinator[StatusMessage]):
"""Data update coordinator for the loqed platform."""
def __init__(
self,
hass: HomeAssistant,
api: loqed.LoqedAPI,
lock: loqed.Lock,
entry: ConfigEntry,
) -> None:
"""Initialize the Loqed Data Update coordinator."""
super().__init__(hass, _LOGGER, name="Loqed sensors")
self._api = api
self._entry = entry
self.lock = lock
self.device_name = self._entry.data[CONF_NAME]
async def _async_update_data(self) -> StatusMessage:
"""Fetch data from API endpoint."""
async with async_timeout.timeout(10):
return await self._api.async_get_lock_details()
async def _handle_webhook(
self, hass: HomeAssistant, webhook_id: str, request: Request
) -> None:
"""Handle incoming Loqed messages."""
_LOGGER.debug("Callback received: %s", request.headers)
received_ts = request.headers["TIMESTAMP"]
received_hash = request.headers["HASH"]
body = await request.text()
_LOGGER.debug("Callback body: %s", body)
event_data = await self.lock.receiveWebhook(body, received_hash, received_ts)
if "error" in event_data:
_LOGGER.warning("Incorrect callback received:: %s", event_data)
return
self.async_update_listeners()
async def ensure_webhooks(self) -> None:
"""Register webhook on LOQED bridge."""
webhook_id = self._entry.data[CONF_WEBHOOK_ID]
webhook.async_register(
self.hass, DOMAIN, "Loqed", webhook_id, self._handle_webhook
)
webhook_url = webhook.async_generate_url(self.hass, webhook_id)
_LOGGER.debug("Webhook URL: %s", webhook_url)
webhooks = await self.lock.getWebhooks()
webhook_index = next(
(x["id"] for x in webhooks if x["url"] == webhook_url), None
)
if not webhook_index:
await self.lock.registerWebhook(webhook_url)
webhooks = await self.lock.getWebhooks()
webhook_index = next(x["id"] for x in webhooks if x["url"] == webhook_url)
_LOGGER.info("Webhook got index %s", webhook_index)
async def remove_webhooks(self) -> None:
"""Remove webhook from LOQED bridge."""
webhook_id = self._entry.data[CONF_WEBHOOK_ID]
webhook_url = webhook.async_generate_url(self.hass, webhook_id)
webhook.async_unregister(
self.hass,
webhook_id,
)
_LOGGER.info("Webhook URL: %s", webhook_url)
webhooks = await self.lock.getWebhooks()
webhook_index = next(
(x["id"] for x in webhooks if x["url"] == webhook_url), None
)
if webhook_index:
await self.lock.deleteWebhook(webhook_index)