Skip to content

Commit 7ff4da3

Browse files
committed
v1.1.1: Fix RCE spread sensors — real-time state tracking
- Added async_track_state_change_event listener for RCE entity - Coordinator recalculates spread instantly on RCE state change (not just every 30 min ENTSO-E API cycle) - Added debug logging in _read_rce_price() for troubleshooting - Fixed test mock for homeassistant.helpers.event
1 parent fcfd222 commit 7ff4da3

3 files changed

Lines changed: 49 additions & 5 deletions

File tree

custom_components/entsoe_prices/coordinator.py

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
import logging
77

88
from aiohttp import ClientSession
9-
from homeassistant.core import HomeAssistant
9+
from homeassistant.core import HomeAssistant, callback
10+
from homeassistant.helpers.event import async_track_state_change_event
1011
from homeassistant.helpers.update_coordinator import (
1112
DataUpdateCoordinator,
1213
UpdateFailed,
@@ -62,6 +63,32 @@ def __init__(
6263
)
6364
self._rce_entity = rce_entity
6465

66+
# Track RCE sensor changes to recalculate spread in real-time
67+
if rce_entity:
68+
_LOGGER.debug("RCE spread enabled, tracking entity: %s", rce_entity)
69+
async_track_state_change_event(
70+
hass, [rce_entity], self._on_rce_state_change
71+
)
72+
73+
@callback
74+
def _on_rce_state_change(self, event) -> None:
75+
"""Handle RCE sensor state change — recalculate spread."""
76+
if self.data is None:
77+
return
78+
rce_price = self._read_rce_price()
79+
rce_max = self._read_rce_max()
80+
_LOGGER.debug(
81+
"RCE state changed → recalculating spread (rce=%.4f, max=%s)",
82+
rce_price if rce_price is not None else 0,
83+
rce_max,
84+
)
85+
self.data = self.api_client.compute_spread(
86+
self.data,
87+
rce_price_mwh=rce_price,
88+
rce_max_today_mwh=rce_max,
89+
)
90+
self.async_set_updated_data(self.data)
91+
6592
async def _async_update_data(self) -> PriceData:
6693
"""Fetch data from ENTSO-E and enrich with RCE spread."""
6794
try:
@@ -73,6 +100,10 @@ async def _async_update_data(self) -> PriceData:
73100
if self._rce_entity:
74101
rce_price = self._read_rce_price()
75102
rce_max = self._read_rce_max()
103+
_LOGGER.debug(
104+
"RCE spread computation: entity=%s, rce_price=%s, rce_max=%s",
105+
self._rce_entity, rce_price, rce_max,
106+
)
76107
data = self.api_client.compute_spread(
77108
data,
78109
rce_price_mwh=rce_price,
@@ -84,11 +115,23 @@ async def _async_update_data(self) -> PriceData:
84115
def _read_rce_price(self) -> float | None:
85116
"""Read current RCE price from HA sensor (PLN/MWh)."""
86117
state = self.hass.states.get(self._rce_entity)
87-
if state is None or state.state in ("unavailable", "unknown"):
118+
if state is None:
119+
_LOGGER.warning("RCE entity %s not found in HA states", self._rce_entity)
120+
return None
121+
if state.state in ("unavailable", "unknown"):
122+
_LOGGER.debug(
123+
"RCE entity %s has state '%s', skipping", self._rce_entity, state.state
124+
)
88125
return None
89126
try:
90-
return float(state.state)
91-
except (ValueError, TypeError):
127+
val = float(state.state)
128+
_LOGGER.debug("RCE price read: %s = %.4f PLN/MWh", self._rce_entity, val)
129+
return val
130+
except (ValueError, TypeError) as exc:
131+
_LOGGER.warning(
132+
"Cannot parse RCE price from %s (state='%s'): %s",
133+
self._rce_entity, state.state, exc,
134+
)
92135
return None
93136

94137
def _read_rce_max(self) -> float | None:

custom_components/entsoe_prices/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"domain": "entsoe_prices",
33
"name": "ENTSO-E Ceny Energii",
4-
"version": "1.1.0",
4+
"version": "1.1.1",
55
"documentation": "https://github.com/GregECAT/entsoe-e",
66
"issue_tracker": "https://github.com/GregECAT/entsoe-e/issues",
77
"attribution": "Dane z platformy ENTSO-E Transparency. Kurs walut z API NBP. Wydawca: Smarting HOME (smartinghome.pl). Dokumentacja API: https://documenter.getpostman.com/view/7009892/2s93JtP3F6",

tests/test_api.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
sys.modules["homeassistant.core"] = MagicMock()
1919
sys.modules["homeassistant.helpers"] = MagicMock()
2020
sys.modules["homeassistant.helpers.aiohttp_client"] = MagicMock()
21+
sys.modules["homeassistant.helpers.event"] = MagicMock()
2122
sys.modules["homeassistant.helpers.update_coordinator"] = MagicMock()
2223
sys.modules["homeassistant.helpers.entity"] = MagicMock()
2324
sys.modules["homeassistant.helpers.entity_platform"] = MagicMock()

0 commit comments

Comments
 (0)