Use runtime_data in guardian (#144344)

* Use runtime_data in guardian

* Adjust tests
This commit is contained in:
epenet 2025-05-06 16:16:16 +02:00 committed by GitHub
parent 32a6b8a0f8
commit 1447392847
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 53 additions and 63 deletions

View File

@ -40,12 +40,14 @@ PLATFORMS = [
Platform.VALVE, Platform.VALVE,
] ]
type GuardianConfigEntry = ConfigEntry[GuardianData]
@dataclass @dataclass
class GuardianData: class GuardianData:
"""Define an object to be stored in `hass.data`.""" """Define an object to be stored in `entry.runtime_data`."""
entry: ConfigEntry entry: GuardianConfigEntry
client: Client client: Client
valve_controller_coordinators: dict[str, GuardianDataUpdateCoordinator] valve_controller_coordinators: dict[str, GuardianDataUpdateCoordinator]
paired_sensor_manager: PairedSensorManager paired_sensor_manager: PairedSensorManager
@ -57,7 +59,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
return True return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: GuardianConfigEntry) -> bool:
"""Set up Elexa Guardian from a config entry.""" """Set up Elexa Guardian from a config entry."""
client = Client(entry.data[CONF_IP_ADDRESS], port=entry.data[CONF_PORT]) client = Client(entry.data[CONF_IP_ADDRESS], port=entry.data[CONF_PORT])
@ -108,8 +110,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
) )
await paired_sensor_manager.async_initialize() await paired_sensor_manager.async_initialize()
hass.data.setdefault(DOMAIN, {}) entry.runtime_data = GuardianData(
hass.data[DOMAIN][entry.entry_id] = GuardianData(
entry=entry, entry=entry,
client=client, client=client,
valve_controller_coordinators=valve_controller_coordinators, valve_controller_coordinators=valve_controller_coordinators,
@ -122,13 +123,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_unload_entry(hass: HomeAssistant, entry: GuardianConfigEntry) -> bool:
"""Unload a config entry.""" """Unload a config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
class PairedSensorManager: class PairedSensorManager:
@ -137,7 +134,7 @@ class PairedSensorManager:
def __init__( def __init__(
self, self,
hass: HomeAssistant, hass: HomeAssistant,
entry: ConfigEntry, entry: GuardianConfigEntry,
client: Client, client: Client,
api_lock: asyncio.Lock, api_lock: asyncio.Lock,
sensor_pair_dump_coordinator: GuardianDataUpdateCoordinator, sensor_pair_dump_coordinator: GuardianDataUpdateCoordinator,

View File

@ -12,17 +12,15 @@ from homeassistant.components.binary_sensor import (
BinarySensorEntity, BinarySensorEntity,
BinarySensorEntityDescription, BinarySensorEntityDescription,
) )
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import GuardianData from . import GuardianConfigEntry
from .const import ( from .const import (
API_SYSTEM_ONBOARD_SENSOR_STATUS, API_SYSTEM_ONBOARD_SENSOR_STATUS,
CONF_UID, CONF_UID,
DOMAIN,
SIGNAL_PAIRED_SENSOR_COORDINATOR_ADDED, SIGNAL_PAIRED_SENSOR_COORDINATOR_ADDED,
) )
from .coordinator import GuardianDataUpdateCoordinator from .coordinator import GuardianDataUpdateCoordinator
@ -87,11 +85,11 @@ VALVE_CONTROLLER_DESCRIPTIONS = (
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
entry: ConfigEntry, entry: GuardianConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Guardian switches based on a config entry.""" """Set up Guardian switches based on a config entry."""
data: GuardianData = hass.data[DOMAIN][entry.entry_id] data = entry.runtime_data
uid = entry.data[CONF_UID] uid = entry.data[CONF_UID]
async_finish_entity_domain_replacements( async_finish_entity_domain_replacements(
@ -151,7 +149,7 @@ class PairedSensorBinarySensor(PairedSensorEntity, BinarySensorEntity):
def __init__( def __init__(
self, self,
entry: ConfigEntry, entry: GuardianConfigEntry,
coordinator: GuardianDataUpdateCoordinator, coordinator: GuardianDataUpdateCoordinator,
description: BinarySensorEntityDescription, description: BinarySensorEntityDescription,
) -> None: ) -> None:
@ -173,7 +171,7 @@ class ValveControllerBinarySensor(ValveControllerEntity, BinarySensorEntity):
def __init__( def __init__(
self, self,
entry: ConfigEntry, entry: GuardianConfigEntry,
coordinators: dict[str, GuardianDataUpdateCoordinator], coordinators: dict[str, GuardianDataUpdateCoordinator],
description: ValveControllerBinarySensorDescription, description: ValveControllerBinarySensorDescription,
) -> None: ) -> None:

View File

@ -12,14 +12,13 @@ from homeassistant.components.button import (
ButtonEntity, ButtonEntity,
ButtonEntityDescription, ButtonEntityDescription,
) )
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import GuardianData from . import GuardianConfigEntry, GuardianData
from .const import API_SYSTEM_DIAGNOSTICS, DOMAIN from .const import API_SYSTEM_DIAGNOSTICS
from .entity import ValveControllerEntity, ValveControllerEntityDescription from .entity import ValveControllerEntity, ValveControllerEntityDescription
from .util import convert_exceptions_to_homeassistant_error from .util import convert_exceptions_to_homeassistant_error
@ -69,11 +68,11 @@ BUTTON_DESCRIPTIONS = (
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
entry: ConfigEntry, entry: GuardianConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Guardian buttons based on a config entry.""" """Set up Guardian buttons based on a config entry."""
data: GuardianData = hass.data[DOMAIN][entry.entry_id] data = entry.runtime_data
async_add_entities( async_add_entities(
GuardianButton(entry, data, description) for description in BUTTON_DESCRIPTIONS GuardianButton(entry, data, description) for description in BUTTON_DESCRIPTIONS
@ -90,7 +89,7 @@ class GuardianButton(ValveControllerEntity, ButtonEntity):
def __init__( def __init__(
self, self,
entry: ConfigEntry, entry: GuardianConfigEntry,
data: GuardianData, data: GuardianData,
description: ValveControllerButtonDescription, description: ValveControllerButtonDescription,
) -> None: ) -> None:

View File

@ -5,18 +5,20 @@ from __future__ import annotations
import asyncio import asyncio
from collections.abc import Callable, Coroutine from collections.abc import Callable, Coroutine
from datetime import timedelta from datetime import timedelta
from typing import Any, cast from typing import TYPE_CHECKING, Any, cast
from aioguardian import Client from aioguardian import Client
from aioguardian.errors import GuardianError from aioguardian.errors import GuardianError
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import LOGGER from .const import LOGGER
if TYPE_CHECKING:
from . import GuardianConfigEntry
DEFAULT_UPDATE_INTERVAL = timedelta(seconds=30) DEFAULT_UPDATE_INTERVAL = timedelta(seconds=30)
SIGNAL_REBOOT_REQUESTED = "guardian_reboot_requested_{0}" SIGNAL_REBOOT_REQUESTED = "guardian_reboot_requested_{0}"
@ -25,13 +27,13 @@ SIGNAL_REBOOT_REQUESTED = "guardian_reboot_requested_{0}"
class GuardianDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): class GuardianDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
"""Define an extended DataUpdateCoordinator with some Guardian goodies.""" """Define an extended DataUpdateCoordinator with some Guardian goodies."""
config_entry: ConfigEntry config_entry: GuardianConfigEntry
def __init__( def __init__(
self, self,
hass: HomeAssistant, hass: HomeAssistant,
*, *,
entry: ConfigEntry, entry: GuardianConfigEntry,
client: Client, client: Client,
api_name: str, api_name: str,
api_coro: Callable[[], Coroutine[Any, Any, dict[str, Any]]], api_coro: Callable[[], Coroutine[Any, Any, dict[str, Any]]],

View File

@ -5,12 +5,11 @@ from __future__ import annotations
from typing import Any from typing import Any
from homeassistant.components.diagnostics import async_redact_data from homeassistant.components.diagnostics import async_redact_data
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_UNIQUE_ID from homeassistant.const import CONF_UNIQUE_ID
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from . import GuardianData from . import GuardianConfigEntry
from .const import CONF_UID, DOMAIN from .const import CONF_UID
CONF_BSSID = "bssid" CONF_BSSID = "bssid"
CONF_PAIRED_UIDS = "paired_uids" CONF_PAIRED_UIDS = "paired_uids"
@ -29,10 +28,10 @@ TO_REDACT = {
async def async_get_config_entry_diagnostics( async def async_get_config_entry_diagnostics(
hass: HomeAssistant, entry: ConfigEntry hass: HomeAssistant, entry: GuardianConfigEntry
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Return diagnostics for a config entry.""" """Return diagnostics for a config entry."""
data: GuardianData = hass.data[DOMAIN][entry.entry_id] data = entry.runtime_data
return { return {
"entry": async_redact_data(entry.as_dict(), TO_REDACT), "entry": async_redact_data(entry.as_dict(), TO_REDACT),

View File

@ -4,11 +4,11 @@ from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import EntityDescription from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import GuardianConfigEntry
from .const import API_SYSTEM_DIAGNOSTICS, CONF_UID, DOMAIN from .const import API_SYSTEM_DIAGNOSTICS, CONF_UID, DOMAIN
from .coordinator import GuardianDataUpdateCoordinator from .coordinator import GuardianDataUpdateCoordinator
@ -32,7 +32,7 @@ class PairedSensorEntity(GuardianEntity):
def __init__( def __init__(
self, self,
entry: ConfigEntry, entry: GuardianConfigEntry,
coordinator: GuardianDataUpdateCoordinator, coordinator: GuardianDataUpdateCoordinator,
description: EntityDescription, description: EntityDescription,
) -> None: ) -> None:
@ -62,7 +62,7 @@ class ValveControllerEntity(GuardianEntity):
def __init__( def __init__(
self, self,
entry: ConfigEntry, entry: GuardianConfigEntry,
coordinators: dict[str, GuardianDataUpdateCoordinator], coordinators: dict[str, GuardianDataUpdateCoordinator],
description: ValveControllerEntityDescription, description: ValveControllerEntityDescription,
) -> None: ) -> None:

View File

@ -12,7 +12,6 @@ from homeassistant.components.sensor import (
SensorEntityDescription, SensorEntityDescription,
SensorStateClass, SensorStateClass,
) )
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
EntityCategory, EntityCategory,
UnitOfElectricCurrent, UnitOfElectricCurrent,
@ -25,13 +24,12 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.typing import StateType from homeassistant.helpers.typing import StateType
from . import GuardianData from . import GuardianConfigEntry
from .const import ( from .const import (
API_SYSTEM_DIAGNOSTICS, API_SYSTEM_DIAGNOSTICS,
API_SYSTEM_ONBOARD_SENSOR_STATUS, API_SYSTEM_ONBOARD_SENSOR_STATUS,
API_VALVE_STATUS, API_VALVE_STATUS,
CONF_UID, CONF_UID,
DOMAIN,
SIGNAL_PAIRED_SENSOR_COORDINATOR_ADDED, SIGNAL_PAIRED_SENSOR_COORDINATOR_ADDED,
) )
from .entity import ( from .entity import (
@ -138,11 +136,11 @@ VALVE_CONTROLLER_DESCRIPTIONS = (
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
entry: ConfigEntry, entry: GuardianConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Guardian switches based on a config entry.""" """Set up Guardian switches based on a config entry."""
data: GuardianData = hass.data[DOMAIN][entry.entry_id] data = entry.runtime_data
@callback @callback
def add_new_paired_sensor(uid: str) -> None: def add_new_paired_sensor(uid: str) -> None:

View File

@ -22,7 +22,7 @@ from homeassistant.helpers import config_validation as cv, device_registry as dr
from .const import CONF_UID, DOMAIN from .const import CONF_UID, DOMAIN
if TYPE_CHECKING: if TYPE_CHECKING:
from . import GuardianData from . import GuardianConfigEntry, GuardianData
SERVICE_NAME_PAIR_SENSOR = "pair_sensor" SERVICE_NAME_PAIR_SENSOR = "pair_sensor"
SERVICE_NAME_UNPAIR_SENSOR = "unpair_sensor" SERVICE_NAME_UNPAIR_SENSOR = "unpair_sensor"
@ -58,7 +58,7 @@ SERVICE_UPGRADE_FIRMWARE_SCHEMA = vol.Schema(
@callback @callback
def async_get_entry_id_for_service_call(call: ServiceCall) -> str: def async_get_entry_id_for_service_call(call: ServiceCall) -> GuardianConfigEntry:
"""Get the entry ID related to a service call (by device ID).""" """Get the entry ID related to a service call (by device ID)."""
device_id = call.data[CONF_DEVICE_ID] device_id = call.data[CONF_DEVICE_ID]
device_registry = dr.async_get(call.hass) device_registry = dr.async_get(call.hass)
@ -70,7 +70,7 @@ def async_get_entry_id_for_service_call(call: ServiceCall) -> str:
if (entry := call.hass.config_entries.async_get_entry(entry_id)) is None: if (entry := call.hass.config_entries.async_get_entry(entry_id)) is None:
continue continue
if entry.domain == DOMAIN: if entry.domain == DOMAIN:
return entry_id return entry
raise ValueError(f"No config entry for device ID: {device_id}") raise ValueError(f"No config entry for device ID: {device_id}")
@ -83,8 +83,7 @@ def call_with_data(
async def wrapper(call: ServiceCall) -> None: async def wrapper(call: ServiceCall) -> None:
"""Wrap the service function.""" """Wrap the service function."""
entry_id = async_get_entry_id_for_service_call(call) data = async_get_entry_id_for_service_call(call).runtime_data
data = call.hass.data[DOMAIN][entry_id]
try: try:
async with data.client: async with data.client:

View File

@ -9,13 +9,12 @@ from typing import Any
from aioguardian import Client from aioguardian import Client
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import GuardianData from . import GuardianConfigEntry, GuardianData
from .const import API_VALVE_STATUS, API_WIFI_STATUS, DOMAIN from .const import API_VALVE_STATUS, API_WIFI_STATUS
from .entity import ValveControllerEntity, ValveControllerEntityDescription from .entity import ValveControllerEntity, ValveControllerEntityDescription
from .util import convert_exceptions_to_homeassistant_error from .util import convert_exceptions_to_homeassistant_error
from .valve import GuardianValveState from .valve import GuardianValveState
@ -111,11 +110,11 @@ VALVE_CONTROLLER_DESCRIPTIONS = (
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
entry: ConfigEntry, entry: GuardianConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Guardian switches based on a config entry.""" """Set up Guardian switches based on a config entry."""
data: GuardianData = hass.data[DOMAIN][entry.entry_id] data = entry.runtime_data
async_add_entities( async_add_entities(
ValveControllerSwitch(entry, data, description) ValveControllerSwitch(entry, data, description)
@ -130,7 +129,7 @@ class ValveControllerSwitch(ValveControllerEntity, SwitchEntity):
def __init__( def __init__(
self, self,
entry: ConfigEntry, entry: GuardianConfigEntry,
data: GuardianData, data: GuardianData,
description: ValveControllerSwitchDescription, description: ValveControllerSwitchDescription,
) -> None: ) -> None:

View File

@ -10,7 +10,6 @@ from typing import TYPE_CHECKING, Any, Concatenate
from aioguardian.errors import GuardianError from aioguardian.errors import GuardianError
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er from homeassistant.helpers import entity_registry as er
@ -18,6 +17,7 @@ from homeassistant.helpers import entity_registry as er
from .const import LOGGER from .const import LOGGER
if TYPE_CHECKING: if TYPE_CHECKING:
from . import GuardianConfigEntry
from .entity import GuardianEntity from .entity import GuardianEntity
DEFAULT_UPDATE_INTERVAL = timedelta(seconds=30) DEFAULT_UPDATE_INTERVAL = timedelta(seconds=30)
@ -36,7 +36,7 @@ class EntityDomainReplacementStrategy:
@callback @callback
def async_finish_entity_domain_replacements( def async_finish_entity_domain_replacements(
hass: HomeAssistant, hass: HomeAssistant,
entry: ConfigEntry, entry: GuardianConfigEntry,
entity_replacement_strategies: Iterable[EntityDomainReplacementStrategy], entity_replacement_strategies: Iterable[EntityDomainReplacementStrategy],
) -> None: ) -> None:
"""Remove old entities and create a repairs issue with info on their replacement.""" """Remove old entities and create a repairs issue with info on their replacement."""

View File

@ -15,12 +15,11 @@ from homeassistant.components.valve import (
ValveEntityDescription, ValveEntityDescription,
ValveEntityFeature, ValveEntityFeature,
) )
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import GuardianData from . import GuardianConfigEntry, GuardianData
from .const import API_VALVE_STATUS, DOMAIN from .const import API_VALVE_STATUS
from .entity import ValveControllerEntity, ValveControllerEntityDescription from .entity import ValveControllerEntity, ValveControllerEntityDescription
from .util import convert_exceptions_to_homeassistant_error from .util import convert_exceptions_to_homeassistant_error
@ -110,11 +109,11 @@ VALVE_CONTROLLER_DESCRIPTIONS = (
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
entry: ConfigEntry, entry: GuardianConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up Guardian switches based on a config entry.""" """Set up Guardian switches based on a config entry."""
data: GuardianData = hass.data[DOMAIN][entry.entry_id] data = entry.runtime_data
async_add_entities( async_add_entities(
ValveControllerValve(entry, data, description) ValveControllerValve(entry, data, description)
@ -132,7 +131,7 @@ class ValveControllerValve(ValveControllerEntity, ValveEntity):
def __init__( def __init__(
self, self,
entry: ConfigEntry, entry: GuardianConfigEntry,
data: GuardianData, data: GuardianData,
description: ValveControllerValveDescription, description: ValveControllerValveDescription,
) -> None: ) -> None:

View File

@ -1,7 +1,7 @@
"""Test Guardian diagnostics.""" """Test Guardian diagnostics."""
from homeassistant.components.diagnostics import REDACTED from homeassistant.components.diagnostics import REDACTED
from homeassistant.components.guardian import DOMAIN, GuardianData from homeassistant.components.guardian import GuardianData
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from tests.common import ANY, MockConfigEntry from tests.common import ANY, MockConfigEntry
@ -16,7 +16,7 @@ async def test_entry_diagnostics(
setup_guardian: None, # relies on config_entry fixture setup_guardian: None, # relies on config_entry fixture
) -> None: ) -> None:
"""Test config entry diagnostics.""" """Test config entry diagnostics."""
data: GuardianData = hass.data[DOMAIN][config_entry.entry_id] data: GuardianData = config_entry.runtime_data
# Simulate the pairing of a paired sensor: # Simulate the pairing of a paired sensor:
await data.paired_sensor_manager.async_pair_sensor("AABBCCDDEEFF") await data.paired_sensor_manager.async_pair_sensor("AABBCCDDEEFF")