"""The dsmr component.""" from __future__ import annotations from asyncio import CancelledError from contextlib import suppress from typing import Any from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from .const import CONF_DSMR_VERSION, DATA_TASK, DOMAIN, PLATFORMS async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up DSMR from a config entry.""" @callback def _async_migrate_entity_entry( entity_entry: er.RegistryEntry, ) -> dict[str, Any] | None: """Migrate DSMR entity entry.""" return async_migrate_entity_entry(entry, entity_entry) await er.async_migrate_entries(hass, entry.entry_id, _async_migrate_entity_entry) hass.data.setdefault(DOMAIN, {}) hass.data[DOMAIN][entry.entry_id] = {} await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) entry.async_on_unload(entry.add_update_listener(async_update_options)) return True async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" task = hass.data[DOMAIN][entry.entry_id][DATA_TASK] # Cancel the reconnect task task.cancel() with suppress(CancelledError): await task unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) if unload_ok: hass.data[DOMAIN].pop(entry.entry_id) return unload_ok async def async_update_options(hass: HomeAssistant, entry: ConfigEntry) -> None: """Update options.""" await hass.config_entries.async_reload(entry.entry_id) @callback def async_migrate_entity_entry( config_entry: ConfigEntry, entity_entry: er.RegistryEntry ) -> dict[str, Any] | None: """Migrate DSMR entity entries. - Migrates unique ID for sensors based on entity description name to key. """ # Replace names with keys in unique ID for old, new in ( ("Power_Consumption", "current_electricity_usage"), ("Power_Production", "current_electricity_delivery"), ("Power_Tariff", "electricity_active_tariff"), ("Energy_Consumption_(tarif_1)", "electricity_used_tariff_1"), ("Energy_Consumption_(tarif_2)", "electricity_used_tariff_2"), ("Energy_Production_(tarif_1)", "electricity_delivered_tariff_1"), ("Energy_Production_(tarif_2)", "electricity_delivered_tariff_2"), ("Power_Consumption_Phase_L1", "instantaneous_active_power_l1_positive"), ("Power_Consumption_Phase_L3", "instantaneous_active_power_l3_positive"), ("Power_Consumption_Phase_L2", "instantaneous_active_power_l2_positive"), ("Power_Production_Phase_L1", "instantaneous_active_power_l1_negative"), ("Power_Production_Phase_L2", "instantaneous_active_power_l2_negative"), ("Power_Production_Phase_L3", "instantaneous_active_power_l3_negative"), ("Short_Power_Failure_Count", "short_power_failure_count"), ("Long_Power_Failure_Count", "long_power_failure_count"), ("Voltage_Sags_Phase_L1", "voltage_sag_l1_count"), ("Voltage_Sags_Phase_L2", "voltage_sag_l2_count"), ("Voltage_Sags_Phase_L3", "voltage_sag_l3_count"), ("Voltage_Swells_Phase_L1", "voltage_swell_l1_count"), ("Voltage_Swells_Phase_L2", "voltage_swell_l2_count"), ("Voltage_Swells_Phase_L3", "voltage_swell_l3_count"), ("Voltage_Phase_L1", "instantaneous_voltage_l1"), ("Voltage_Phase_L2", "instantaneous_voltage_l2"), ("Voltage_Phase_L3", "instantaneous_voltage_l3"), ("Current_Phase_L1", "instantaneous_current_l1"), ("Current_Phase_L2", "instantaneous_current_l2"), ("Current_Phase_L3", "instantaneous_current_l3"), ("Max_power_per_phase", "belgium_max_power_per_phase"), ("Max_current_per_phase", "belgium_max_current_per_phase"), ("Energy_Consumption_(total)", "electricity_imported_total"), ("Energy_Production_(total)", "electricity_exported_total"), ): if entity_entry.unique_id.endswith(old): return {"new_unique_id": entity_entry.unique_id.replace(old, new)} # Replace unique ID for gas sensors, based on DSMR version old = "Gas_Consumption" if entity_entry.unique_id.endswith(old): dsmr_version = config_entry.data[CONF_DSMR_VERSION] if dsmr_version in {"4", "5", "5L"}: return { "new_unique_id": entity_entry.unique_id.replace( old, "hourly_gas_meter_reading" ) } if dsmr_version == "5B": return { "new_unique_id": entity_entry.unique_id.replace( old, "belgium_5min_gas_meter_reading" ) } if dsmr_version == "2.2": return { "new_unique_id": entity_entry.unique_id.replace( old, "gas_meter_reading" ) } # No migration needed return None