1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-26 14:08:21 +00:00

Add support for externally connected utility devices in HomeWizard (#100684)

* Backport code from #86386

* Add tests

* Remove local dev change

* Implement device class validation based on unit

* Swap sensor and externalsensor classes (based on importance)

* Use translations for external sensor entities

* Re-add meter identifier as sensor for external devices

* Add migration for Gas identifier

* Rename HomeWizardExternalIdentifierSensorEntity class

* Fix all existing tests

* Reimplement tests for extenal devices with smapshots

* Remove non-used 'None' type in unit

* Add migration test

* Clean up parameterize

* Add test to fix last coverage issue

* Fix non-frozen mypy issue

* Set device name via added EntityDescription field

* Remove device key translations for external sensors,

* Bring back translation keys

* Set device unique_id as serial number

* Remove meter identifier sensor

* Simplify external device initialization

* Adjust tests

* Remove unused gas_meter_id migration

* Remove external_devices redaction

* Remove old gas meter id sensor after migration
This commit is contained in:
Duco Sebel
2024-01-25 12:51:50 +01:00
committed by GitHub
parent c54b65fdf0
commit 0c9a30ab69
6 changed files with 2165 additions and 37 deletions

View File

@@ -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)