mirror of
https://github.com/home-assistant/core.git
synced 2026-09-26 17:31:15 -04:00
Drop Sofar meter sensors a model denies from the registry (#182633)
This commit is contained in:
@@ -15,7 +15,7 @@ from homeassistant.components.sensor import (
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import ConfigEntryError
|
||||
from homeassistant.helpers import (
|
||||
config_validation as cv,
|
||||
@@ -29,6 +29,7 @@ from .const import (
|
||||
BATTERY_COMPONENTS,
|
||||
CONF_UNIT_ID,
|
||||
DOMAIN,
|
||||
METER_ENERGY,
|
||||
SCAN_INTERVAL,
|
||||
SETTINGS_SCAN_INTERVAL,
|
||||
)
|
||||
@@ -51,6 +52,7 @@ _IDENTITY_ATTEMPTS = 3
|
||||
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
|
||||
|
||||
|
||||
@callback
|
||||
def _async_remove_stale_waiting_time(hass: HomeAssistant, serial: str) -> None:
|
||||
"""Drop the removed waiting-time entity so it doesn't linger unavailable."""
|
||||
registry = er.async_get(hass)
|
||||
@@ -61,6 +63,24 @@ def _async_remove_stale_waiting_time(hass: HomeAssistant, serial: str) -> None:
|
||||
registry.async_remove(entity_id)
|
||||
|
||||
|
||||
@callback
|
||||
def _async_remove_denied_meter_energy(
|
||||
hass: HomeAssistant, serial: str, served: frozenset[str]
|
||||
) -> None:
|
||||
"""Drop meter sensors a model denies, so they don't linger unavailable."""
|
||||
if METER_ENERGY in served:
|
||||
return
|
||||
registry = er.async_get(hass)
|
||||
for description in SENSOR_DESCRIPTIONS:
|
||||
if description.component != METER_ENERGY:
|
||||
continue
|
||||
entity_id = registry.async_get_entity_id(
|
||||
SENSOR_DOMAIN, DOMAIN, f"{serial}_{description.key}"
|
||||
)
|
||||
if entity_id is not None:
|
||||
registry.async_remove(entity_id)
|
||||
|
||||
|
||||
async def _async_read_identity(entry: SofarConfigEntry, device: SofarInverter) -> None:
|
||||
"""Read identity once, retrying a few times against a transient blip."""
|
||||
for attempt in range(_IDENTITY_ATTEMPTS):
|
||||
@@ -156,6 +176,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: SofarConfigEntry) -> boo
|
||||
config_entry_id=entry.entry_id, **readings.device_info
|
||||
)
|
||||
entry.runtime_data = SofarRuntimeData(readings, settings, inverter.id)
|
||||
_async_remove_denied_meter_energy(
|
||||
hass, serial, entry.runtime_data.served_components
|
||||
)
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
return True
|
||||
|
||||
@@ -11,6 +11,8 @@ SETTINGS_SCAN_INTERVAL = 60
|
||||
|
||||
CONF_UNIT_ID = "unit_id"
|
||||
|
||||
METER_ENERGY = "meter_energy"
|
||||
|
||||
BATTERY_COMPONENTS = {
|
||||
n: "battery_1_2" if n <= 2 else "battery_3_8" for n in range(1, 9)
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ from homeassistant.const import (
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import BATTERY_COMPONENTS
|
||||
from .const import BATTERY_COMPONENTS, METER_ENERGY
|
||||
from .coordinator import SofarConfigEntry
|
||||
from .entity import SofarEntity, SofarEntityDescription
|
||||
|
||||
@@ -1153,7 +1153,7 @@ SENSOR_DESCRIPTIONS: tuple[SofarSensorDescription, ...] = (
|
||||
),
|
||||
SofarSensorDescription(
|
||||
key="load_consumption_today",
|
||||
component="meter_energy",
|
||||
component=METER_ENERGY,
|
||||
translation_key="load_consumption_today",
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
@@ -1163,7 +1163,7 @@ SENSOR_DESCRIPTIONS: tuple[SofarSensorDescription, ...] = (
|
||||
),
|
||||
SofarSensorDescription(
|
||||
key="load_consumption_total",
|
||||
component="meter_energy",
|
||||
component=METER_ENERGY,
|
||||
translation_key="load_consumption_total",
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
@@ -1172,7 +1172,7 @@ SENSOR_DESCRIPTIONS: tuple[SofarSensorDescription, ...] = (
|
||||
),
|
||||
SofarSensorDescription(
|
||||
key="import_energy_today",
|
||||
component="meter_energy",
|
||||
component=METER_ENERGY,
|
||||
translation_key="import_energy_today",
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
@@ -1182,7 +1182,7 @@ SENSOR_DESCRIPTIONS: tuple[SofarSensorDescription, ...] = (
|
||||
),
|
||||
SofarSensorDescription(
|
||||
key="import_energy_total",
|
||||
component="meter_energy",
|
||||
component=METER_ENERGY,
|
||||
translation_key="import_energy_total",
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
@@ -1191,7 +1191,7 @@ SENSOR_DESCRIPTIONS: tuple[SofarSensorDescription, ...] = (
|
||||
),
|
||||
SofarSensorDescription(
|
||||
key="export_energy_today",
|
||||
component="meter_energy",
|
||||
component=METER_ENERGY,
|
||||
translation_key="export_energy_today",
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
@@ -1201,7 +1201,7 @@ SENSOR_DESCRIPTIONS: tuple[SofarSensorDescription, ...] = (
|
||||
),
|
||||
SofarSensorDescription(
|
||||
key="export_energy_total",
|
||||
component="meter_energy",
|
||||
component=METER_ENERGY,
|
||||
translation_key="export_energy_total",
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
|
||||
@@ -255,6 +255,37 @@ async def test_setup_keeps_meter_sensors_a_model_serves(
|
||||
assert hass.states.get(entity_id).state == "1000.0"
|
||||
|
||||
|
||||
async def test_setup_removes_meter_sensors_a_model_denies(
|
||||
hass: HomeAssistant,
|
||||
mock_connection: MockModbusConnection,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test an upgrade drops meter sensors the model turns out to deny."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
deny_meter_energy(mock_connection.for_unit(1))
|
||||
stale = [
|
||||
entity_registry.async_get_or_create(
|
||||
SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
f"{MOCK_SERIAL}_{key}",
|
||||
config_entry=mock_config_entry,
|
||||
).entity_id
|
||||
for key in METER_ENERGY_KEYS
|
||||
]
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.sofar.async_get_unit",
|
||||
side_effect=lambda hass, entry, params, unit_id: mock_connection.for_unit(
|
||||
unit_id
|
||||
),
|
||||
):
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
assert all(entity_registry.async_get(entity_id) is None for entity_id in stale)
|
||||
|
||||
|
||||
async def test_setup_keeps_meter_sensors_when_no_mask_is_published(
|
||||
hass: HomeAssistant,
|
||||
mock_connection: MockModbusConnection,
|
||||
|
||||
Reference in New Issue
Block a user