mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-03-29 21:03:40 +00:00
fix(listeners): ensure both normal and time-sensitive listeners are notified after midnight turnover
This commit is contained in:
parent
f60b5990ae
commit
c0069e32b8
1 changed files with 30 additions and 1 deletions
|
|
@ -104,6 +104,17 @@ FRESH_TO_CACHED_SECONDS = 300 # 5 minutes
|
||||||
# - No race condition possible - Python datetime.date() comparison is thread-safe
|
# - No race condition possible - Python datetime.date() comparison is thread-safe
|
||||||
# - _last_transformation_time is separate and tracks when data was last transformed (for cache)
|
# - _last_transformation_time is separate and tracks when data was last transformed (for cache)
|
||||||
#
|
#
|
||||||
|
# CRITICAL - Dual Listener System:
|
||||||
|
# After midnight turnover, BOTH listener groups must be notified:
|
||||||
|
# 1. Normal listeners (async_update_listeners) - standard HA entities
|
||||||
|
# 2. Time-sensitive listeners (_async_update_time_sensitive_listeners) - quarter-hour entities
|
||||||
|
#
|
||||||
|
# Why? Entities like best_price_period and peak_price_period register as time-sensitive
|
||||||
|
# listeners and won't update if only async_update_listeners() is called. This caused
|
||||||
|
# the bug where period binary sensors showed stale data until the next quarter-hour
|
||||||
|
# refresh at 00:15 (they were updated then because Timer #2 explicitly calls
|
||||||
|
# _async_update_time_sensitive_listeners in its normal flow).
|
||||||
|
#
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -439,9 +450,17 @@ class TibberPricesDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||||
self._log("info", "[Timer #2] Midnight turnover detected, performing data rotation")
|
self._log("info", "[Timer #2] Midnight turnover detected, performing data rotation")
|
||||||
self._perform_midnight_data_rotation(now)
|
self._perform_midnight_data_rotation(now)
|
||||||
|
|
||||||
# Notify listeners about updated data
|
# CRITICAL: Notify BOTH listener groups after midnight turnover
|
||||||
|
# - async_update_listeners(): Notifies normal entities (via HA's DataUpdateCoordinator)
|
||||||
|
# - async_update_time_sensitive_listeners(): Notifies time-sensitive entities (custom system)
|
||||||
|
# Without both calls, period binary sensors (best_price_period, peak_price_period)
|
||||||
|
# won't update because they're time-sensitive listeners, not normal listeners.
|
||||||
self.async_update_listeners()
|
self.async_update_listeners()
|
||||||
|
|
||||||
|
# Create TimeService with fresh reference time for time-sensitive entity updates
|
||||||
|
time_service = TibberPricesTimeService()
|
||||||
|
self._async_update_time_sensitive_listeners(time_service)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def register_lifecycle_callback(self, callback: Callable[[], None]) -> None:
|
def register_lifecycle_callback(self, callback: Callable[[], None]) -> None:
|
||||||
|
|
@ -525,6 +544,16 @@ class TibberPricesDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||||
self._perform_midnight_data_rotation(current_time)
|
self._perform_midnight_data_rotation(current_time)
|
||||||
# After rotation, save cache and notify entities
|
# After rotation, save cache and notify entities
|
||||||
await self._store_cache()
|
await self._store_cache()
|
||||||
|
|
||||||
|
# CRITICAL: Notify time-sensitive listeners explicitly
|
||||||
|
# When Timer #1 performs turnover, returning self.data will trigger
|
||||||
|
# async_update_listeners() (normal listeners) automatically via DataUpdateCoordinator.
|
||||||
|
# But time-sensitive listeners (like best_price_period, peak_price_period)
|
||||||
|
# won't be notified unless we explicitly call their update method.
|
||||||
|
# This ensures ALL entities see the updated periods after midnight turnover.
|
||||||
|
time_service = TibberPricesTimeService()
|
||||||
|
self._async_update_time_sensitive_listeners(time_service)
|
||||||
|
|
||||||
# Return current data (enriched after rotation) to trigger entity updates
|
# Return current data (enriched after rotation) to trigger entity updates
|
||||||
if self.data:
|
if self.data:
|
||||||
return self.data
|
return self.data
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue