Implement runtime data for Plugwise (#117172)

This commit is contained in:
Bouwe Westerdijk 2024-05-13 09:38:06 +02:00 committed by GitHub
parent d0c60ab21b
commit 84cc650bb3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 50 additions and 53 deletions

View file

@ -12,16 +12,18 @@ from homeassistant.helpers import device_registry as dr, entity_registry as er
from .const import DOMAIN, LOGGER, PLATFORMS from .const import DOMAIN, LOGGER, PLATFORMS
from .coordinator import PlugwiseDataUpdateCoordinator from .coordinator import PlugwiseDataUpdateCoordinator
PlugwiseConfigEntry = ConfigEntry[PlugwiseDataUpdateCoordinator]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_setup_entry(hass: HomeAssistant, entry: PlugwiseConfigEntry) -> bool:
"""Set up Plugwise components from a config entry.""" """Set up Plugwise components from a config entry."""
await er.async_migrate_entries(hass, entry.entry_id, async_migrate_entity_entry) await er.async_migrate_entries(hass, entry.entry_id, async_migrate_entity_entry)
coordinator = PlugwiseDataUpdateCoordinator(hass, entry) coordinator = PlugwiseDataUpdateCoordinator(hass)
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
migrate_sensor_entities(hass, coordinator) migrate_sensor_entities(hass, coordinator)
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator entry.runtime_data = coordinator
device_registry = dr.async_get(hass) device_registry = dr.async_get(hass)
device_registry.async_get_or_create( device_registry.async_get_or_create(
@ -38,11 +40,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: PlugwiseConfigEntry) -> bool:
"""Unload the Plugwise components.""" """Unload the Plugwise components."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
@callback @callback
@ -59,6 +59,12 @@ def async_migrate_entity_entry(entry: er.RegistryEntry) -> dict[str, Any] | None
"-slave_boiler_state", "-secondary_boiler_state" "-slave_boiler_state", "-secondary_boiler_state"
) )
} }
if entry.domain == Platform.SENSOR and entry.unique_id.endswith(
"-relative_humidity"
):
return {
"new_unique_id": entry.unique_id.replace("-relative_humidity", "-humidity")
}
if entry.domain == Platform.SWITCH and entry.unique_id.endswith("-plug"): if entry.domain == Platform.SWITCH and entry.unique_id.endswith("-plug"):
return {"new_unique_id": entry.unique_id.replace("-plug", "-relay")} return {"new_unique_id": entry.unique_id.replace("-plug", "-relay")}

View file

@ -12,12 +12,11 @@ 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 from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN from . import PlugwiseConfigEntry
from .coordinator import PlugwiseDataUpdateCoordinator from .coordinator import PlugwiseDataUpdateCoordinator
from .entity import PlugwiseEntity from .entity import PlugwiseEntity
@ -78,13 +77,11 @@ BINARY_SENSORS: tuple[PlugwiseBinarySensorEntityDescription, ...] = (
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: ConfigEntry, entry: PlugwiseConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up the Smile binary_sensors from a config entry.""" """Set up the Smile binary_sensors from a config entry."""
coordinator: PlugwiseDataUpdateCoordinator = hass.data[DOMAIN][ coordinator = entry.runtime_data
config_entry.entry_id
]
entities: list[PlugwiseBinarySensorEntity] = [] entities: list[PlugwiseBinarySensorEntity] = []
for device_id, device in coordinator.data.devices.items(): for device_id, device in coordinator.data.devices.items():

View file

@ -13,12 +13,12 @@ from homeassistant.components.climate import (
HVACAction, HVACAction,
HVACMode, HVACMode,
) )
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import PlugwiseConfigEntry
from .const import DOMAIN, MASTER_THERMOSTATS from .const import DOMAIN, MASTER_THERMOSTATS
from .coordinator import PlugwiseDataUpdateCoordinator from .coordinator import PlugwiseDataUpdateCoordinator
from .entity import PlugwiseEntity from .entity import PlugwiseEntity
@ -27,11 +27,12 @@ from .util import plugwise_command
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: ConfigEntry, entry: PlugwiseConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up the Smile Thermostats from a config entry.""" """Set up the Smile Thermostats from a config entry."""
coordinator = hass.data[DOMAIN][config_entry.entry_id] coordinator = entry.runtime_data
async_add_entities( async_add_entities(
PlugwiseClimateEntity(coordinator, device_id) PlugwiseClimateEntity(coordinator, device_id)
for device_id, device in coordinator.data.devices.items() for device_id, device in coordinator.data.devices.items()

View file

@ -27,7 +27,9 @@ class PlugwiseDataUpdateCoordinator(DataUpdateCoordinator[PlugwiseData]):
_connected: bool = False _connected: bool = False
def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None: config_entry: ConfigEntry
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize the coordinator.""" """Initialize the coordinator."""
super().__init__( super().__init__(
hass, hass,
@ -45,10 +47,10 @@ class PlugwiseDataUpdateCoordinator(DataUpdateCoordinator[PlugwiseData]):
) )
self.api = Smile( self.api = Smile(
host=entry.data[CONF_HOST], host=self.config_entry.data[CONF_HOST],
username=entry.data.get(CONF_USERNAME, DEFAULT_USERNAME), username=self.config_entry.data.get(CONF_USERNAME, DEFAULT_USERNAME),
password=entry.data[CONF_PASSWORD], password=self.config_entry.data[CONF_PASSWORD],
port=entry.data.get(CONF_PORT, DEFAULT_PORT), port=self.config_entry.data.get(CONF_PORT, DEFAULT_PORT),
timeout=30, timeout=30,
websession=async_get_clientsession(hass, verify_ssl=False), websession=async_get_clientsession(hass, verify_ssl=False),
) )

View file

@ -4,18 +4,16 @@ from __future__ import annotations
from typing import Any from typing import Any
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from .const import DOMAIN from . import PlugwiseConfigEntry
from .coordinator import PlugwiseDataUpdateCoordinator
async def async_get_config_entry_diagnostics( async def async_get_config_entry_diagnostics(
hass: HomeAssistant, entry: ConfigEntry hass: HomeAssistant, entry: PlugwiseConfigEntry
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Return diagnostics for a config entry.""" """Return diagnostics for a config entry."""
coordinator: PlugwiseDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] coordinator = entry.runtime_data
return { return {
"gateway": coordinator.data.gateway, "gateway": coordinator.data.gateway,
"devices": coordinator.data.devices, "devices": coordinator.data.devices,

View file

@ -13,12 +13,12 @@ from homeassistant.components.number import (
NumberEntityDescription, NumberEntityDescription,
NumberMode, NumberMode,
) )
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory, UnitOfTemperature from homeassistant.const import EntityCategory, UnitOfTemperature
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN, NumberType from . import PlugwiseConfigEntry
from .const import NumberType
from .coordinator import PlugwiseDataUpdateCoordinator from .coordinator import PlugwiseDataUpdateCoordinator
from .entity import PlugwiseEntity from .entity import PlugwiseEntity
@ -67,14 +67,12 @@ NUMBER_TYPES = (
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: ConfigEntry, entry: PlugwiseConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up Plugwise number platform.""" """Set up Plugwise number platform."""
coordinator: PlugwiseDataUpdateCoordinator = hass.data[DOMAIN][ coordinator = entry.runtime_data
config_entry.entry_id
]
async_add_entities( async_add_entities(
PlugwiseNumberEntity(coordinator, device_id, description) PlugwiseNumberEntity(coordinator, device_id, description)

View file

@ -8,12 +8,12 @@ from dataclasses import dataclass
from plugwise import Smile from plugwise import Smile
from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_ON, EntityCategory from homeassistant.const import STATE_ON, EntityCategory
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN, SelectOptionsType, SelectType from . import PlugwiseConfigEntry
from .const import SelectOptionsType, SelectType
from .coordinator import PlugwiseDataUpdateCoordinator from .coordinator import PlugwiseDataUpdateCoordinator
from .entity import PlugwiseEntity from .entity import PlugwiseEntity
@ -60,13 +60,11 @@ SELECT_TYPES = (
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: ConfigEntry, entry: PlugwiseConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up the Smile selector from a config entry.""" """Set up the Smile selector from a config entry."""
coordinator: PlugwiseDataUpdateCoordinator = hass.data[DOMAIN][ coordinator = entry.runtime_data
config_entry.entry_id
]
async_add_entities( async_add_entities(
PlugwiseSelectEntity(coordinator, device_id, description) PlugwiseSelectEntity(coordinator, device_id, description)

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 (
LIGHT_LUX, LIGHT_LUX,
PERCENTAGE, PERCENTAGE,
@ -28,7 +27,7 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN from . import PlugwiseConfigEntry
from .coordinator import PlugwiseDataUpdateCoordinator from .coordinator import PlugwiseDataUpdateCoordinator
from .entity import PlugwiseEntity from .entity import PlugwiseEntity
@ -403,11 +402,11 @@ SENSORS: tuple[PlugwiseSensorEntityDescription, ...] = (
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: ConfigEntry, entry: PlugwiseConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up the Smile sensors from a config entry.""" """Set up the Smile sensors from a config entry."""
coordinator = hass.data[DOMAIN][config_entry.entry_id] coordinator = entry.runtime_data
entities: list[PlugwiseSensorEntity] = [] entities: list[PlugwiseSensorEntity] = []
for device_id, device in coordinator.data.devices.items(): for device_id, device in coordinator.data.devices.items():

View file

@ -12,12 +12,11 @@ from homeassistant.components.switch import (
SwitchEntity, SwitchEntity,
SwitchEntityDescription, SwitchEntityDescription,
) )
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.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN from . import PlugwiseConfigEntry
from .coordinator import PlugwiseDataUpdateCoordinator from .coordinator import PlugwiseDataUpdateCoordinator
from .entity import PlugwiseEntity from .entity import PlugwiseEntity
from .util import plugwise_command from .util import plugwise_command
@ -57,11 +56,12 @@ SWITCHES: tuple[PlugwiseSwitchEntityDescription, ...] = (
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: ConfigEntry, entry: PlugwiseConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up the Smile switches from a config entry.""" """Set up the Smile switches from a config entry."""
coordinator = hass.data[DOMAIN][config_entry.entry_id] coordinator = entry.runtime_data
entities: list[PlugwiseSwitchEntity] = [] entities: list[PlugwiseSwitchEntity] = []
for device_id, device in coordinator.data.devices.items(): for device_id, device in coordinator.data.devices.items():
if not (switches := device.get("switches")): if not (switches := device.get("switches")):

View file

@ -66,8 +66,7 @@
"model": "ThermoTouch", "model": "ThermoTouch",
"name": "Anna", "name": "Anna",
"preset_modes": ["no_frost", "asleep", "vacation", "home", "away"], "preset_modes": ["no_frost", "asleep", "vacation", "home", "away"],
"select_schedule": "Weekschema", "select_schedule": "None",
"selected_schedule": "None",
"sensors": { "sensors": {
"setpoint": 23.5, "setpoint": 23.5,
"temperature": 25.8 "temperature": 25.8

View file

@ -71,8 +71,7 @@
"model": "ThermoTouch", "model": "ThermoTouch",
"name": "Anna", "name": "Anna",
"preset_modes": ["no_frost", "asleep", "vacation", "home", "away"], "preset_modes": ["no_frost", "asleep", "vacation", "home", "away"],
"select_schedule": "Weekschema", "select_schedule": "None",
"selected_schedule": "None",
"sensors": { "sensors": {
"setpoint": 20.0, "setpoint": 20.0,
"temperature": 19.1 "temperature": 19.1

View file

@ -3,7 +3,7 @@
from unittest.mock import MagicMock from unittest.mock import MagicMock
from homeassistant.components.plugwise.const import DOMAIN from homeassistant.components.plugwise.const import DOMAIN
from homeassistant.components.plugwise.sensor import DOMAIN as SENSOR_DOMAIN from homeassistant.const import Platform
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_component import async_update_entity from homeassistant.helpers.entity_component import async_update_entity
from homeassistant.helpers.entity_registry import async_get from homeassistant.helpers.entity_registry import async_get
@ -58,7 +58,7 @@ async def test_unique_id_migration_humidity(
entity_registry = async_get(hass) entity_registry = async_get(hass)
# Entry to migrate # Entry to migrate
entity_registry.async_get_or_create( entity_registry.async_get_or_create(
SENSOR_DOMAIN, Platform.SENSOR,
DOMAIN, DOMAIN,
"f61f1a2535f54f52ad006a3d18e459ca-relative_humidity", "f61f1a2535f54f52ad006a3d18e459ca-relative_humidity",
config_entry=mock_config_entry, config_entry=mock_config_entry,
@ -67,7 +67,7 @@ async def test_unique_id_migration_humidity(
) )
# Entry not needing migration # Entry not needing migration
entity_registry.async_get_or_create( entity_registry.async_get_or_create(
SENSOR_DOMAIN, Platform.SENSOR,
DOMAIN, DOMAIN,
"f61f1a2535f54f52ad006a3d18e459ca-battery", "f61f1a2535f54f52ad006a3d18e459ca-battery",
config_entry=mock_config_entry, config_entry=mock_config_entry,