1
0
mirror of https://github.com/home-assistant/core.git synced 2026-04-02 00:20:30 +01:00

Migrate nuki to use runtime_data (#166943)

This commit is contained in:
epenet
2026-03-31 13:55:19 +02:00
committed by GitHub
parent cb8597d62f
commit 7b9b457f15
5 changed files with 35 additions and 48 deletions

View File

@@ -3,7 +3,6 @@
from __future__ import annotations
import asyncio
from dataclasses import dataclass
from http import HTTPStatus
import logging
@@ -14,7 +13,6 @@ from requests.exceptions import RequestException
from homeassistant import exceptions
from homeassistant.components import webhook
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_HOST,
CONF_PORT,
@@ -28,7 +26,7 @@ from homeassistant.helpers.network import NoURLAvailableError, get_url
from homeassistant.helpers.update_coordinator import UpdateFailed
from .const import CONF_ENCRYPT_TOKEN, DEFAULT_TIMEOUT, DOMAIN
from .coordinator import NukiCoordinator
from .coordinator import NukiConfigEntry, NukiCoordinator, NukiEntryData
from .helpers import NukiWebhookException, parse_id
_LOGGER = logging.getLogger(__name__)
@@ -36,22 +34,12 @@ _LOGGER = logging.getLogger(__name__)
PLATFORMS = [Platform.BINARY_SENSOR, Platform.LOCK, Platform.SENSOR]
@dataclass(slots=True)
class NukiEntryData:
"""Class to hold Nuki data."""
coordinator: NukiCoordinator
bridge: NukiBridge
locks: list[NukiLock]
openers: list[NukiOpener]
def _get_bridge_devices(bridge: NukiBridge) -> tuple[list[NukiLock], list[NukiOpener]]:
return bridge.locks, bridge.openers
async def _create_webhook(
hass: HomeAssistant, entry: ConfigEntry, bridge: NukiBridge
hass: HomeAssistant, entry: NukiConfigEntry, bridge: NukiBridge
) -> None:
# Create HomeAssistant webhook
async def handle_webhook(
@@ -63,16 +51,14 @@ async def _create_webhook(
except ValueError:
return web.Response(status=HTTPStatus.BAD_REQUEST)
entry_data: NukiEntryData = hass.data[DOMAIN][entry.entry_id]
locks = entry_data.locks
openers = entry_data.openers
locks = entry.runtime_data.locks
openers = entry.runtime_data.openers
devices = [x for x in locks + openers if x.nuki_id == data["nukiId"]]
if len(devices) == 1:
devices[0].update_from_callback(data)
coordinator = entry_data.coordinator
coordinator.async_set_updated_data(None)
entry.runtime_data.coordinator.async_set_updated_data(None)
return web.Response(status=HTTPStatus.OK)
@@ -157,11 +143,9 @@ def _remove_webhook(bridge: NukiBridge, entry_id: str) -> None:
bridge.callback_remove(item["id"])
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_setup_entry(hass: HomeAssistant, entry: NukiConfigEntry) -> bool:
"""Set up the Nuki entry."""
hass.data.setdefault(DOMAIN, {})
# Migration of entry unique_id
if isinstance(entry.unique_id, int):
new_id = parse_id(entry.unique_id)
@@ -225,7 +209,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
)
coordinator = NukiCoordinator(hass, entry, bridge, locks, openers)
hass.data[DOMAIN][entry.entry_id] = NukiEntryData(
entry.runtime_data = NukiEntryData(
coordinator=coordinator,
bridge=bridge,
locks=locks,
@@ -240,16 +224,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: NukiConfigEntry) -> bool:
"""Unload the Nuki entry."""
webhook.async_unregister(hass, entry.entry_id)
entry_data: NukiEntryData = hass.data[DOMAIN][entry.entry_id]
try:
async with asyncio.timeout(10):
await hass.async_add_executor_job(
_remove_webhook,
entry_data.bridge,
entry.runtime_data.bridge,
entry.entry_id,
)
except InvalidCredentialsException as err:
@@ -261,8 +244,4 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
f"Unable to remove callback. Error communicating with Bridge: {err}"
) from err
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

View File

@@ -9,23 +9,21 @@ from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import NukiEntryData
from .const import DOMAIN
from .coordinator import NukiConfigEntry
from .entity import NukiEntity
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: NukiConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Nuki binary sensors."""
entry_data: NukiEntryData = hass.data[DOMAIN][entry.entry_id]
entry_data = entry.runtime_data
entities: list[NukiEntity] = []

View File

@@ -4,6 +4,7 @@ from __future__ import annotations
import asyncio
from collections import defaultdict
from dataclasses import dataclass
from datetime import timedelta
import logging
@@ -25,16 +26,28 @@ _LOGGER = logging.getLogger(__name__)
UPDATE_INTERVAL = timedelta(seconds=30)
type NukiConfigEntry = ConfigEntry[NukiEntryData]
@dataclass(slots=True)
class NukiEntryData:
"""Class to hold Nuki data."""
coordinator: NukiCoordinator
bridge: NukiBridge
locks: list[NukiLock]
openers: list[NukiOpener]
class NukiCoordinator(DataUpdateCoordinator[None]):
"""Data Update Coordinator for the Nuki integration."""
config_entry: ConfigEntry
config_entry: NukiConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: ConfigEntry,
config_entry: NukiConfigEntry,
bridge: NukiBridge,
locks: list[NukiLock],
openers: list[NukiOpener],

View File

@@ -12,24 +12,23 @@ from requests.exceptions import RequestException
import voluptuous as vol
from homeassistant.components.lock import LockEntity, LockEntityFeature
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import NukiEntryData
from .const import ATTR_ENABLE, ATTR_UNLATCH, DOMAIN, ERROR_STATES
from .const import ATTR_ENABLE, ATTR_UNLATCH, ERROR_STATES
from .coordinator import NukiConfigEntry
from .entity import NukiEntity
from .helpers import CannotConnect
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: NukiConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Nuki lock platform."""
entry_data: NukiEntryData = hass.data[DOMAIN][entry.entry_id]
entry_data = entry.runtime_data
coordinator = entry_data.coordinator
entities: list[NukiDeviceEntity] = [

View File

@@ -9,23 +9,21 @@ from homeassistant.components.sensor import (
SensorEntity,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PERCENTAGE, EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import NukiEntryData
from .const import DOMAIN
from .coordinator import NukiConfigEntry
from .entity import NukiEntity
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: NukiConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Nuki lock sensor."""
entry_data: NukiEntryData = hass.data[DOMAIN][entry.entry_id]
entry_data = entry.runtime_data
async_add_entities(
NukiBatterySensor(entry_data.coordinator, lock) for lock in entry_data.locks