mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 04:07:08 +00:00
Fix suggested UOM cannot be set for dsmr entities (#102134)
* Supply dsmr entities jit on first telegram * Stale docstr Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Simplify tuple type --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
c574cefc30
commit
9db9f1b8a9
@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from asyncio import CancelledError
|
||||
from collections.abc import Callable
|
||||
from contextlib import suppress
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
@ -34,6 +35,10 @@ from homeassistant.const import (
|
||||
)
|
||||
from homeassistant.core import CoreState, Event, HomeAssistant, callback
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.dispatcher import (
|
||||
async_dispatcher_connect,
|
||||
async_dispatcher_send,
|
||||
)
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import StateType
|
||||
from homeassistant.util import Throttle
|
||||
@ -58,6 +63,8 @@ from .const import (
|
||||
LOGGER,
|
||||
)
|
||||
|
||||
EVENT_FIRST_TELEGRAM = "dsmr_first_telegram_{}"
|
||||
|
||||
UNIT_CONVERSION = {"m3": UnitOfVolume.CUBIC_METERS}
|
||||
|
||||
|
||||
@ -387,17 +394,58 @@ async def async_setup_entry(
|
||||
) -> None:
|
||||
"""Set up the DSMR sensor."""
|
||||
dsmr_version = entry.data[CONF_DSMR_VERSION]
|
||||
entities = [
|
||||
DSMREntity(description, entry)
|
||||
for description in SENSORS
|
||||
if (
|
||||
description.dsmr_versions is None
|
||||
or dsmr_version in description.dsmr_versions
|
||||
)
|
||||
and (not description.is_gas or CONF_SERIAL_ID_GAS in entry.data)
|
||||
]
|
||||
async_add_entities(entities)
|
||||
entities: list[DSMREntity] = []
|
||||
initialized: bool = False
|
||||
add_entities_handler: Callable[..., None] | None
|
||||
|
||||
@callback
|
||||
def init_async_add_entities(telegram: dict[str, DSMRObject]) -> None:
|
||||
"""Add the sensor entities after the first telegram was received."""
|
||||
nonlocal add_entities_handler
|
||||
assert add_entities_handler is not None
|
||||
add_entities_handler()
|
||||
add_entities_handler = None
|
||||
|
||||
def device_class_and_uom(
|
||||
telegram: dict[str, DSMRObject],
|
||||
entity_description: DSMRSensorEntityDescription,
|
||||
) -> tuple[SensorDeviceClass | None, str | None]:
|
||||
"""Get native unit of measurement from telegram,."""
|
||||
dsmr_object = telegram[entity_description.obis_reference]
|
||||
uom: str | None = getattr(dsmr_object, "unit") or None
|
||||
with suppress(ValueError):
|
||||
if entity_description.device_class == SensorDeviceClass.GAS and (
|
||||
enery_uom := UnitOfEnergy(str(uom))
|
||||
):
|
||||
return (SensorDeviceClass.ENERGY, enery_uom)
|
||||
if uom in UNIT_CONVERSION:
|
||||
return (entity_description.device_class, UNIT_CONVERSION[uom])
|
||||
return (entity_description.device_class, uom)
|
||||
|
||||
entities.extend(
|
||||
[
|
||||
DSMREntity(
|
||||
description,
|
||||
entry,
|
||||
telegram,
|
||||
*device_class_and_uom(
|
||||
telegram, description
|
||||
), # type: ignore[arg-type]
|
||||
)
|
||||
for description in SENSORS
|
||||
if (
|
||||
description.dsmr_versions is None
|
||||
or dsmr_version in description.dsmr_versions
|
||||
)
|
||||
and (not description.is_gas or CONF_SERIAL_ID_GAS in entry.data)
|
||||
and description.obis_reference in telegram
|
||||
]
|
||||
)
|
||||
async_add_entities(entities)
|
||||
|
||||
add_entities_handler = async_dispatcher_connect(
|
||||
hass, EVENT_FIRST_TELEGRAM.format(entry.entry_id), init_async_add_entities
|
||||
)
|
||||
min_time_between_updates = timedelta(
|
||||
seconds=entry.options.get(CONF_TIME_BETWEEN_UPDATE, DEFAULT_TIME_BETWEEN_UPDATE)
|
||||
)
|
||||
@ -405,10 +453,17 @@ async def async_setup_entry(
|
||||
@Throttle(min_time_between_updates)
|
||||
def update_entities_telegram(telegram: dict[str, DSMRObject] | None) -> None:
|
||||
"""Update entities with latest telegram and trigger state update."""
|
||||
nonlocal initialized
|
||||
# Make all device entities aware of new telegram
|
||||
for entity in entities:
|
||||
entity.update_data(telegram)
|
||||
|
||||
if not initialized and telegram:
|
||||
initialized = True
|
||||
async_dispatcher_send(
|
||||
hass, EVENT_FIRST_TELEGRAM.format(entry.entry_id), telegram
|
||||
)
|
||||
|
||||
# Creates an asyncio.Protocol factory for reading DSMR telegrams from
|
||||
# serial and calls update_entities_telegram to update entities on arrival
|
||||
protocol = entry.data.get(CONF_PROTOCOL, DSMR_PROTOCOL)
|
||||
@ -525,6 +580,8 @@ async def async_setup_entry(
|
||||
|
||||
@callback
|
||||
async def _async_stop(_: Event) -> None:
|
||||
if add_entities_handler is not None:
|
||||
add_entities_handler()
|
||||
task.cancel()
|
||||
|
||||
# Make sure task is cancelled on shutdown (or tests complete)
|
||||
@ -544,12 +601,19 @@ class DSMREntity(SensorEntity):
|
||||
_attr_should_poll = False
|
||||
|
||||
def __init__(
|
||||
self, entity_description: DSMRSensorEntityDescription, entry: ConfigEntry
|
||||
self,
|
||||
entity_description: DSMRSensorEntityDescription,
|
||||
entry: ConfigEntry,
|
||||
telegram: dict[str, DSMRObject],
|
||||
device_class: SensorDeviceClass,
|
||||
native_unit_of_measurement: str | None,
|
||||
) -> None:
|
||||
"""Initialize entity."""
|
||||
self.entity_description = entity_description
|
||||
self._attr_device_class = device_class
|
||||
self._attr_native_unit_of_measurement = native_unit_of_measurement
|
||||
self._entry = entry
|
||||
self.telegram: dict[str, DSMRObject] | None = {}
|
||||
self.telegram: dict[str, DSMRObject] | None = telegram
|
||||
|
||||
device_serial = entry.data[CONF_SERIAL_ID]
|
||||
device_name = DEVICE_NAME_ELECTRICITY
|
||||
@ -593,21 +657,6 @@ class DSMREntity(SensorEntity):
|
||||
"""Entity is only available if there is a telegram."""
|
||||
return self.telegram is not None
|
||||
|
||||
@property
|
||||
def device_class(self) -> SensorDeviceClass | None:
|
||||
"""Return the device class of this entity."""
|
||||
device_class = super().device_class
|
||||
|
||||
# Override device class for gas sensors providing energy units, like
|
||||
# kWh, MWh, GJ, etc. In those cases, the class should be energy, not gas
|
||||
with suppress(ValueError):
|
||||
if device_class == SensorDeviceClass.GAS and UnitOfEnergy(
|
||||
str(self.native_unit_of_measurement)
|
||||
):
|
||||
return SensorDeviceClass.ENERGY
|
||||
|
||||
return device_class
|
||||
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state of sensor, if available, translate if needed."""
|
||||
@ -628,14 +677,6 @@ class DSMREntity(SensorEntity):
|
||||
|
||||
return value
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
"""Return the unit of measurement of this entity, if any."""
|
||||
unit_of_measurement = self.get_dsmr_object_attr("unit")
|
||||
if unit_of_measurement in UNIT_CONVERSION:
|
||||
return UNIT_CONVERSION[unit_of_measurement]
|
||||
return unit_of_measurement
|
||||
|
||||
@staticmethod
|
||||
def translate_tariff(value: str, dsmr_version: str) -> str | None:
|
||||
"""Convert 2/1 to normal/low depending on DSMR version."""
|
||||
|
@ -23,8 +23,6 @@ from homeassistant.const import (
|
||||
ATTR_FRIENDLY_NAME,
|
||||
ATTR_ICON,
|
||||
ATTR_UNIT_OF_MEASUREMENT,
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
UnitOfEnergy,
|
||||
UnitOfPower,
|
||||
UnitOfVolume,
|
||||
@ -84,6 +82,14 @@ async def test_default_setup(hass: HomeAssistant, dsmr_connection_fixture) -> No
|
||||
await hass.config_entries.async_setup(mock_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
telegram_callback = connection_factory.call_args_list[0][0][2]
|
||||
|
||||
# simulate a telegram pushed from the smartmeter and parsed by dsmr_parser
|
||||
telegram_callback(telegram)
|
||||
|
||||
# after receiving telegram entities need to have the chance to be created
|
||||
await hass.async_block_till_done()
|
||||
|
||||
registry = er.async_get(hass)
|
||||
|
||||
entry = registry.async_get("sensor.electricity_meter_power_consumption")
|
||||
@ -94,11 +100,9 @@ async def test_default_setup(hass: HomeAssistant, dsmr_connection_fixture) -> No
|
||||
assert entry
|
||||
assert entry.unique_id == "5678_gas_meter_reading"
|
||||
|
||||
telegram_callback = connection_factory.call_args_list[0][0][2]
|
||||
|
||||
# make sure entities have been created and return 'unavailable' state
|
||||
# make sure entities are initialized
|
||||
power_consumption = hass.states.get("sensor.electricity_meter_power_consumption")
|
||||
assert power_consumption.state == STATE_UNAVAILABLE
|
||||
assert power_consumption.state == "0.0"
|
||||
assert (
|
||||
power_consumption.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.POWER
|
||||
)
|
||||
@ -107,7 +111,24 @@ async def test_default_setup(hass: HomeAssistant, dsmr_connection_fixture) -> No
|
||||
power_consumption.attributes.get(ATTR_STATE_CLASS)
|
||||
== SensorStateClass.MEASUREMENT
|
||||
)
|
||||
assert power_consumption.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None
|
||||
assert power_consumption.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "W"
|
||||
|
||||
telegram = {
|
||||
CURRENT_ELECTRICITY_USAGE: CosemObject(
|
||||
CURRENT_ELECTRICITY_USAGE,
|
||||
[{"value": Decimal("35.0"), "unit": UnitOfPower.WATT}],
|
||||
),
|
||||
ELECTRICITY_ACTIVE_TARIFF: CosemObject(
|
||||
ELECTRICITY_ACTIVE_TARIFF, [{"value": "0001", "unit": ""}]
|
||||
),
|
||||
GAS_METER_READING: MBusObject(
|
||||
GAS_METER_READING,
|
||||
[
|
||||
{"value": datetime.datetime.fromtimestamp(1551642214)},
|
||||
{"value": Decimal(745.701), "unit": UnitOfVolume.CUBIC_METERS},
|
||||
],
|
||||
),
|
||||
}
|
||||
|
||||
# simulate a telegram pushed from the smartmeter and parsed by dsmr_parser
|
||||
telegram_callback(telegram)
|
||||
@ -117,7 +138,7 @@ async def test_default_setup(hass: HomeAssistant, dsmr_connection_fixture) -> No
|
||||
|
||||
# ensure entities have new state value after incoming telegram
|
||||
power_consumption = hass.states.get("sensor.electricity_meter_power_consumption")
|
||||
assert power_consumption.state == "0.0"
|
||||
assert power_consumption.state == "35.0"
|
||||
assert power_consumption.attributes.get("unit_of_measurement") == UnitOfPower.WATT
|
||||
|
||||
# tariff should be translated in human readable and have no unit
|
||||
@ -131,11 +152,11 @@ async def test_default_setup(hass: HomeAssistant, dsmr_connection_fixture) -> No
|
||||
)
|
||||
assert active_tariff.attributes.get(ATTR_OPTIONS) == ["low", "normal"]
|
||||
assert active_tariff.attributes.get(ATTR_STATE_CLASS) is None
|
||||
assert active_tariff.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ""
|
||||
assert active_tariff.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None
|
||||
|
||||
# check if gas consumption is parsed correctly
|
||||
gas_consumption = hass.states.get("sensor.gas_meter_gas_consumption")
|
||||
assert gas_consumption.state == "745.695"
|
||||
assert gas_consumption.state == "745.701"
|
||||
assert gas_consumption.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.GAS
|
||||
assert (
|
||||
gas_consumption.attributes.get(ATTR_FRIENDLY_NAME)
|
||||
@ -153,6 +174,14 @@ async def test_default_setup(hass: HomeAssistant, dsmr_connection_fixture) -> No
|
||||
|
||||
async def test_setup_only_energy(hass: HomeAssistant, dsmr_connection_fixture) -> None:
|
||||
"""Test the default setup."""
|
||||
(connection_factory, transport, protocol) = dsmr_connection_fixture
|
||||
|
||||
from dsmr_parser.obis_references import (
|
||||
CURRENT_ELECTRICITY_USAGE,
|
||||
ELECTRICITY_ACTIVE_TARIFF,
|
||||
)
|
||||
from dsmr_parser.objects import CosemObject
|
||||
|
||||
entry_data = {
|
||||
"port": "/dev/ttyUSB0",
|
||||
"dsmr_version": "2.2",
|
||||
@ -160,9 +189,22 @@ async def test_setup_only_energy(hass: HomeAssistant, dsmr_connection_fixture) -
|
||||
"reconnect_interval": 30,
|
||||
"serial_id": "1234",
|
||||
}
|
||||
entry_options = {
|
||||
"time_between_update": 0,
|
||||
}
|
||||
|
||||
telegram = {
|
||||
CURRENT_ELECTRICITY_USAGE: CosemObject(
|
||||
CURRENT_ELECTRICITY_USAGE,
|
||||
[{"value": Decimal("35.0"), "unit": UnitOfPower.WATT}],
|
||||
),
|
||||
ELECTRICITY_ACTIVE_TARIFF: CosemObject(
|
||||
ELECTRICITY_ACTIVE_TARIFF, [{"value": "0001", "unit": ""}]
|
||||
),
|
||||
}
|
||||
|
||||
mock_entry = MockConfigEntry(
|
||||
domain="dsmr", unique_id="/dev/ttyUSB0", data=entry_data
|
||||
domain="dsmr", unique_id="/dev/ttyUSB0", data=entry_data, options=entry_options
|
||||
)
|
||||
|
||||
mock_entry.add_to_hass(hass)
|
||||
@ -170,6 +212,14 @@ async def test_setup_only_energy(hass: HomeAssistant, dsmr_connection_fixture) -
|
||||
await hass.config_entries.async_setup(mock_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
telegram_callback = connection_factory.call_args_list[0][0][2]
|
||||
|
||||
# simulate a telegram pushed from the smartmeter and parsed by dsmr_parser
|
||||
telegram_callback(telegram)
|
||||
|
||||
# after receiving telegram entities need to have the chance to be created
|
||||
await hass.async_block_till_done()
|
||||
|
||||
registry = er.async_get(hass)
|
||||
|
||||
entry = registry.async_get("sensor.electricity_meter_power_consumption")
|
||||
@ -229,8 +279,8 @@ async def test_v4_meter(hass: HomeAssistant, dsmr_connection_fixture) -> None:
|
||||
# simulate a telegram pushed from the smartmeter and parsed by dsmr_parser
|
||||
telegram_callback(telegram)
|
||||
|
||||
# after receiving telegram entities need to have the chance to update
|
||||
await asyncio.sleep(0)
|
||||
# after receiving telegram entities need to have the chance to be created
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# tariff should be translated in human readable and have no unit
|
||||
active_tariff = hass.states.get("sensor.electricity_meter_active_tariff")
|
||||
@ -239,7 +289,7 @@ async def test_v4_meter(hass: HomeAssistant, dsmr_connection_fixture) -> None:
|
||||
assert active_tariff.attributes.get(ATTR_ICON) == "mdi:flash"
|
||||
assert active_tariff.attributes.get(ATTR_OPTIONS) == ["low", "normal"]
|
||||
assert active_tariff.attributes.get(ATTR_STATE_CLASS) is None
|
||||
assert active_tariff.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ""
|
||||
assert active_tariff.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None
|
||||
|
||||
# check if gas consumption is parsed correctly
|
||||
gas_consumption = hass.states.get("sensor.gas_meter_gas_consumption")
|
||||
@ -308,8 +358,8 @@ async def test_v5_meter(hass: HomeAssistant, dsmr_connection_fixture) -> None:
|
||||
# simulate a telegram pushed from the smartmeter and parsed by dsmr_parser
|
||||
telegram_callback(telegram)
|
||||
|
||||
# after receiving telegram entities need to have the chance to update
|
||||
await asyncio.sleep(0)
|
||||
# after receiving telegram entities need to have the chance to be created
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# tariff should be translated in human readable and have no unit
|
||||
active_tariff = hass.states.get("sensor.electricity_meter_active_tariff")
|
||||
@ -318,7 +368,7 @@ async def test_v5_meter(hass: HomeAssistant, dsmr_connection_fixture) -> None:
|
||||
assert active_tariff.attributes.get(ATTR_ICON) == "mdi:flash"
|
||||
assert active_tariff.attributes.get(ATTR_OPTIONS) == ["low", "normal"]
|
||||
assert active_tariff.attributes.get(ATTR_STATE_CLASS) is None
|
||||
assert active_tariff.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ""
|
||||
assert active_tariff.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None
|
||||
|
||||
# check if gas consumption is parsed correctly
|
||||
gas_consumption = hass.states.get("sensor.gas_meter_gas_consumption")
|
||||
@ -389,8 +439,8 @@ async def test_luxembourg_meter(hass: HomeAssistant, dsmr_connection_fixture) ->
|
||||
# simulate a telegram pushed from the smartmeter and parsed by dsmr_parser
|
||||
telegram_callback(telegram)
|
||||
|
||||
# after receiving telegram entities need to have the chance to update
|
||||
await asyncio.sleep(0)
|
||||
# after receiving telegram entities need to have the chance to be created
|
||||
await hass.async_block_till_done()
|
||||
|
||||
active_tariff = hass.states.get("sensor.electricity_meter_energy_consumption_total")
|
||||
assert active_tariff.state == "123.456"
|
||||
@ -472,8 +522,8 @@ async def test_belgian_meter(hass: HomeAssistant, dsmr_connection_fixture) -> No
|
||||
# simulate a telegram pushed from the smartmeter and parsed by dsmr_parser
|
||||
telegram_callback(telegram)
|
||||
|
||||
# after receiving telegram entities need to have the chance to update
|
||||
await asyncio.sleep(0)
|
||||
# after receiving telegram entities need to have the chance to be created
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# tariff should be translated in human readable and have no unit
|
||||
active_tariff = hass.states.get("sensor.electricity_meter_active_tariff")
|
||||
@ -482,7 +532,7 @@ async def test_belgian_meter(hass: HomeAssistant, dsmr_connection_fixture) -> No
|
||||
assert active_tariff.attributes.get(ATTR_ICON) == "mdi:flash"
|
||||
assert active_tariff.attributes.get(ATTR_OPTIONS) == ["low", "normal"]
|
||||
assert active_tariff.attributes.get(ATTR_STATE_CLASS) is None
|
||||
assert active_tariff.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ""
|
||||
assert active_tariff.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None
|
||||
|
||||
# check if gas consumption is parsed correctly
|
||||
gas_consumption = hass.states.get("sensor.gas_meter_gas_consumption")
|
||||
@ -537,8 +587,8 @@ async def test_belgian_meter_low(hass: HomeAssistant, dsmr_connection_fixture) -
|
||||
# simulate a telegram pushed from the smartmeter and parsed by dsmr_parser
|
||||
telegram_callback(telegram)
|
||||
|
||||
# after receiving telegram entities need to have the chance to update
|
||||
await asyncio.sleep(0)
|
||||
# after receiving telegram entities need to have the chance to be created
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# tariff should be translated in human readable and have no unit
|
||||
active_tariff = hass.states.get("sensor.electricity_meter_active_tariff")
|
||||
@ -547,7 +597,7 @@ async def test_belgian_meter_low(hass: HomeAssistant, dsmr_connection_fixture) -
|
||||
assert active_tariff.attributes.get(ATTR_ICON) == "mdi:flash"
|
||||
assert active_tariff.attributes.get(ATTR_OPTIONS) == ["low", "normal"]
|
||||
assert active_tariff.attributes.get(ATTR_STATE_CLASS) is None
|
||||
assert active_tariff.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ""
|
||||
assert active_tariff.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None
|
||||
|
||||
|
||||
async def test_swedish_meter(hass: HomeAssistant, dsmr_connection_fixture) -> None:
|
||||
@ -597,8 +647,8 @@ async def test_swedish_meter(hass: HomeAssistant, dsmr_connection_fixture) -> No
|
||||
# simulate a telegram pushed from the smartmeter and parsed by dsmr_parser
|
||||
telegram_callback(telegram)
|
||||
|
||||
# after receiving telegram entities need to have the chance to update
|
||||
await asyncio.sleep(0)
|
||||
# after receiving telegram entities need to have the chance to be created
|
||||
await hass.async_block_till_done()
|
||||
|
||||
active_tariff = hass.states.get("sensor.electricity_meter_energy_consumption_total")
|
||||
assert active_tariff.state == "123.456"
|
||||
@ -675,8 +725,8 @@ async def test_easymeter(hass: HomeAssistant, dsmr_connection_fixture) -> None:
|
||||
# simulate a telegram pushed from the smartmeter and parsed by dsmr_parser
|
||||
telegram_callback(telegram)
|
||||
|
||||
# after receiving telegram entities need to have the chance to update
|
||||
await asyncio.sleep(0)
|
||||
# after receiving telegram entities need to have the chance to be created
|
||||
await hass.async_block_till_done()
|
||||
|
||||
active_tariff = hass.states.get("sensor.electricity_meter_energy_consumption_total")
|
||||
assert active_tariff.state == "54184.6316"
|
||||
@ -800,6 +850,12 @@ async def test_connection_errors_retry(
|
||||
|
||||
async def test_reconnect(hass: HomeAssistant, dsmr_connection_fixture) -> None:
|
||||
"""If transport disconnects, the connection should be retried."""
|
||||
from dsmr_parser.obis_references import (
|
||||
CURRENT_ELECTRICITY_USAGE,
|
||||
ELECTRICITY_ACTIVE_TARIFF,
|
||||
)
|
||||
from dsmr_parser.objects import CosemObject
|
||||
|
||||
(connection_factory, transport, protocol) = dsmr_connection_fixture
|
||||
|
||||
entry_data = {
|
||||
@ -810,6 +866,19 @@ async def test_reconnect(hass: HomeAssistant, dsmr_connection_fixture) -> None:
|
||||
"serial_id": "1234",
|
||||
"serial_id_gas": "5678",
|
||||
}
|
||||
entry_options = {
|
||||
"time_between_update": 0,
|
||||
}
|
||||
|
||||
telegram = {
|
||||
CURRENT_ELECTRICITY_USAGE: CosemObject(
|
||||
CURRENT_ELECTRICITY_USAGE,
|
||||
[{"value": Decimal("35.0"), "unit": UnitOfPower.WATT}],
|
||||
),
|
||||
ELECTRICITY_ACTIVE_TARIFF: CosemObject(
|
||||
ELECTRICITY_ACTIVE_TARIFF, [{"value": "0001", "unit": ""}]
|
||||
),
|
||||
}
|
||||
|
||||
# mock waiting coroutine while connection lasts
|
||||
closed = asyncio.Event()
|
||||
@ -823,7 +892,7 @@ async def test_reconnect(hass: HomeAssistant, dsmr_connection_fixture) -> None:
|
||||
protocol.wait_closed = wait_closed
|
||||
|
||||
mock_entry = MockConfigEntry(
|
||||
domain="dsmr", unique_id="/dev/ttyUSB0", data=entry_data
|
||||
domain="dsmr", unique_id="/dev/ttyUSB0", data=entry_data, options=entry_options
|
||||
)
|
||||
|
||||
mock_entry.add_to_hass(hass)
|
||||
@ -831,11 +900,19 @@ async def test_reconnect(hass: HomeAssistant, dsmr_connection_fixture) -> None:
|
||||
await hass.config_entries.async_setup(mock_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
telegram_callback = connection_factory.call_args_list[0][0][2]
|
||||
|
||||
# simulate a telegram pushed from the smartmeter and parsed by dsmr_parser
|
||||
telegram_callback(telegram)
|
||||
|
||||
# after receiving telegram entities need to have the chance to be created
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert connection_factory.call_count == 1
|
||||
|
||||
state = hass.states.get("sensor.electricity_meter_power_consumption")
|
||||
assert state
|
||||
assert state.state == STATE_UNKNOWN
|
||||
assert state.state == "35.0"
|
||||
|
||||
# indicate disconnect, release wait lock and allow reconnect to happen
|
||||
closed.set()
|
||||
@ -897,7 +974,7 @@ async def test_gas_meter_providing_energy_reading(
|
||||
|
||||
telegram_callback = connection_factory.call_args_list[0][0][2]
|
||||
telegram_callback(telegram)
|
||||
await asyncio.sleep(0)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
gas_consumption = hass.states.get("sensor.gas_meter_gas_consumption")
|
||||
assert gas_consumption.state == "123.456"
|
||||
|
Loading…
x
Reference in New Issue
Block a user