fix: re-align dead-band on sync
This commit is contained in:
@@ -127,19 +127,20 @@ class EaseeSolarCoordinator(DataUpdateCoordinator):
|
|||||||
"""Return True only when the target warrants a new service call.
|
"""Return True only when the target warrants a new service call.
|
||||||
|
|
||||||
- First run: always send.
|
- First run: always send.
|
||||||
- Transitions to/from 0: always send (start/stop events).
|
- Transitions to/from 0: always send immediately (start/stop events).
|
||||||
- Outside dead-band: send immediately.
|
- Outside dead-band: send immediately.
|
||||||
- Inside dead-band: send once per minute so gradual solar drift is applied.
|
- Inside dead-band (including same value): re-align once per minute so
|
||||||
|
the charger is periodically re-confirmed even if the target hasn't changed.
|
||||||
|
- 0 → 0: never resend (charger is already off).
|
||||||
"""
|
"""
|
||||||
if self._last_sent_current is None:
|
if self._last_sent_current is None:
|
||||||
return True
|
return True
|
||||||
if target == self._last_sent_current:
|
# Start / stop transitions fire immediately; 0→0 is a no-op.
|
||||||
return False
|
|
||||||
if target == 0 or self._last_sent_current == 0:
|
if target == 0 or self._last_sent_current == 0:
|
||||||
return True
|
return target != self._last_sent_current
|
||||||
if abs(target - self._last_sent_current) >= HYSTERESIS_A:
|
if abs(target - self._last_sent_current) >= HYSTERESIS_A:
|
||||||
return True
|
return True
|
||||||
# Within dead-band: resync once per minute
|
# Within dead-band or same value: re-align once per minute.
|
||||||
return (
|
return (
|
||||||
self._last_sent_at is None
|
self._last_sent_at is None
|
||||||
or datetime.now(timezone.utc) - self._last_sent_at >= _DEAD_BAND_RESYNC
|
or datetime.now(timezone.utc) - self._last_sent_at >= _DEAD_BAND_RESYNC
|
||||||
|
|||||||
@@ -27,10 +27,21 @@ class TestShouldSend:
|
|||||||
def test_first_run_always_sends(self, coord):
|
def test_first_run_always_sends(self, coord):
|
||||||
assert coord._should_send(8) is True
|
assert coord._should_send(8) is True
|
||||||
|
|
||||||
def test_same_value_no_send(self, coord):
|
def test_same_value_no_send_when_recent(self, coord):
|
||||||
coord._last_sent_current = 8
|
coord._last_sent_current = 8
|
||||||
|
coord._last_sent_at = datetime.now(timezone.utc)
|
||||||
assert coord._should_send(8) is False
|
assert coord._should_send(8) is False
|
||||||
|
|
||||||
|
def test_same_value_sends_after_one_minute(self, coord):
|
||||||
|
coord._last_sent_current = 8
|
||||||
|
coord._last_sent_at = datetime.now(timezone.utc) - timedelta(minutes=1, seconds=1)
|
||||||
|
assert coord._should_send(8) is True
|
||||||
|
|
||||||
|
def test_zero_to_zero_never_resends(self, coord):
|
||||||
|
coord._last_sent_current = 0
|
||||||
|
coord._last_sent_at = datetime.now(timezone.utc) - timedelta(minutes=10)
|
||||||
|
assert coord._should_send(0) is False
|
||||||
|
|
||||||
def test_zero_to_nonzero_sends(self, coord):
|
def test_zero_to_nonzero_sends(self, coord):
|
||||||
coord._last_sent_current = 0
|
coord._last_sent_current = 0
|
||||||
assert coord._should_send(8) is True
|
assert coord._should_send(8) is True
|
||||||
|
|||||||
Reference in New Issue
Block a user