mirror of
https://github.com/home-assistant/core.git
synced 2026-09-24 15:31:52 -05:00
Tessie: log warning instead of raising UpdateFailed for missing energy history (#168068)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
Copilot
parent
b4c8452a5a
commit
e5cd1e2830
@@ -224,10 +224,11 @@ class TessieEnergyHistoryCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
or not isinstance(data.get("time_series"), list)
|
||||
or not data["time_series"]
|
||||
):
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_energy_history_data",
|
||||
_LOGGER.warning(
|
||||
"Tessie returned no energy history time_series for coordinator %s; skipping update",
|
||||
self.config_entry.entry_id,
|
||||
)
|
||||
return self.data
|
||||
|
||||
time_series = data["time_series"]
|
||||
output: dict[str, Any] = {}
|
||||
|
||||
@@ -638,4 +638,4 @@ class TessieEnergyHistorySensorEntity(TessieEnergyHistoryEntity, SensorEntity):
|
||||
"""Update the attributes of the sensor."""
|
||||
self._attr_available = self._value is not None
|
||||
self._attr_native_value = self._value
|
||||
self._attr_last_reset = self.coordinator.data["_period_start"]
|
||||
self._attr_last_reset = self.coordinator.data.get("_period_start")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Test the Tessie sensor platform."""
|
||||
|
||||
from copy import deepcopy
|
||||
from datetime import timedelta
|
||||
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
@@ -14,11 +15,17 @@ from homeassistant.components.tessie.coordinator import (
|
||||
TESSIE_SYNC_INTERVAL,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import STATE_ON, STATE_UNAVAILABLE, Platform
|
||||
from homeassistant.const import STATE_ON, STATE_UNAVAILABLE, STATE_UNKNOWN, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.update_coordinator import UpdateFailed
|
||||
|
||||
from .common import ERROR_AUTH, ERROR_CONNECTION, ERROR_UNKNOWN, setup_platform
|
||||
from .common import (
|
||||
ENERGY_HISTORY,
|
||||
ERROR_AUTH,
|
||||
ERROR_CONNECTION,
|
||||
ERROR_UNKNOWN,
|
||||
setup_platform,
|
||||
)
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
|
||||
@@ -184,21 +191,52 @@ async def test_coordinator_energy_history_error(
|
||||
async def test_coordinator_energy_history_invalid_data(
|
||||
hass: HomeAssistant, mock_energy_history, freezer: FrozenDateTimeFactory
|
||||
) -> None:
|
||||
"""Tests that the energy history coordinator handles invalid data."""
|
||||
"""Tests that the energy history coordinator handles invalid data gracefully."""
|
||||
|
||||
entry = await setup_platform(hass, [Platform.SENSOR])
|
||||
coordinator = entry.runtime_data.energysites[0].history_coordinator
|
||||
assert coordinator is not None
|
||||
|
||||
# Capture state after successful initial load
|
||||
state_before = hass.states.get("sensor.energy_site_grid_imported").state
|
||||
|
||||
mock_energy_history.reset_mock()
|
||||
mock_energy_history.side_effect = lambda *a, **kw: {"response": {}}
|
||||
freezer.tick(TESSIE_ENERGY_HISTORY_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
mock_energy_history.assert_called_once()
|
||||
assert (
|
||||
hass.states.get("sensor.energy_site_grid_imported").state == STATE_UNAVAILABLE
|
||||
)
|
||||
assert isinstance(coordinator.last_exception, UpdateFailed)
|
||||
assert coordinator.last_exception.translation_domain == DOMAIN
|
||||
assert coordinator.last_exception.translation_key == "invalid_energy_history_data"
|
||||
|
||||
# Sensor should retain last good state rather than becoming unavailable
|
||||
assert hass.states.get("sensor.energy_site_grid_imported").state == state_before
|
||||
assert coordinator.last_exception is None
|
||||
|
||||
|
||||
async def test_coordinator_energy_history_cold_start_invalid_data(
|
||||
hass: HomeAssistant, mock_energy_history, freezer: FrozenDateTimeFactory
|
||||
) -> None:
|
||||
"""Tests cold-start fallback when the very first energy history fetch has invalid data."""
|
||||
|
||||
mock_energy_history.side_effect = lambda *a, **kw: {"response": {}}
|
||||
entry = await setup_platform(hass, [Platform.SENSOR])
|
||||
coordinator = entry.runtime_data.energysites[0].history_coordinator
|
||||
assert coordinator is not None
|
||||
|
||||
# Coordinator should not have raised an exception; data stays empty
|
||||
assert coordinator.last_exception is None
|
||||
assert coordinator.data == {}
|
||||
|
||||
# Sensor should be unknown until the first successful fetch
|
||||
assert hass.states.get("sensor.energy_site_grid_imported").state == STATE_UNKNOWN
|
||||
|
||||
# Now recover: restore valid energy history data and trigger an update
|
||||
mock_energy_history.side_effect = lambda *a, **kw: deepcopy(ENERGY_HISTORY)
|
||||
mock_energy_history.reset_mock()
|
||||
freezer.tick(TESSIE_ENERGY_HISTORY_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
mock_energy_history.assert_called_once()
|
||||
|
||||
# Coordinator should have real data and no exception
|
||||
assert coordinator.last_exception is None
|
||||
assert coordinator.data["solar_energy_exported"] == 724
|
||||
|
||||
Reference in New Issue
Block a user