diff --git a/goodwe_controller/DOCS.md b/goodwe_controller/DOCS.md index 78747cb..56548e1 100644 --- a/goodwe_controller/DOCS.md +++ b/goodwe_controller/DOCS.md @@ -3113,7 +3113,7 @@ second set of 23- and 25-hour-day bugs. ### Static day/night and fully-fixed tariffs (`static_profile`) Most Belgian households are **not** on a dynamic contract, and an EMS that only -works under hourly pricing is an EMS for a minority. `static_profile` is how a +works under dynamic pricing is an EMS for a minority. `static_profile` is how a two-period day/night tariff or a single fixed price becomes a first-class configuration rather than "turn the price feature off and hope". diff --git a/goodwe_controller/app/ui_text/en.json b/goodwe_controller/app/ui_text/en.json index 9c603ef..102e311 100644 --- a/goodwe_controller/app/ui_text/en.json +++ b/goodwe_controller/app/ui_text/en.json @@ -29,7 +29,7 @@ "periods": {"name": "Time windows and prices", "description": "One price per kWh for each time window, all in, as on your bill: divide c€/kWh by 100, so 34.512 c€/kWh is 0.34512."} }, "choices": { - "contract": {"none": "No prices", "fixed": "Fixed price", "daynight": "Day and night", "dynamic": "Dynamic, hourly", "custom": "Other time windows"}, + "contract": {"none": "No prices", "fixed": "Fixed price", "daynight": "Day and night", "dynamic": "Dynamic, every 15 minutes", "custom": "Other time windows"}, "fallback": {"none": "None", "fixed": "One price", "daynight": "Day and night", "custom": "Other time windows"}, "region": {"flanders": "Flanders, Fluvius Antwerpen", "own": "I enter my own figure"}, "meter_source": {"off": "One grid power entity", "ha_dsmr": "Import and export entities", "mqtt_p1": "Meter over MQTT", "ha_signed": "One net power entity", "homewizard_local": "HomeWizard meter on the network"}, diff --git a/goodwe_controller/app/ui_text/nl.json b/goodwe_controller/app/ui_text/nl.json index 6c4763c..e027d6e 100644 --- a/goodwe_controller/app/ui_text/nl.json +++ b/goodwe_controller/app/ui_text/nl.json @@ -29,7 +29,7 @@ "periods": {"name": "Tijdvakken en prijzen", "description": "Eén prijs per kWh voor elk tijdvak, alles inbegrepen, zoals op uw factuur: deel c€/kWh door 100, dus 34,512 c€/kWh is 0,34512."} }, "choices": { - "contract": {"none": "Geen prijzen", "fixed": "Vaste prijs", "daynight": "Dag en nacht", "dynamic": "Dynamisch, per uur", "custom": "Andere tijdvakken"}, + "contract": {"none": "Geen prijzen", "fixed": "Vaste prijs", "daynight": "Dag en nacht", "dynamic": "Dynamisch, per kwartier", "custom": "Andere tijdvakken"}, "fallback": {"none": "Geen", "fixed": "Eén prijs", "daynight": "Dag en nacht", "custom": "Andere tijdvakken"}, "region": {"flanders": "Vlaanderen, Fluvius Antwerpen", "own": "Ik vul zelf een bedrag in"}, "meter_source": {"off": "Eén entiteit voor netvermogen", "ha_dsmr": "Entiteiten voor afname en injectie", "mqtt_p1": "Meter via MQTT", "ha_signed": "Eén entiteit voor nettovermogen", "homewizard_local": "HomeWizard-meter op het netwerk"}, diff --git a/goodwe_controller/test_ui_text.py b/goodwe_controller/test_ui_text.py index d23a8cd..6d0fe16 100644 --- a/goodwe_controller/test_ui_text.py +++ b/goodwe_controller/test_ui_text.py @@ -286,6 +286,22 @@ check("app/uitext.py falls back to English per key and reads nl-BE as nl", and uitext._merge({"a": {"b": 1, "c": 2}}, {"a": {"b": 3}}) == {"a": {"b": 3, "c": 2}}) +# ============================================================================ # +print("\n7. the dynamic contract choice says 15 minutes, never hourly (UX-44)") +# Belgian day-ahead prices are per 15 minutes since 2025-10-01. +HOURLY = re.compile(r"hourly|per hour|\bhour\b|per uur|\buur\b|uurprijs", + re.I) +_dyn = {"en": EN["choices"]["contract"]["dynamic"], + "nl": NL["choices"]["contract"]["dynamic"]} +check(f"the label reads 'Dynamic, every 15 minutes' / 'Dynamisch, per " + f"kwartier' ({_dyn})", + _dyn == {"en": "Dynamic, every 15 minutes", + "nl": "Dynamisch, per kwartier"}) +check("neither language calls the dynamic contract hourly", + not any(HOURLY.search(t) for t in _dyn.values())) +check("mutation: the old labels are caught", + all(HOURLY.search(t) for t in ("Dynamic, hourly", "Dynamisch, per uur"))) + print() if fails: print(f"{len(fails)} FAILED")