Keep Teslemetry energy history unavailable while the stream is down (#184224)

This commit is contained in:
Brett Adams
2026-10-04 15:27:10 +02:00
committed by GitHub
parent 3fbd190077
commit 35d395cb22
3 changed files with 21 additions and 21 deletions
@@ -374,15 +374,6 @@ class TeslemetryEnergyHistoryCoordinator(DataUpdateCoordinator[dict[str, Any]]):
return
self.time_zone = zone
@override
async def _async_update_data(self) -> dict[str, Any]:
"""Return the current totals; there is nothing to fetch.
Only reached through the generic entity update service, which must not
fail on a coordinator the stream alone feeds.
"""
return self.data
def handle_stream_update(self, event: EnergyTotalsEvent) -> None:
"""Handle an energy_totals document from the stream."""
data: dict[str, Any] = asdict(event.totals)
@@ -194,6 +194,10 @@ class TeslemetryEnergyHistoryEntity(TeslemetryPollingEntity):
super().__init__(data.history_coordinator, key)
@override
async def async_update(self) -> None:
"""Keep the streamed totals; the stream is their only source."""
class TeslemetryWallConnectorEntity(TeslemetryPollingEntity):
"""Parent class for Teslemetry Wall Connector Entities."""
+17 -12
View File
@@ -1,7 +1,6 @@
"""Test the Teslemetry sensor platform."""
from copy import deepcopy
from datetime import timedelta
from unittest.mock import AsyncMock, MagicMock
from freezegun.api import FrozenDateTimeFactory
@@ -748,22 +747,33 @@ async def test_energy_history_time_zone_fallback(
assert state.attributes["last_reset"] == "2024-09-18T00:00:00-07:00"
async def test_energy_history_update_entity_service_is_a_noop(
@pytest.mark.parametrize(
("connected", "expected_state"),
[
pytest.param(True, "0.036", id="connected"),
pytest.param(False, STATE_UNAVAILABLE, id="disconnected"),
],
)
async def test_energy_history_update_entity_service(
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
caplog: pytest.LogCaptureFixture,
mock_add_connection_listener: MagicMock,
mock_energy_totals_stream: MagicMock,
connected: bool,
expected_state: str,
) -> None:
"""The generic update service keeps the streamed totals instead of failing.
"""The generic update service leaves the history sensors as the stream set them.
The coordinator has nothing to fetch, so the service must not leave the
sensors unavailable on a stream that is perfectly healthy.
The stream is their only source, so the service must neither fail on a
healthy stream nor revive stale totals while it is down.
"""
await setup_platform(hass, [Platform.SENSOR])
await async_setup_component(hass, HOMEASSISTANT_DOMAIN, {})
mock_energy_totals_stream.send()
await hass.async_block_till_done()
mock_add_connection_listener.send(connected)
await hass.async_block_till_done()
await hass.services.async_call(
HOMEASSISTANT_DOMAIN,
@@ -771,15 +781,10 @@ async def test_energy_history_update_entity_service_is_a_noop(
{ATTR_ENTITY_ID: ENERGY_HISTORY_ENTITY},
blocking=True,
)
# The coordinator debounces refresh requests, so let the deferred one land.
freezer.tick(timedelta(seconds=30))
async_fire_time_changed(hass)
await hass.async_block_till_done()
assert "NotImplementedError" not in caplog.text
assert (state := hass.states.get(ENERGY_HISTORY_ENTITY))
assert state.state == "0.036"
assert state.attributes["last_reset"] == SITE_MIDNIGHT
assert state.state == expected_state
async def test_energy_history_unavailable_while_stream_disconnected(