diff --git a/homeassistant/components/homewizard/sensor.py b/homeassistant/components/homewizard/sensor.py index 177fc3ef176..f8a5b3b144a 100644 --- a/homeassistant/components/homewizard/sensor.py +++ b/homeassistant/components/homewizard/sensor.py @@ -5,9 +5,10 @@ from collections.abc import Callable from dataclasses import dataclass from typing import Final -from homewizard_energy.models import Data +from homewizard_energy.models import Data, ExternalDevice from homeassistant.components.sensor import ( + DEVICE_CLASS_UNITS, SensorDeviceClass, SensorEntity, SensorEntityDescription, @@ -15,8 +16,10 @@ from homeassistant.components.sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( + ATTR_VIA_DEVICE, PERCENTAGE, EntityCategory, + Platform, UnitOfElectricCurrent, UnitOfElectricPotential, UnitOfEnergy, @@ -25,6 +28,8 @@ from homeassistant.const import ( UnitOfVolume, ) from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er +from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import StateType @@ -44,6 +49,14 @@ class HomeWizardSensorEntityDescription(SensorEntityDescription): value_fn: Callable[[Data], StateType] +@dataclass(frozen=True, kw_only=True) +class HomeWizardExternalSensorEntityDescription(SensorEntityDescription): + """Class describing HomeWizard sensor entities.""" + + suggested_device_class: SensorDeviceClass + device_name: str + + SENSORS: Final[tuple[HomeWizardSensorEntityDescription, ...]] = ( HomeWizardSensorEntityDescription( key="smr_version", @@ -378,22 +391,6 @@ SENSORS: Final[tuple[HomeWizardSensorEntityDescription, ...]] = ( has_fn=lambda data: data.monthly_power_peak_w is not None, value_fn=lambda data: data.monthly_power_peak_w, ), - HomeWizardSensorEntityDescription( - key="total_gas_m3", - translation_key="total_gas_m3", - native_unit_of_measurement=UnitOfVolume.CUBIC_METERS, - device_class=SensorDeviceClass.GAS, - state_class=SensorStateClass.TOTAL_INCREASING, - has_fn=lambda data: data.total_gas_m3 is not None, - value_fn=lambda data: data.total_gas_m3, - ), - HomeWizardSensorEntityDescription( - key="gas_unique_id", - translation_key="gas_unique_id", - entity_category=EntityCategory.DIAGNOSTIC, - has_fn=lambda data: data.gas_unique_id is not None, - value_fn=lambda data: data.gas_unique_id, - ), HomeWizardSensorEntityDescription( key="active_liter_lpm", translation_key="active_liter_lpm", @@ -414,16 +411,86 @@ SENSORS: Final[tuple[HomeWizardSensorEntityDescription, ...]] = ( ) +EXTERNAL_SENSORS = { + ExternalDevice.DeviceType.GAS_METER: HomeWizardExternalSensorEntityDescription( + key="gas_meter", + translation_key="total_gas_m3", + suggested_device_class=SensorDeviceClass.GAS, + state_class=SensorStateClass.TOTAL_INCREASING, + device_name="Gas meter", + ), + ExternalDevice.DeviceType.HEAT_METER: HomeWizardExternalSensorEntityDescription( + key="heat_meter", + translation_key="total_energy_gj", + suggested_device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + device_name="Heat meter", + ), + ExternalDevice.DeviceType.WARM_WATER_METER: HomeWizardExternalSensorEntityDescription( + key="warm_water_meter", + translation_key="total_liter_m3", + suggested_device_class=SensorDeviceClass.WATER, + state_class=SensorStateClass.TOTAL_INCREASING, + device_name="Warm water meter", + ), + ExternalDevice.DeviceType.WATER_METER: HomeWizardExternalSensorEntityDescription( + key="water_meter", + translation_key="total_liter_m3", + suggested_device_class=SensorDeviceClass.WATER, + state_class=SensorStateClass.TOTAL_INCREASING, + device_name="Water meter", + ), + ExternalDevice.DeviceType.INLET_HEAT_METER: HomeWizardExternalSensorEntityDescription( + key="inlet_heat_meter", + translation_key="total_energy_gj", + suggested_device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, + device_name="Inlet heat meter", + ), +} + + async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Initialize sensors.""" coordinator: HWEnergyDeviceUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] - async_add_entities( + + # Migrate original gas meter sensor to ExternalDevice + ent_reg = er.async_get(hass) + + if ( + entity_id := ent_reg.async_get_entity_id( + Platform.SENSOR, DOMAIN, f"{entry.unique_id}_total_gas_m3" + ) + ) and coordinator.data.data.gas_unique_id is not None: + ent_reg.async_update_entity( + entity_id, + new_unique_id=f"{DOMAIN}_{coordinator.data.data.gas_unique_id}", + ) + + # Remove old gas_unique_id sensor + if entity_id := ent_reg.async_get_entity_id( + Platform.SENSOR, DOMAIN, f"{entry.unique_id}_gas_unique_id" + ): + ent_reg.async_remove(entity_id) + + # Initialize default sensors + entities: list = [ HomeWizardSensorEntity(coordinator, description) for description in SENSORS if description.has_fn(coordinator.data.data) - ) + ] + + # Initialize external devices + if coordinator.data.data.external_devices is not None: + for unique_id, device in coordinator.data.data.external_devices.items(): + if description := EXTERNAL_SENSORS.get(device.meter_type): + entities.append( + HomeWizardExternalSensorEntity(coordinator, description, unique_id) + ) + + async_add_entities(entities) class HomeWizardSensorEntity(HomeWizardEntity, SensorEntity): @@ -452,3 +519,74 @@ class HomeWizardSensorEntity(HomeWizardEntity, SensorEntity): def available(self) -> bool: """Return availability of meter.""" return super().available and self.native_value is not None + + +class HomeWizardExternalSensorEntity(HomeWizardEntity, SensorEntity): + """Representation of externally connected HomeWizard Sensor.""" + + def __init__( + self, + coordinator: HWEnergyDeviceUpdateCoordinator, + description: HomeWizardExternalSensorEntityDescription, + device_unique_id: str, + ) -> None: + """Initialize Externally connected HomeWizard Sensors.""" + super().__init__(coordinator) + self.entity_description = description + self._device_id = device_unique_id + self._suggested_device_class = description.suggested_device_class + self._attr_unique_id = f"{DOMAIN}_{device_unique_id}" + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, device_unique_id)}, + name=description.device_name, + manufacturer="HomeWizard", + model=coordinator.data.device.product_type, + serial_number=device_unique_id, + ) + if coordinator.data.device.serial is not None: + self._attr_device_info[ATTR_VIA_DEVICE] = ( + DOMAIN, + coordinator.data.device.serial, + ) + + @property + def native_value(self) -> float | int | str | None: + """Return the sensor value.""" + return self.device.value if self.device is not None else None + + @property + def device(self) -> ExternalDevice | None: + """Return ExternalDevice object.""" + return ( + self.coordinator.data.data.external_devices[self._device_id] + if self.coordinator.data.data.external_devices is not None + else None + ) + + @property + def available(self) -> bool: + """Return availability of meter.""" + return super().available and self.device is not None + + @property + def native_unit_of_measurement(self) -> str | None: + """Return unit of measurement based on device unit.""" + if (device := self.device) is None: + return None + + # API returns 'm3' but we expect m³ + if device.unit == "m3": + return UnitOfVolume.CUBIC_METERS + + return device.unit + + @property + def device_class(self) -> SensorDeviceClass | None: + """Validate unit of measurement and set device class.""" + if ( + self.native_unit_of_measurement + not in DEVICE_CLASS_UNITS[self._suggested_device_class] + ): + return None + + return self._suggested_device_class diff --git a/homeassistant/components/homewizard/strings.json b/homeassistant/components/homewizard/strings.json index acdb321d6ff..d3cf8f88bed 100644 --- a/homeassistant/components/homewizard/strings.json +++ b/homeassistant/components/homewizard/strings.json @@ -149,14 +149,17 @@ "total_gas_m3": { "name": "Total gas" }, - "gas_unique_id": { - "name": "Gas meter identifier" + "meter_identifier": { + "name": "Meter identifier" }, "active_liter_lpm": { "name": "Active water usage" }, "total_liter_m3": { "name": "Total water usage" + }, + "total_energy_gj": { + "name": "Total heat energy" } }, "switch": { diff --git a/tests/components/homewizard/fixtures/HWE-P1/data.json b/tests/components/homewizard/fixtures/HWE-P1/data.json index 2eb7e3e430b..b221ad6f804 100644 --- a/tests/components/homewizard/fixtures/HWE-P1/data.json +++ b/tests/components/homewizard/fixtures/HWE-P1/data.json @@ -41,5 +41,42 @@ "montly_power_peak_w": 1111.0, "montly_power_peak_timestamp": 230101080010, "active_liter_lpm": 12.345, - "total_liter_m3": 1234.567 + "total_liter_m3": 1234.567, + "external": [ + { + "unique_id": "47303031", + "type": "gas_meter", + "timestamp": 230125220957, + "value": 111.111, + "unit": "m3" + }, + { + "unique_id": "57303031", + "type": "water_meter", + "timestamp": 230125220957, + "value": 222.222, + "unit": "m3" + }, + { + "unique_id": "5757303031", + "type": "warm_water_meter", + "timestamp": 230125220957, + "value": 333.333, + "unit": "m3" + }, + { + "unique_id": "48303031", + "type": "heat_meter", + "timestamp": 230125220957, + "value": 444.444, + "unit": "GJ" + }, + { + "unique_id": "4948303031", + "type": "inlet_heat_meter", + "timestamp": 230125220957, + "value": 555.555, + "unit": "m3" + } + ] } diff --git a/tests/components/homewizard/snapshots/test_diagnostics.ambr b/tests/components/homewizard/snapshots/test_diagnostics.ambr index bddac0a79dc..e1fdfcf7c12 100644 --- a/tests/components/homewizard/snapshots/test_diagnostics.ambr +++ b/tests/components/homewizard/snapshots/test_diagnostics.ambr @@ -32,7 +32,58 @@ 'active_voltage_l3_v': 230.333, 'active_voltage_v': None, 'any_power_fail_count': 4, - 'external_devices': None, + 'external_devices': dict({ + 'G001': dict({ + 'meter_type': dict({ + '__type': "", + 'repr': '', + }), + 'timestamp': '2023-01-25T22:09:57', + 'unique_id': '**REDACTED**', + 'unit': 'm3', + 'value': 111.111, + }), + 'H001': dict({ + 'meter_type': dict({ + '__type': "", + 'repr': '', + }), + 'timestamp': '2023-01-25T22:09:57', + 'unique_id': '**REDACTED**', + 'unit': 'GJ', + 'value': 444.444, + }), + 'IH001': dict({ + 'meter_type': dict({ + '__type': "", + 'repr': '', + }), + 'timestamp': '2023-01-25T22:09:57', + 'unique_id': '**REDACTED**', + 'unit': 'm3', + 'value': 555.555, + }), + 'W001': dict({ + 'meter_type': dict({ + '__type': "", + 'repr': '', + }), + 'timestamp': '2023-01-25T22:09:57', + 'unique_id': '**REDACTED**', + 'unit': 'm3', + 'value': 222.222, + }), + 'WW001': dict({ + 'meter_type': dict({ + '__type': "", + 'repr': '', + }), + 'timestamp': '2023-01-25T22:09:57', + 'unique_id': '**REDACTED**', + 'unit': 'm3', + 'value': 333.333, + }), + }), 'gas_timestamp': '2021-03-14T11:22:33', 'gas_unique_id': '**REDACTED**', 'long_power_fail_count': 5, diff --git a/tests/components/homewizard/snapshots/test_sensor.ambr b/tests/components/homewizard/snapshots/test_sensor.ambr index 032972a7901..7d98a10089f 100644 --- a/tests/components/homewizard/snapshots/test_sensor.ambr +++ b/tests/components/homewizard/snapshots/test_sensor.ambr @@ -1,4 +1,221 @@ # serializer version: 1 +# name: test_gas_meter_migrated[HWE-P1-unique_ids0][sensor.homewizard_aabbccddeeff_gas_unique_id:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.homewizard_aabbccddeeff_gas_unique_id', + 'has_entity_name': False, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': 'aabbccddeeff_gas_unique_id', + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'homewizard_01FFEEDDCCBBAA99887766554433221100_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_gas_meter_migrated[HWE-P1-unique_ids0][sensor.homewizard_aabbccddeeff_total_gas_m3:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.homewizard_aabbccddeeff_total_gas_m3', + 'has_entity_name': False, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': 'aabbccddeeff_total_gas_m3', + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'homewizard_01FFEEDDCCBBAA99887766554433221100', + 'unit_of_measurement': None, + }) +# --- +# name: test_gas_meter_migrated[aabbccddeeff_gas_unique_id][sensor.homewizard_a:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.homewizard_a', + 'has_entity_name': False, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'a', + 'unit_of_measurement': None, + }) +# --- +# name: test_gas_meter_migrated[aabbccddeeff_gas_unique_id][sensor.homewizard_aabbccddeeff_gas_unique_id:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.homewizard_aabbccddeeff_gas_unique_id', + 'has_entity_name': False, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': 'aabbccddeeff_gas_unique_id', + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'homewizard_01FFEEDDCCBBAA99887766554433221100_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_gas_meter_migrated[aabbccddeeff_total_gas_m3][sensor.homewizard_a:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.homewizard_a', + 'has_entity_name': False, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'a', + 'unit_of_measurement': None, + }) +# --- +# name: test_gas_meter_migrated[aabbccddeeff_total_gas_m3][sensor.homewizard_aabbccddeeff_total_gas_m3:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.homewizard_aabbccddeeff_total_gas_m3', + 'has_entity_name': False, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': 'aabbccddeeff_total_gas_m3', + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'homewizard_01FFEEDDCCBBAA99887766554433221100', + 'unit_of_measurement': None, + }) +# --- +# name: test_gas_meter_migrated[sensor.homewizard_aabbccddeeff_total_gas_m3:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.homewizard_aabbccddeeff_total_gas_m3', + 'has_entity_name': False, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': 'aabbccddeeff_total_gas_m3', + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'homewizard_01FFEEDDCCBBAA99887766554433221100', + 'unit_of_measurement': None, + }) +# --- # name: test_sensors[HWE-P1-entity_ids0][sensor.device_active_average_demand:device-registry] DeviceRegistryEntrySnapshot({ 'area_id': None, @@ -3227,6 +3444,745 @@ 'state': '100', }) # --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.gas_meter:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'G001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Gas meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.gas_meter:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.gas_meter', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': 'mdi:alphabetical-variant', + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'meter_identifier', + 'unique_id': 'homewizard_G001_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.gas_meter:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Gas meter', + 'icon': 'mdi:alphabetical-variant', + }), + 'context': , + 'entity_id': 'sensor.gas_meter', + 'last_changed': , + 'last_updated': , + 'state': 'G001', + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.gas_meter_total_gas:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'G001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Gas meter', + 'name_by_user': None, + 'serial_number': 'G001', + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.gas_meter_total_gas:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.gas_meter_total_gas', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Total gas', + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'total_gas_m3', + 'unique_id': 'homewizard_G001', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.gas_meter_total_gas:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'gas', + 'friendly_name': 'Gas meter Total gas', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.gas_meter_total_gas', + 'last_changed': , + 'last_updated': , + 'state': '111.111', + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.heat_meter:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'H001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Heat meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.heat_meter:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.heat_meter', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': 'mdi:alphabetical-variant', + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'meter_identifier', + 'unique_id': 'homewizard_H001_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.heat_meter:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Heat meter', + 'icon': 'mdi:alphabetical-variant', + }), + 'context': , + 'entity_id': 'sensor.heat_meter', + 'last_changed': , + 'last_updated': , + 'state': 'H001', + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.heat_meter_total_heat_energy:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'H001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Heat meter', + 'name_by_user': None, + 'serial_number': 'H001', + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.heat_meter_total_heat_energy:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.heat_meter_total_heat_energy', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Total heat energy', + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'total_energy_gj', + 'unique_id': 'homewizard_H001', + 'unit_of_measurement': 'GJ', + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.heat_meter_total_heat_energy:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'energy', + 'friendly_name': 'Heat meter Total heat energy', + 'state_class': , + 'unit_of_measurement': 'GJ', + }), + 'context': , + 'entity_id': 'sensor.heat_meter_total_heat_energy', + 'last_changed': , + 'last_updated': , + 'state': '444.444', + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.inlet_heat_meter:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'IH001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Inlet heat meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.inlet_heat_meter:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.inlet_heat_meter', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': 'mdi:alphabetical-variant', + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'meter_identifier', + 'unique_id': 'homewizard_IH001_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.inlet_heat_meter:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Inlet heat meter', + 'icon': 'mdi:alphabetical-variant', + }), + 'context': , + 'entity_id': 'sensor.inlet_heat_meter', + 'last_changed': , + 'last_updated': , + 'state': 'IH001', + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.inlet_heat_meter_total_heat_energy:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'IH001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Inlet heat meter', + 'name_by_user': None, + 'serial_number': 'IH001', + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.inlet_heat_meter_total_heat_energy:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.inlet_heat_meter_total_heat_energy', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Total heat energy', + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'total_energy_gj', + 'unique_id': 'homewizard_IH001', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.inlet_heat_meter_total_heat_energy:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Inlet heat meter Total heat energy', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.inlet_heat_meter_total_heat_energy', + 'last_changed': , + 'last_updated': , + 'state': '555.555', + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.warm_water_meter:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'WW001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Warm water meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.warm_water_meter:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.warm_water_meter', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': 'mdi:alphabetical-variant', + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'meter_identifier', + 'unique_id': 'homewizard_WW001_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.warm_water_meter:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Warm water meter', + 'icon': 'mdi:alphabetical-variant', + }), + 'context': , + 'entity_id': 'sensor.warm_water_meter', + 'last_changed': , + 'last_updated': , + 'state': 'WW001', + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.warm_water_meter_total_water_usage:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'WW001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Warm water meter', + 'name_by_user': None, + 'serial_number': 'WW001', + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.warm_water_meter_total_water_usage:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.warm_water_meter_total_water_usage', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Total water usage', + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'total_liter_m3', + 'unique_id': 'homewizard_WW001', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.warm_water_meter_total_water_usage:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'water', + 'friendly_name': 'Warm water meter Total water usage', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.warm_water_meter_total_water_usage', + 'last_changed': , + 'last_updated': , + 'state': '333.333', + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.water_meter:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'W001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Water meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.water_meter:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.water_meter', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': 'mdi:alphabetical-variant', + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'meter_identifier', + 'unique_id': 'homewizard_W001_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.water_meter:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Water meter', + 'icon': 'mdi:alphabetical-variant', + }), + 'context': , + 'entity_id': 'sensor.water_meter', + 'last_changed': , + 'last_updated': , + 'state': 'W001', + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.water_meter_total_water_usage:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'W001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Water meter', + 'name_by_user': None, + 'serial_number': 'W001', + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.water_meter_total_water_usage:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.water_meter_total_water_usage', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Total water usage', + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'total_liter_m3', + 'unique_id': 'homewizard_W001', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors[HWE-P1-entity_ids0][sensor.water_meter_total_water_usage:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'water', + 'friendly_name': 'Water meter Total water usage', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.water_meter_total_water_usage', + 'last_changed': , + 'last_updated': , + 'state': '222.222', + }) +# --- # name: test_sensors[HWE-P1-zero-values-entity_ids1][sensor.device_active_average_demand:device-registry] DeviceRegistryEntrySnapshot({ 'area_id': None, @@ -7831,3 +8787,889 @@ 'state': '92', }) # --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.gas_meter:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'G001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Gas meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.gas_meter:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.gas_meter', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': 'mdi:alphabetical-variant', + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'meter_identifier', + 'unique_id': 'homewizard_G001_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.gas_meter:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Gas meter', + 'icon': 'mdi:alphabetical-variant', + }), + 'context': , + 'entity_id': 'sensor.gas_meter', + 'last_changed': , + 'last_updated': , + 'state': 'G001', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.gas_meter_2:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'unknown_unit', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Gas meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.gas_meter_2:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.gas_meter_2', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': 'mdi:alphabetical-variant', + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'meter_identifier', + 'unique_id': 'homewizard_unknown_unit_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.gas_meter_2:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Gas meter', + 'icon': 'mdi:alphabetical-variant', + }), + 'context': , + 'entity_id': 'sensor.gas_meter_2', + 'last_changed': , + 'last_updated': , + 'state': 'unknown_unit', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.gas_meter_total_gas:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'G001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Gas meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.gas_meter_total_gas:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.gas_meter_total_gas', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Total gas', + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'total_gas_m3', + 'unique_id': 'homewizard_G001', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.gas_meter_total_gas:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'gas', + 'friendly_name': 'Gas meter Total gas', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.gas_meter_total_gas', + 'last_changed': , + 'last_updated': , + 'state': '111.111', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.gas_meter_total_gas_2:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'unknown_unit', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Gas meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.gas_meter_total_gas_2:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.gas_meter_total_gas_2', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Total gas', + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'total_gas_m3', + 'unique_id': 'homewizard_unknown_unit', + 'unit_of_measurement': 'cats', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.gas_meter_total_gas_2:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Gas meter Total gas', + 'state_class': , + 'unit_of_measurement': 'cats', + }), + 'context': , + 'entity_id': 'sensor.gas_meter_total_gas_2', + 'last_changed': , + 'last_updated': , + 'state': '666.666', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.heat_meter:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'H001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Heat meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.heat_meter:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.heat_meter', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': 'mdi:alphabetical-variant', + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'meter_identifier', + 'unique_id': 'homewizard_H001_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.heat_meter:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Heat meter', + 'icon': 'mdi:alphabetical-variant', + }), + 'context': , + 'entity_id': 'sensor.heat_meter', + 'last_changed': , + 'last_updated': , + 'state': 'H001', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.heat_meter_total_heat_energy:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'H001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Heat meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.heat_meter_total_heat_energy:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.heat_meter_total_heat_energy', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Total heat energy', + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'total_energy_gj', + 'unique_id': 'homewizard_H001', + 'unit_of_measurement': 'GJ', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.heat_meter_total_heat_energy:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'energy', + 'friendly_name': 'Heat meter Total heat energy', + 'state_class': , + 'unit_of_measurement': 'GJ', + }), + 'context': , + 'entity_id': 'sensor.heat_meter_total_heat_energy', + 'last_changed': , + 'last_updated': , + 'state': '444.444', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.inlet_heat_meter:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'IH001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Inlet heat meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.inlet_heat_meter:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.inlet_heat_meter', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': 'mdi:alphabetical-variant', + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'meter_identifier', + 'unique_id': 'homewizard_IH001_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.inlet_heat_meter:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Inlet heat meter', + 'icon': 'mdi:alphabetical-variant', + }), + 'context': , + 'entity_id': 'sensor.inlet_heat_meter', + 'last_changed': , + 'last_updated': , + 'state': 'IH001', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.inlet_heat_meter_total_heat_energy:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'IH001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Inlet heat meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.inlet_heat_meter_total_heat_energy:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.inlet_heat_meter_total_heat_energy', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Total heat energy', + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'total_energy_gj', + 'unique_id': 'homewizard_IH001', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.inlet_heat_meter_total_heat_energy:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Inlet heat meter Total heat energy', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.inlet_heat_meter_total_heat_energy', + 'last_changed': , + 'last_updated': , + 'state': '555.555', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.warm_water_meter:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'WW001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Warm water meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.warm_water_meter:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.warm_water_meter', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': 'mdi:alphabetical-variant', + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'meter_identifier', + 'unique_id': 'homewizard_WW001_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.warm_water_meter:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Warm water meter', + 'icon': 'mdi:alphabetical-variant', + }), + 'context': , + 'entity_id': 'sensor.warm_water_meter', + 'last_changed': , + 'last_updated': , + 'state': 'WW001', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.warm_water_meter_total_water_usage:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'WW001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Warm water meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.warm_water_meter_total_water_usage:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.warm_water_meter_total_water_usage', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Total water usage', + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'total_liter_m3', + 'unique_id': 'homewizard_WW001', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.warm_water_meter_total_water_usage:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'water', + 'friendly_name': 'Warm water meter Total water usage', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.warm_water_meter_total_water_usage', + 'last_changed': , + 'last_updated': , + 'state': '333.333', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.water_meter:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'W001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Water meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.water_meter:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.water_meter', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': 'mdi:alphabetical-variant', + 'original_name': None, + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'meter_identifier', + 'unique_id': 'homewizard_W001_meter_identifier', + 'unit_of_measurement': None, + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.water_meter:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Water meter', + 'icon': 'mdi:alphabetical-variant', + }), + 'context': , + 'entity_id': 'sensor.water_meter', + 'last_changed': , + 'last_updated': , + 'state': 'W001', + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.water_meter_total_water_usage:device-registry] + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'homewizard', + 'W001', + ), + }), + 'is_new': False, + 'manufacturer': 'HomeWizard', + 'model': 'HWE-P1', + 'name': 'Water meter', + 'name_by_user': None, + 'serial_number': None, + 'suggested_area': None, + 'sw_version': None, + 'via_device_id': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.water_meter_total_water_usage:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.water_meter_total_water_usage', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Total water usage', + 'platform': 'homewizard', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'total_liter_m3', + 'unique_id': 'homewizard_W001', + 'unit_of_measurement': , + }) +# --- +# name: test_sensors_external_devices[HWE-P1-entity_ids0][sensor.water_meter_total_water_usage:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'water', + 'friendly_name': 'Water meter Total water usage', + 'state_class': , + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.water_meter_total_water_usage', + 'last_changed': , + 'last_updated': , + 'state': '222.222', + }) +# --- diff --git a/tests/components/homewizard/test_sensor.py b/tests/components/homewizard/test_sensor.py index 7e59769a768..214e1db706b 100644 --- a/tests/components/homewizard/test_sensor.py +++ b/tests/components/homewizard/test_sensor.py @@ -3,16 +3,18 @@ from unittest.mock import MagicMock from homewizard_energy.errors import DisabledError, RequestError +from homewizard_energy.models import Data import pytest from syrupy.assertion import SnapshotAssertion +from homeassistant.components.homewizard import DOMAIN from homeassistant.components.homewizard.const import UPDATE_INTERVAL -from homeassistant.const import STATE_UNAVAILABLE +from homeassistant.const import STATE_UNAVAILABLE, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr, entity_registry as er import homeassistant.util.dt as dt_util -from tests.common import async_fire_time_changed +from tests.common import MockConfigEntry, async_fire_time_changed pytestmark = [ pytest.mark.usefixtures("init_integration"), @@ -63,10 +65,13 @@ pytestmark = [ "sensor.device_long_power_failures_detected", "sensor.device_active_average_demand", "sensor.device_peak_demand_current_month", - "sensor.device_total_gas", - "sensor.device_gas_meter_identifier", "sensor.device_active_water_usage", "sensor.device_total_water_usage", + "sensor.gas_meter_total_gas", + "sensor.water_meter_total_water_usage", + "sensor.warm_water_meter_total_water_usage", + "sensor.heat_meter_total_heat_energy", + "sensor.inlet_heat_meter_total_heat_energy", ], ), ( @@ -102,8 +107,6 @@ pytestmark = [ "sensor.device_power_failures_detected", "sensor.device_long_power_failures_detected", "sensor.device_active_average_demand", - "sensor.device_peak_demand_current_month", - "sensor.device_total_gas", "sensor.device_active_water_usage", "sensor.device_total_water_usage", ], @@ -256,6 +259,22 @@ async def test_sensors_unreachable( assert state.state == STATE_UNAVAILABLE +async def test_external_sensors_unreachable( + hass: HomeAssistant, + mock_homewizardenergy: MagicMock, +) -> None: + """Test external device sensor handles API unreachable.""" + assert (state := hass.states.get("sensor.gas_meter_total_gas")) + assert state.state == "111.111" + + mock_homewizardenergy.data.return_value = Data.from_dict({}) + async_fire_time_changed(hass, dt_util.utcnow() + UPDATE_INTERVAL) + await hass.async_block_till_done() + + assert (state := hass.states.get(state.entity_id)) + assert state.state == STATE_UNAVAILABLE + + @pytest.mark.parametrize( ("device_fixture", "entity_ids"), [ @@ -275,7 +294,6 @@ async def test_sensors_unreachable( "sensor.device_active_voltage_phase_3", "sensor.device_active_water_usage", "sensor.device_dsmr_version", - "sensor.device_gas_meter_identifier", "sensor.device_long_power_failures_detected", "sensor.device_peak_demand_current_month", "sensor.device_power_failures_detected", @@ -289,7 +307,6 @@ async def test_sensors_unreachable( "sensor.device_total_energy_import_tariff_2", "sensor.device_total_energy_import_tariff_3", "sensor.device_total_energy_import_tariff_4", - "sensor.device_total_gas", "sensor.device_total_water_usage", "sensor.device_voltage_sags_detected_phase_1", "sensor.device_voltage_sags_detected_phase_2", @@ -337,8 +354,6 @@ async def test_sensors_unreachable( "sensor.device_long_power_failures_detected", "sensor.device_active_average_demand", "sensor.device_peak_demand_current_month", - "sensor.device_total_gas", - "sensor.device_gas_meter_identifier", ], ), ( @@ -357,7 +372,6 @@ async def test_sensors_unreachable( "sensor.device_active_voltage_phase_3", "sensor.device_active_water_usage", "sensor.device_dsmr_version", - "sensor.device_gas_meter_identifier", "sensor.device_long_power_failures_detected", "sensor.device_peak_demand_current_month", "sensor.device_power_failures_detected", @@ -371,7 +385,6 @@ async def test_sensors_unreachable( "sensor.device_total_energy_import_tariff_2", "sensor.device_total_energy_import_tariff_3", "sensor.device_total_energy_import_tariff_4", - "sensor.device_total_gas", "sensor.device_total_water_usage", "sensor.device_voltage_sags_detected_phase_1", "sensor.device_voltage_sags_detected_phase_2", @@ -395,7 +408,6 @@ async def test_sensors_unreachable( "sensor.device_active_voltage_phase_3", "sensor.device_active_water_usage", "sensor.device_dsmr_version", - "sensor.device_gas_meter_identifier", "sensor.device_long_power_failures_detected", "sensor.device_peak_demand_current_month", "sensor.device_power_failures_detected", @@ -409,7 +421,6 @@ async def test_sensors_unreachable( "sensor.device_total_energy_import_tariff_2", "sensor.device_total_energy_import_tariff_3", "sensor.device_total_energy_import_tariff_4", - "sensor.device_total_gas", "sensor.device_total_water_usage", "sensor.device_voltage_sags_detected_phase_1", "sensor.device_voltage_sags_detected_phase_2", @@ -428,3 +439,49 @@ async def test_entities_not_created_for_device( """Ensures entities for a specific device are not created.""" for entity_id in entity_ids: assert not hass.states.get(entity_id) + + +async def test_gas_meter_migrated( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + init_integration: MockConfigEntry, + snapshot: SnapshotAssertion, +) -> None: + """Test old gas meter sensor is migrated.""" + entity_registry.async_get_or_create( + Platform.SENSOR, + DOMAIN, + "aabbccddeeff_total_gas_m3", + ) + + await hass.config_entries.async_reload(init_integration.entry_id) + await hass.async_block_till_done() + + entity_id = "sensor.homewizard_aabbccddeeff_total_gas_m3" + + assert (entity_entry := entity_registry.async_get(entity_id)) + assert snapshot(name=f"{entity_id}:entity-registry") == entity_entry + + # Make really sure this happens + assert entity_entry.previous_unique_id == "aabbccddeeff_total_gas_m3" + + +async def test_gas_unique_id_removed( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + init_integration: MockConfigEntry, + snapshot: SnapshotAssertion, +) -> None: + """Test old gas meter id sensor is removed.""" + entity_registry.async_get_or_create( + Platform.SENSOR, + DOMAIN, + "aabbccddeeff_gas_unique_id", + ) + + await hass.config_entries.async_reload(init_integration.entry_id) + await hass.async_block_till_done() + + entity_id = "sensor.homewizard_aabbccddeeff_gas_unique_id" + + assert not entity_registry.async_get(entity_id)