diff --git a/homeassistant/components/landisgyr_heat_meter/sensor.py b/homeassistant/components/landisgyr_heat_meter/sensor.py index 244515a07d4..947ab2b2a8c 100644 --- a/homeassistant/components/landisgyr_heat_meter/sensor.py +++ b/homeassistant/components/landisgyr_heat_meter/sensor.py @@ -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.""" diff --git a/tests/components/landisgyr_heat_meter/snapshots/test_sensor.ambr b/tests/components/landisgyr_heat_meter/snapshots/test_sensor.ambr index 9c62ca3f94b..d3ab9d5ade0 100644 --- a/tests/components/landisgyr_heat_meter/snapshots/test_sensor.ambr +++ b/tests/components/landisgyr_heat_meter/snapshots/test_sensor.ambr @@ -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': , 'last_updated': , - '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': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_measuring_range', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Heat Meter Settings and firmware', + }), + 'context': , + 'entity_id': 'sensor.heat_meter_settings_and_firmware', + 'last_changed': , + 'last_updated': , + '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': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_heat_usage_mwh', + 'last_changed': , + 'last_updated': , + 'state': '123.0', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'volume', + 'friendly_name': 'Heat Meter Volume usage', + 'icon': 'mdi:fire', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_volume_usage', + 'last_changed': , + 'last_updated': , + 'state': '456.0', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'energy', + 'friendly_name': 'Heat Meter Heat previous year MWh', + 'icon': 'mdi:fire', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_heat_previous_year_mwh', + 'last_changed': , + 'last_updated': , + 'state': '111.0', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'volume', + 'friendly_name': 'Heat Meter Volume usage previous year', + 'icon': 'mdi:fire', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_volume_usage_previous_year', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Heat Meter Ownership number', + 'icon': 'mdi:identifier', + }), + 'context': , + 'entity_id': 'sensor.heat_meter_ownership_number', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Heat Meter Error number', + 'icon': 'mdi:home-alert', + }), + 'context': , + 'entity_id': 'sensor.heat_meter_error_number', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Heat Meter Device number', + 'icon': 'mdi:identifier', + }), + 'context': , + 'entity_id': 'sensor.heat_meter_device_number', + 'last_changed': , + 'last_updated': , + 'state': 'devicenr_789', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'duration', + 'friendly_name': 'Heat Meter Measurement period minutes', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_measurement_period_minutes', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'power', + 'friendly_name': 'Heat Meter Power max', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_power_max', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'power', + 'friendly_name': 'Heat Meter Power max previous year', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_power_max_previous_year', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Heat Meter Flowrate max', + 'icon': 'mdi:water-outline', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_flowrate_max', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Heat Meter Flowrate max previous year', + 'icon': 'mdi:water-outline', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_flowrate_max_previous_year', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'temperature', + 'friendly_name': 'Heat Meter Return temperature max', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_return_temperature_max', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'temperature', + 'friendly_name': 'Heat Meter Return temperature max previous year', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_return_temperature_max_previous_year', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'temperature', + 'friendly_name': 'Heat Meter Flow temperature max', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_flow_temperature_max', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'temperature', + 'friendly_name': 'Heat Meter Flow temperature max previous year', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_flow_temperature_max_previous_year', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'duration', + 'friendly_name': 'Heat Meter Operating hours', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_operating_hours', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'duration', + 'friendly_name': 'Heat Meter Flow hours', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_flow_hours', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'duration', + 'friendly_name': 'Heat Meter Fault hours', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_fault_hours', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'duration', + 'friendly_name': 'Heat Meter Fault hours previous year', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.heat_meter_fault_hours_previous_year', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Heat Meter Yearly set day', + 'icon': 'mdi:clock-outline', + }), + 'context': , + 'entity_id': 'sensor.heat_meter_yearly_set_day', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Heat Meter Monthly set day', + 'icon': 'mdi:clock-outline', + }), + 'context': , + 'entity_id': 'sensor.heat_meter_monthly_set_day', + 'last_changed': , + 'last_updated': , + 'state': 'unknown', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'timestamp', + 'friendly_name': 'Heat Meter Meter date time', + 'icon': 'mdi:clock-outline', + }), + 'context': , + 'entity_id': 'sensor.heat_meter_meter_date_time', + 'last_changed': , + 'last_updated': , + 'state': '2022-05-19T19:41:17+00:00', }), StateSnapshot({ 'attributes': ReadOnlyDict({ diff --git a/tests/components/landisgyr_heat_meter/test_sensor.py b/tests/components/landisgyr_heat_meter/test_sensor.py index 4de58a206e6..9f4ad241245 100644 --- a/tests/components/landisgyr_heat_meter/test_sensor.py +++ b/tests/components/landisgyr_heat_meter/test_sensor.py @@ -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)), )