diff --git a/tests/components/enphase_envoy/test_sensor.py b/tests/components/enphase_envoy/test_sensor.py index d0d347d9df0..1b066ca9f59 100644 --- a/tests/components/enphase_envoy/test_sensor.py +++ b/tests/components/enphase_envoy/test_sensor.py @@ -3,12 +3,14 @@ from itertools import chain from unittest.mock import AsyncMock, patch +from freezegun.api import FrozenDateTimeFactory from pyenphase.const import PHASENAMES import pytest from syrupy.assertion import SnapshotAssertion from homeassistant.components.enphase_envoy.const import Platform -from homeassistant.const import UnitOfTemperature +from homeassistant.components.enphase_envoy.coordinator import SCAN_INTERVAL +from homeassistant.const import STATE_UNKNOWN, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from homeassistant.util import dt as dt_util @@ -16,7 +18,7 @@ from homeassistant.util.unit_conversion import TemperatureConverter from . import setup_integration -from tests.common import MockConfigEntry, snapshot_platform +from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform @pytest.mark.parametrize( @@ -843,3 +845,64 @@ def integration_disabled_entities( ) if entity_entry.disabled_by == er.RegistryEntryDisabler.INTEGRATION ] + + +@pytest.mark.parametrize( + ("mock_envoy"), + [ + "envoy_metered_batt_relay", + ], + indirect=["mock_envoy"], +) +@pytest.mark.usefixtures("entity_registry_enabled_by_default") +async def test_sensor_missing_data( + hass: HomeAssistant, + config_entry: MockConfigEntry, + mock_envoy: AsyncMock, + entity_registry: er.EntityRegistry, + freezer: FrozenDateTimeFactory, +) -> None: + """Test enphase_envoy sensor platform midding data handling.""" + with patch("homeassistant.components.enphase_envoy.PLATFORMS", [Platform.SENSOR]): + await setup_integration(hass, config_entry) + + ENTITY_BASE = f"{Platform.SENSOR}.envoy_{mock_envoy.serial_number}" + + # force missing data to test 'if == none' code sections + mock_envoy.data.system_production_phases["L2"] = None + mock_envoy.data.system_consumption_phases["L2"] = None + mock_envoy.data.ctmeter_production = None + mock_envoy.data.ctmeter_consumption = None + mock_envoy.data.ctmeter_storage = None + mock_envoy.data.ctmeter_production_phases = None + mock_envoy.data.ctmeter_consumption_phases = None + mock_envoy.data.ctmeter_storage_phases = None + + # use different inverter serial to test 'expected inverter missing' code + mock_envoy.data.inverters["2"] = mock_envoy.data.inverters.pop("1") + + # force HA to detect changed data by changing raw + mock_envoy.data.raw = {"I": "am changed"} + + # MOve time to next update + freezer.tick(SCAN_INTERVAL) + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) + + # all these should now be in unknown state + for entity in ( + "lifetime_energy_production_l2", + "lifetime_energy_consumption_l2", + "metering_status_production_ct", + "metering_status_net_consumption_ct", + "metering_status_storage_ct", + "metering_status_production_ct_l2", + "metering_status_net_consumption_ct_l2", + "metering_status_storage_ct_l2", + ): + assert (entity_state := hass.states.get(f"{ENTITY_BASE}_{entity}")) + assert entity_state.state == STATE_UNKNOWN + + # test the original inverter is now unknown + assert (entity_state := hass.states.get("sensor.inverter_1")) + assert entity_state.state == STATE_UNKNOWN