PRICE-01: own price server as a price source, with fallbacks #190

Merged
admin merged 7 commits from PRICE-01 into release/1.0 2026-10-14 22:47:44 +02:00
Showing only changes of commit 2f261f8ba4 - Show all commits
+23 -3
View File
@@ -1224,9 +1224,12 @@ check("...without a token it is refused, naming both settings by label and key "
f"({_e})", len(_e) == 1 and "“Dynamic price source” (price_provider)" f"({_e})", len(_e) == 1 and "“Dynamic price source” (price_provider)"
in _e[0] and "“Price service token” (price_service_token)" in _e[0] in _e[0] and "“Price service token” (price_service_token)" in _e[0]
and TOKEN not in _e[0]) and TOKEN not in _e[0])
check("...a token with a space in it is refused, and the token is not echoed", # Long enough to pass the length rule, so only the space can refuse it.
len(problems(price_service_token="ab cd")) == 1 _SPACED = "tk-0123456789 abcdefgh"
and "ab cd" not in problems(price_service_token="ab cd")[0]) _e = problems(price_service_token=_SPACED)
check("...a token with a space in it is refused for the space, and the token "
"is not echoed",
len(_e) == 1 and "space" in _e[0] and _SPACED not in _e[0])
_e = problems(price_now_entity="sensor.a", price_avg_entity="sensor.b") _e = problems(price_now_entity="sensor.a", price_avg_entity="sensor.b")
check(f"the existing conflict refusal stands: the Home Assistant pair beside " check(f"the existing conflict refusal stands: the Home Assistant pair beside "
f"this provider is refused ({len(_e)} problem)", f"this provider is refused ({len(_e)} problem)",
@@ -1430,6 +1433,23 @@ check("a notification raised while the cycle was on is cleared, once, when "
len(_r) == 1 and [x[0] for x in _n] == ["create", "dismiss"] len(_r) == 1 and [x[0] for x in _n] == ["create", "dismiss"]
and _g is False) and _g is False)
async def _scenario_key_missing():
"""No `maintenance_enabled` key at all: its shipped default (off) holds."""
with Wired(NOW) as W:
c = W.ctl
c.o.pop("maintenance_enabled", None)
W.net.down()
await W.refresh()
for k in range(3):
await W.tick(NOW + timedelta(seconds=30 * k))
return c.price_gap, list(W.notes())
_g2, _n2 = run(_scenario_key_missing())
check("with no maintenance_enabled key its default (off) holds: no no-price "
"words, no notification", _g2 is False and _n2 == [])
async def _modes_no_price(): async def _modes_no_price():
"""Battery modes on, maintenance off, no price anywhere: what happens.""" """Battery modes on, maintenance off, no price anywhere: what happens."""
from app import packmode, homeview from app import packmode, homeview