Only reflect unavailable state in DSMR when disconnected (#84862)
* Only reflect unavailable state in DSMR when disonnected * Addressreview comment
This commit is contained in:
parent
f8fa676ac8
commit
02f64ada2d
2 changed files with 31 additions and 8 deletions
|
@ -401,7 +401,7 @@ async def async_setup_entry(
|
|||
)
|
||||
|
||||
@Throttle(min_time_between_updates)
|
||||
def update_entities_telegram(telegram: dict[str, DSMRObject]) -> None:
|
||||
def update_entities_telegram(telegram: dict[str, DSMRObject] | None) -> None:
|
||||
"""Update entities with latest telegram and trigger state update."""
|
||||
# Make all device entities aware of new telegram
|
||||
for entity in entities:
|
||||
|
@ -445,6 +445,11 @@ async def async_setup_entry(
|
|||
|
||||
while hass.state == CoreState.not_running or hass.is_running:
|
||||
# Start DSMR asyncio.Protocol reader
|
||||
|
||||
# Reflect connected state in devices state by setting an
|
||||
# empty telegram resulting in `unknown` states
|
||||
update_entities_telegram({})
|
||||
|
||||
try:
|
||||
transport, protocol = await hass.loop.create_task(reader_factory())
|
||||
|
||||
|
@ -472,8 +477,8 @@ async def async_setup_entry(
|
|||
protocol = None
|
||||
|
||||
# Reflect disconnect state in devices state by setting an
|
||||
# empty telegram resulting in `unknown` states
|
||||
update_entities_telegram({})
|
||||
# None telegram resulting in `unavailable` states
|
||||
update_entities_telegram(None)
|
||||
|
||||
# throttle reconnect attempts
|
||||
await asyncio.sleep(
|
||||
|
@ -487,11 +492,19 @@ async def async_setup_entry(
|
|||
transport = None
|
||||
protocol = None
|
||||
|
||||
# Reflect disconnect state in devices state by setting an
|
||||
# None telegram resulting in `unavailable` states
|
||||
update_entities_telegram(None)
|
||||
|
||||
# throttle reconnect attempts
|
||||
await asyncio.sleep(
|
||||
entry.data.get(CONF_RECONNECT_INTERVAL, DEFAULT_RECONNECT_INTERVAL)
|
||||
)
|
||||
except CancelledError:
|
||||
# Reflect disconnect state in devices state by setting an
|
||||
# None telegram resulting in `unavailable` states
|
||||
update_entities_telegram(None)
|
||||
|
||||
if stop_listener and (
|
||||
hass.state == CoreState.not_running or hass.is_running
|
||||
):
|
||||
|
@ -534,7 +547,7 @@ class DSMREntity(SensorEntity):
|
|||
"""Initialize entity."""
|
||||
self.entity_description = entity_description
|
||||
self._entry = entry
|
||||
self.telegram: dict[str, DSMRObject] = {}
|
||||
self.telegram: dict[str, DSMRObject] | None = {}
|
||||
|
||||
device_serial = entry.data[CONF_SERIAL_ID]
|
||||
device_name = DEVICE_NAME_ELECTRICITY
|
||||
|
@ -551,16 +564,21 @@ class DSMREntity(SensorEntity):
|
|||
self._attr_unique_id = f"{device_serial}_{entity_description.key}"
|
||||
|
||||
@callback
|
||||
def update_data(self, telegram: dict[str, DSMRObject]) -> None:
|
||||
def update_data(self, telegram: dict[str, DSMRObject] | None) -> None:
|
||||
"""Update data."""
|
||||
self.telegram = telegram
|
||||
if self.hass and self.entity_description.obis_reference in self.telegram:
|
||||
if self.hass and (
|
||||
telegram is None or self.entity_description.obis_reference in telegram
|
||||
):
|
||||
self.async_write_ha_state()
|
||||
|
||||
def get_dsmr_object_attr(self, attribute: str) -> str | None:
|
||||
"""Read attribute from last received telegram for this DSMR object."""
|
||||
# Make sure telegram contains an object for this entities obis
|
||||
if self.entity_description.obis_reference not in self.telegram:
|
||||
if (
|
||||
self.telegram is None
|
||||
or self.entity_description.obis_reference not in self.telegram
|
||||
):
|
||||
return None
|
||||
|
||||
# Get the attribute value if the object has it
|
||||
|
@ -571,7 +589,7 @@ class DSMREntity(SensorEntity):
|
|||
@property
|
||||
def available(self) -> bool:
|
||||
"""Entity is only available if there is a telegram."""
|
||||
return bool(self.telegram)
|
||||
return self.telegram is not None
|
||||
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
|
|
|
@ -24,6 +24,7 @@ from homeassistant.const import (
|
|||
ATTR_UNIT_OF_MEASUREMENT,
|
||||
ENERGY_KILO_WATT_HOUR,
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
VOLUME_CUBIC_METERS,
|
||||
UnitOfPower,
|
||||
)
|
||||
|
@ -783,6 +784,10 @@ async def test_reconnect(hass, dsmr_connection_fixture):
|
|||
|
||||
assert connection_factory.call_count == 1
|
||||
|
||||
state = hass.states.get("sensor.electricity_meter_power_consumption")
|
||||
assert state
|
||||
assert state.state == STATE_UNKNOWN
|
||||
|
||||
# indicate disconnect, release wait lock and allow reconnect to happen
|
||||
closed.set()
|
||||
# wait for lock set to resolve
|
||||
|
|
Loading…
Add table
Reference in a new issue