diff --git a/goodwe_controller/DECISIONS/OPT-27-last-fresh-forecast-for-the-night.md b/goodwe_controller/DECISIONS/OPT-27-last-fresh-forecast-for-the-night.md index 6924cb8..8d2c09f 100644 --- a/goodwe_controller/DECISIONS/OPT-27-last-fresh-forecast-for-the-night.md +++ b/goodwe_controller/DECISIONS/OPT-27-last-fresh-forecast-for-the-night.md @@ -35,9 +35,10 @@ evening restart keeps it. It is written when a reading's figure changes or every 15 min (`SAVE_EVERY_S`), not on every poll. A damaged entry is dropped. **The screens.** `Forecast.kept` is true when a reading older than `FRESH_S` is -in use; the forecast line then reads "Solar forecast read 17:05, used for -tonight's plan." (`home_words.solar.kept`, EN and NL). The event log says +in use; the forecast line then reads "Solar forecast read 17:05, kept for +tonight." (`home_words.solar.kept`, EN and NL). The event log says "read, kept from 17:05". -**Not changed.** Modes off (nothing reads the sensors). A forecast that stays -fresh. The hold does not look at the weather, only at the clock and the day. +**Not changed.** Control with modes off: it does not use the forecast. The +screens still show the line, so it says "kept", not "used for the plan". A +forecast that stays fresh. The hold does not look at the weather, only at the clock and the day. diff --git a/goodwe_controller/DOCS.md b/goodwe_controller/DOCS.md index 2a7a8e7..76bdb13 100644 --- a/goodwe_controller/DOCS.md +++ b/goodwe_controller/DOCS.md @@ -557,7 +557,7 @@ With battery modes on, these choices replace the *Charging and selling on price* - The plan is checked every 15 minutes. A planned level moves only by 1 kWh or 10 %, so a wobbling forecast does not flip it. - No forecast, one older than 3 hours or from before midnight, or no house use yet: *Leftover solar* takes solar only and *Cheap hours only* fills to the top level. The Batteries screen says so. - A battery needs its capacity (`inverters.capacity_kwh`) for a plan. -- **At night.** Some forecasts stop updating in the evening (Forecast.Solar does). The add-on keeps the last reading of each sensor and uses it for that night's plan: from 20:00 until 03:00, or until a newer reading comes. A sensor that is missing for up to 3 hours is covered the same way. A figure is never used for another day, and never older than that night. The Batteries screen says "Solar forecast read 17:05, used for tonight's plan." With no reading all day, the night run still needs the wider gap. +- **At night.** Some forecasts stop updating in the evening (Forecast.Solar does). The add-on keeps the last reading of each sensor and uses it for that night's plan: from 20:00 until 03:00, or until a newer reading comes. A sensor that is missing for up to 3 hours is covered the same way. A figure is never used for another day, and never older than that night. The Batteries screen says "Solar forecast read 17:05, kept for tonight." With no reading all day, the night run still needs the wider gap. **What always comes first.** - The peak limit, the safety stops and the monthly cycle come before a battery's mode. diff --git a/goodwe_controller/app/ui_text/en.json b/goodwe_controller/app/ui_text/en.json index 7d225db..135cb06 100644 --- a/goodwe_controller/app/ui_text/en.json +++ b/goodwe_controller/app/ui_text/en.json @@ -360,7 +360,7 @@ "tops_up": "It charges from the grid to {pct}. That covers {kwh} of expensive hours the sun will not.", "no_forecast": "No solar forecast, so it charges from solar only." }, - "solar": {"line": "Solar still to come today: {kwh}, we count on {count}. Updated {at}.", "uncovered": "The expensive hours need more than Leftover solar can hold. The rest, {kwh}, comes from another battery or the grid.", "kept": "Solar forecast read {at}, used for tonight's plan.", "no_forecast": "No solar forecast now, so Leftover solar charges from solar only.", "learning": "The add-on is learning your house's use. The plan starts after one full day."}, + "solar": {"line": "Solar still to come today: {kwh}, we count on {count}. Updated {at}.", "uncovered": "The expensive hours need more than Leftover solar can hold. The rest, {kwh}, comes from another battery or the grid.", "kept": "Solar forecast read {at}, kept for tonight.", "no_forecast": "No solar forecast now, so Leftover solar charges from solar only.", "learning": "The add-on is learning your house's use. The plan starts after one full day."}, "today": { "not_planned": "Not planned yet.", "no_runs": "No cheap or expensive hours left today.", diff --git a/goodwe_controller/app/ui_text/nl.json b/goodwe_controller/app/ui_text/nl.json index cc0ba46..84dadf5 100644 --- a/goodwe_controller/app/ui_text/nl.json +++ b/goodwe_controller/app/ui_text/nl.json @@ -300,7 +300,7 @@ "tops_up": "Ze laadt van het net tot {pct}. Dat dekt {kwh} dat de zon in dure uren niet levert.", "no_forecast": "Geen zonneprognose, dus ze laadt alleen met zonne-energie." }, - "solar": {"line": "Nog verwachte zon vandaag: {kwh}, we rekenen op {count}. Bijgewerkt om {at}.", "uncovered": "De dure uren vragen meer dan Overschot zonne-energie kan opslaan. De rest, {kwh}, komt van een andere batterij of het net.", "kept": "Zonneprognose van {at}, gebruikt voor het plan van vanavond.", "no_forecast": "Nu geen zonneprognose, dus Overschot zonne-energie laadt alleen met zon.", "learning": "De add-on leert eerst het verbruik van uw huis. Het plan start na één volle dag."}, + "solar": {"line": "Nog verwachte zon vandaag: {kwh}, we rekenen op {count}. Bijgewerkt om {at}.", "uncovered": "De dure uren vragen meer dan Overschot zonne-energie kan opslaan. De rest, {kwh}, komt van een andere batterij of het net.", "kept": "Zonneprognose van {at}, bewaard voor vannacht.", "no_forecast": "Nu geen zonneprognose, dus Overschot zonne-energie laadt alleen met zon.", "learning": "De add-on leert eerst het verbruik van uw huis. Het plan start na één volle dag."}, "today": { "not_planned": "Nog niet gepland.", "no_runs": "Vandaag geen goedkope of dure uren meer.", diff --git a/goodwe_controller/test_opt27.py b/goodwe_controller/test_opt27.py index 62ac848..9643db3 100644 --- a/goodwe_controller/test_opt27.py +++ b/goodwe_controller/test_opt27.py @@ -21,8 +21,8 @@ DECISIONS/OPT-27-last-fresh-forecast-for-the-night.md. c. an evening restart keeps it (a new Controller on the saved store); d. a one-hour outage at 18:47 does not drop it; e. past midnight + 3 h the figure is not used, before it it is. -3. The screens: the forecast line says when it was read and that it is used - for tonight's plan (EN and NL), and Home agrees with control. +3. The screens: the forecast line says when it was read and that it is kept + for tonight (EN and NL), and Home agrees with control. Mutations (MUTATION.md, purged copies, graded over this file): see the DECISIONS note and the dev report. @@ -539,9 +539,8 @@ check("... and the level, the grid need, the shortfall and the sun counted " print("\n3. The screens") blk = ca.block print(f" forecast line: {blk['line']!r} (state {blk['state']})") -check("the forecast line says when it was read and that it is used for " - "tonight's plan", blk["line"] == "Solar forecast read 17:05, used for " - "tonight's plan.") +check("the forecast line says when it was read and that it is kept for " + "tonight", blk["line"] == "Solar forecast read 17:05, kept for tonight.") check("the same line comes from the Forecast tab (dayview) on today", homeview.line_solar(0.4, 0.3, "17:05", kept=True) == blk["line"] and homeview.line_solar(0.4, 0.3, "17:05").startswith( @@ -555,7 +554,7 @@ k_nl = nl["home_words"]["solar"]["kept"] print(f" EN {k_en!r}\n NL {k_nl!r}") check("EN and NL both say it, with the time, and the NL is not the English", "{at}" in k_en and "{at}" in k_nl and k_en != k_nl - and "plan" in k_en and "vanavond" in k_nl) + and "tonight" in k_en and "vannacht" in k_nl) check("a daytime reading keeps the old line (daytime unchanged)", "Updated 09:05" in homeview.line_solar(1.0, 0.7, "09:05") and "Bijgewerkt" in json.dumps(nl["home_words"]["solar"]["line"]))