mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 09:17:10 +00:00
Add Landis+Gyr MWh-readings from ultraheat-api (#89937)
* Use mwh values from ultraheat api when available Remove manifest cleanup from PR Remove added device class from this PR Restore entity registry fixture Replace filter by attr_entity_registry_enabled_default * Catchup with #90182 and #90183 * Add comment explaining disabling some entities * Add parameterisation of test cases
This commit is contained in:
parent
ba32e28fc6
commit
a7040a0487
@ -54,6 +54,15 @@ class HeatMeterSensorEntityDescription(
|
||||
|
||||
|
||||
HEAT_METER_SENSOR_TYPES = (
|
||||
HeatMeterSensorEntityDescription(
|
||||
key="heat_usage_mwh",
|
||||
icon="mdi:fire",
|
||||
name="Heat usage MWh",
|
||||
native_unit_of_measurement=UnitOfEnergy.MEGA_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
state_class=SensorStateClass.TOTAL,
|
||||
value_fn=lambda res: getattr(res, "heat_usage_mwh", None),
|
||||
),
|
||||
HeatMeterSensorEntityDescription(
|
||||
key="volume_usage_m3",
|
||||
icon="mdi:fire",
|
||||
@ -72,6 +81,15 @@ HEAT_METER_SENSOR_TYPES = (
|
||||
state_class=SensorStateClass.TOTAL,
|
||||
value_fn=lambda res: getattr(res, "heat_usage_gj", None),
|
||||
),
|
||||
HeatMeterSensorEntityDescription(
|
||||
key="heat_previous_year_mwh",
|
||||
icon="mdi:fire",
|
||||
name="Heat previous year MWh",
|
||||
native_unit_of_measurement=UnitOfEnergy.MEGA_WATT_HOUR,
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda res: getattr(res, "heat_previous_year_mwh", None),
|
||||
),
|
||||
HeatMeterSensorEntityDescription(
|
||||
key="heat_previous_year_gj",
|
||||
icon="mdi:fire",
|
||||
@ -277,7 +295,6 @@ async def async_setup_entry(
|
||||
)
|
||||
|
||||
sensors = []
|
||||
|
||||
for description in HEAT_METER_SENSOR_TYPES:
|
||||
sensors.append(HeatMeterSensor(coordinator, description, device))
|
||||
|
||||
@ -306,6 +323,14 @@ class HeatMeterSensor(
|
||||
self.entity_description = description
|
||||
self._attr_device_info = device
|
||||
|
||||
if (
|
||||
description.native_unit_of_measurement
|
||||
in {UnitOfEnergy.GIGA_JOULE, UnitOfEnergy.MEGA_WATT_HOUR}
|
||||
and self.native_value is None
|
||||
):
|
||||
# Some meters will return MWh, others will return GJ.
|
||||
self._attr_entity_registry_enabled_default = False
|
||||
|
||||
@property
|
||||
def native_value(self) -> StateType | datetime:
|
||||
"""Return the state of the sensor."""
|
||||
|
@ -1,5 +1,5 @@
|
||||
# serializer version: 1
|
||||
# name: test_create_sensors
|
||||
# name: test_create_sensors[mock_heat_meter_response0]
|
||||
list([
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
@ -276,7 +276,310 @@
|
||||
'entity_id': 'sensor.heat_meter_meter_date_time',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2022-05-20T02:41:17+00:00',
|
||||
'state': '2022-05-19T19:41:17+00:00',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Heat Meter Measuring range',
|
||||
'icon': 'mdi:water-outline',
|
||||
'unit_of_measurement': <UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR: 'm³/h'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_measuring_range',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Heat Meter Settings and firmware',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_settings_and_firmware',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_create_sensors[mock_heat_meter_response1]
|
||||
list([
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'energy',
|
||||
'friendly_name': 'Heat Meter Heat usage MWh',
|
||||
'icon': 'mdi:fire',
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
'unit_of_measurement': <UnitOfEnergy.MEGA_WATT_HOUR: 'MWh'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_heat_usage_mwh',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '123.0',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'volume',
|
||||
'friendly_name': 'Heat Meter Volume usage',
|
||||
'icon': 'mdi:fire',
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
'unit_of_measurement': <UnitOfVolume.CUBIC_METERS: 'm³'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_volume_usage',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '456.0',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'energy',
|
||||
'friendly_name': 'Heat Meter Heat previous year MWh',
|
||||
'icon': 'mdi:fire',
|
||||
'unit_of_measurement': <UnitOfEnergy.MEGA_WATT_HOUR: 'MWh'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_heat_previous_year_mwh',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '111.0',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'volume',
|
||||
'friendly_name': 'Heat Meter Volume usage previous year',
|
||||
'icon': 'mdi:fire',
|
||||
'unit_of_measurement': <UnitOfVolume.CUBIC_METERS: 'm³'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_volume_usage_previous_year',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Heat Meter Ownership number',
|
||||
'icon': 'mdi:identifier',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_ownership_number',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Heat Meter Error number',
|
||||
'icon': 'mdi:home-alert',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_error_number',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Heat Meter Device number',
|
||||
'icon': 'mdi:identifier',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_device_number',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'devicenr_789',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'duration',
|
||||
'friendly_name': 'Heat Meter Measurement period minutes',
|
||||
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_measurement_period_minutes',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'power',
|
||||
'friendly_name': 'Heat Meter Power max',
|
||||
'unit_of_measurement': <UnitOfPower.KILO_WATT: 'kW'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_power_max',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'power',
|
||||
'friendly_name': 'Heat Meter Power max previous year',
|
||||
'unit_of_measurement': <UnitOfPower.KILO_WATT: 'kW'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_power_max_previous_year',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Heat Meter Flowrate max',
|
||||
'icon': 'mdi:water-outline',
|
||||
'unit_of_measurement': <UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR: 'm³/h'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_flowrate_max',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Heat Meter Flowrate max previous year',
|
||||
'icon': 'mdi:water-outline',
|
||||
'unit_of_measurement': <UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR: 'm³/h'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_flowrate_max_previous_year',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'temperature',
|
||||
'friendly_name': 'Heat Meter Return temperature max',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_return_temperature_max',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'temperature',
|
||||
'friendly_name': 'Heat Meter Return temperature max previous year',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_return_temperature_max_previous_year',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'temperature',
|
||||
'friendly_name': 'Heat Meter Flow temperature max',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_flow_temperature_max',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'temperature',
|
||||
'friendly_name': 'Heat Meter Flow temperature max previous year',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_flow_temperature_max_previous_year',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'duration',
|
||||
'friendly_name': 'Heat Meter Operating hours',
|
||||
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_operating_hours',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'duration',
|
||||
'friendly_name': 'Heat Meter Flow hours',
|
||||
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_flow_hours',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'duration',
|
||||
'friendly_name': 'Heat Meter Fault hours',
|
||||
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_fault_hours',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'duration',
|
||||
'friendly_name': 'Heat Meter Fault hours previous year',
|
||||
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_fault_hours_previous_year',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Heat Meter Yearly set day',
|
||||
'icon': 'mdi:clock-outline',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_yearly_set_day',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Heat Meter Monthly set day',
|
||||
'icon': 'mdi:clock-outline',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_monthly_set_day',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'timestamp',
|
||||
'friendly_name': 'Heat Meter Meter date time',
|
||||
'icon': 'mdi:clock-outline',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_meter_meter_date_time',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2022-05-19T19:41:17+00:00',
|
||||
}),
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
|
@ -3,6 +3,7 @@ from dataclasses import dataclass
|
||||
import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
import serial
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
@ -25,19 +26,49 @@ API_HEAT_METER_SERVICE = (
|
||||
class MockHeatMeterResponse:
|
||||
"""Mock for HeatMeterResponse."""
|
||||
|
||||
heat_usage_gj: float
|
||||
heat_usage_gj: float | None
|
||||
heat_usage_mwh: float | None
|
||||
volume_usage_m3: float
|
||||
heat_previous_year_gj: float
|
||||
heat_previous_year_gj: float | None
|
||||
heat_previous_year_mwh: float | None
|
||||
device_number: str
|
||||
meter_date_time: datetime.datetime
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"mock_heat_meter_response",
|
||||
[
|
||||
{
|
||||
"heat_usage_gj": 123.0,
|
||||
"heat_usage_mwh": None,
|
||||
"volume_usage_m3": 456.0,
|
||||
"heat_previous_year_gj": 111.0,
|
||||
"heat_previous_year_mwh": None,
|
||||
"device_number": "devicenr_789",
|
||||
"meter_date_time": dt_util.as_utc(
|
||||
datetime.datetime(2022, 5, 19, 19, 41, 17)
|
||||
),
|
||||
},
|
||||
{
|
||||
"heat_usage_gj": None,
|
||||
"heat_usage_mwh": 123.0,
|
||||
"volume_usage_m3": 456.0,
|
||||
"heat_previous_year_gj": None,
|
||||
"heat_previous_year_mwh": 111.0,
|
||||
"device_number": "devicenr_789",
|
||||
"meter_date_time": dt_util.as_utc(
|
||||
datetime.datetime(2022, 5, 19, 19, 41, 17)
|
||||
),
|
||||
},
|
||||
],
|
||||
)
|
||||
@patch(API_HEAT_METER_SERVICE)
|
||||
async def test_create_sensors(
|
||||
mock_heat_meter,
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
snapshot: SnapshotAssertion,
|
||||
mock_heat_meter_response,
|
||||
) -> None:
|
||||
"""Test sensor."""
|
||||
entry_data = {
|
||||
@ -48,13 +79,7 @@ async def test_create_sensors(
|
||||
mock_entry = MockConfigEntry(domain=DOMAIN, unique_id=DOMAIN, data=entry_data)
|
||||
mock_entry.add_to_hass(hass)
|
||||
|
||||
mock_heat_meter_response = MockHeatMeterResponse(
|
||||
heat_usage_gj=123.0,
|
||||
volume_usage_m3=456.0,
|
||||
heat_previous_year_gj=111.0,
|
||||
device_number="devicenr_789",
|
||||
meter_date_time=dt_util.as_utc(datetime.datetime(2022, 5, 19, 19, 41, 17)),
|
||||
)
|
||||
mock_heat_meter_response = MockHeatMeterResponse(**mock_heat_meter_response)
|
||||
|
||||
mock_heat_meter().read.return_value = mock_heat_meter_response
|
||||
|
||||
@ -79,8 +104,10 @@ async def test_exception_on_polling(mock_heat_meter, hass: HomeAssistant) -> Non
|
||||
# First setup normally
|
||||
mock_heat_meter_response = MockHeatMeterResponse(
|
||||
heat_usage_gj=123.0,
|
||||
heat_usage_mwh=None,
|
||||
volume_usage_m3=456.0,
|
||||
heat_previous_year_gj=111.0,
|
||||
heat_previous_year_mwh=None,
|
||||
device_number="devicenr_789",
|
||||
meter_date_time=dt_util.as_utc(datetime.datetime(2022, 5, 19, 19, 41, 17)),
|
||||
)
|
||||
@ -106,8 +133,10 @@ async def test_exception_on_polling(mock_heat_meter, hass: HomeAssistant) -> Non
|
||||
# Now 'enable' and see if next poll succeeds
|
||||
mock_heat_meter_response = MockHeatMeterResponse(
|
||||
heat_usage_gj=124.0,
|
||||
heat_usage_mwh=None,
|
||||
volume_usage_m3=457.0,
|
||||
heat_previous_year_gj=112.0,
|
||||
heat_previous_year_mwh=None,
|
||||
device_number="devicenr_789",
|
||||
meter_date_time=dt_util.as_utc(datetime.datetime(2022, 5, 19, 20, 41, 17)),
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user