Repository navigation
fix(history): count unknown PV as 0 W after sunset - #1755
Conversation
49311a3 to
84a4655
Compare
historySources set MissingLoad for every reason except invalid_balance. Telemetry puts a source's own failure there too, such as "offline:sma:pv" or "stale:easee:ev", so a real snapshot with a silent inverter or charger voided the whole balance and the source writer held nothing. Only configuration and duplicate-flow reasons now set MissingLoad; a failed source is unknown on its own flag. Found by the #1755 session through historySources. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
84a4655 to
cc892be
Compare
* fix(history): bridge short source gaps instead of losing the day's Home use Since #1741 a Core restart (18-20 s), a source unknown for a few seconds or a writer pause over 15 s made the whole day's load_wh null, and an unknown PV also nulled pv_wh. The source writer now holds an episode that starts at the last fully known snapshot. If every source is known again with the same topology within LoadEstimateRecoveryWindow (2 min), the episode is written as an estimate marked EstimatedLoad: measured sources keep their snapshots, unknown ones hold the anchor's values. Otherwise it is written exactly as before. Pending time stays out of totals and expected coverage, and the day waits for it before closing. On open Core marks the cursor as stopped instead of deleting it, so a brief stop is bridged as an estimate and a longer one starts a new period as before. Older Cores still delete the cursor on open. Relates to #1750. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(history): forgiving Home use display, strict marker for training Follows Fredrik's two-layer direction (19 October). Display is forgiving: an unknown PV, battery or EV source holds its last known value; the site meter, a writer pause or a restart holds for at most two minutes; a topology change no longer stops integration. A day's flow is unknown only when it is unknown or unrecorded for more than a tenth of the range. Only two fully measured snapshots a safe tick apart, of one topology and one process, make a measured interval. Every other interval keeps EstimatedLoad, and quarter-hour retention now keeps that bit, so the training layer can skip it. Replaces the pending episodes of the first version. Closed source-era days cached under the old rule are recomputed once. Relates to #1750. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(history): stop holding a source that would make the house negative A held value that turns the household residual negative cannot be right: the source changed while unknown, such as a charger that finished. That interval leaves the held flows unknown instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(history): a failed source leaves only its own flow unknown historySources set MissingLoad for every reason except invalid_balance. Telemetry puts a source's own failure there too, such as "offline:sma:pv" or "stale:easee:ev", so a real snapshot with a silent inverter or charger voided the whole balance and the source writer held nothing. Only configuration and duplicate-flow reasons now set MissingLoad; a failed source is unknown on its own flag. Found by the #1755 session through historySources. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
A PV inverter that sleeps at night is the most common remaining reason for a day without Home use. Göran's SMA was silent for 145 s at 02:22 on 19 October with 0 W on both sides, longer than the 2-minute bridge. While the sun is below the horizon at the site's map pin, Core now records an unknown PV source as 0 W, marked EstimatedLoad, never as a measurement. An inverter the watchdog took offline keeps its device in the history topology, so the night is not cut out. The source writer carries the marker into every interval an estimated snapshot bounds. Without a pin (unset, 0,0 or the untouched default) nothing changes. By day the gap stays unknown. Grid, battery and EV are not affected. Relates to #1750. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Load models train only on fully measured intervals (#1754). Marking every dark PV snapshot as an estimate would drop each night with a sleeping inverter from training. Past civil dusk (zenith over 96°) no panel produces, so an unknown PV source now reads as a known 0 W without EstimatedLoad: the night counts in Home use and in training. Between sunset and civil dusk diffuse light remains, and the 0 W stays a marked estimate. No new bit records the physical zero. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rebased on the rewritten #1753, whose writer marks an interval as an estimate at an unknown source, a stop, a long gap or a topology change. A night past civil dusk therefore trains only if every snapshot is fully known and the sleeping inverter keeps its device in the topology. The devices line moves into historyDevices so the test drives the same code as persistTelemetryTick. The test runs eight hours of a sleeping inverter through it, with and without a map pin. TestDarkPVByTimeOfDay now also checks that PV reads 0 W and that Load stays unknown for any cause but PV; it replaces the two-hour series test, whose day-level outcome the new writer decides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#1753 (85100d6) no longer marks Load unknown when a single source fails, so darkPV need not clear it. It now changes only the PV flow and its marker; a configuration fault keeps Load unknown on its own. The night test without a pin checks Home use again: the writer holds PV's last value as an estimate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cc892be to
cc75e99
Compare
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| p.PVW = 0 | ||
| p.Missing &^= state.MissingPV |
There was a problem hiding this comment.
Preserve output from PV sources that are still reporting
When a site has multiple PV flows and only one becomes unavailable during twilight, Known[DerPV] is false for the aggregate even though ForecastReading.PVW still contains output from the remaining fresh sources. historySources consequently zeroes the aggregate, and clearing MissingPV here records every inverter as 0 W; for example, one sleeping inverter plus another producing diffuse-light power makes Home use too low for the affected intervals. Apply the zero assumption only to the unavailable PV flows, while retaining the contributions from sources that are still reporting.
Useful? React with 👍 / 👎.
historyDevices read cached PV readings directly to find a sleeping inverter. Move the health check into telemetry.OfflineDrivers, which returns only driver names, so no caller handles a stale cached value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stacked on #1753 (base
1750-bridge-short-history-gaps, rebuilt on 85100d6). Relates to #1750.Fredrik, 19 October: Home use has two layers. Display is lenient: #1753 now holds an unknown source's last known value and marks every such minute
EstimatedLoad. Training is strict: #1754 learns only from minutes without the mark. A sleeping inverter must not take every night out of the load models.What this adds to #1753
Holding a PV value is wrong after sunset: an inverter that went silent at dusk would carry its last evening reading through the night. While the sun is below the horizon at the site's map pin, Core records an unknown PV source as 0 W instead. This is physics, not interpolation.
EstimatedLoad, and fix(history): keep Home use through device dropouts and restarts #1753's writer marks every interval it bounds. Home use counts those minutes; training skips them.historyDevices, shared bypersistTelemetryTickand the test.siteLocation, which already rejects those.Sun positions come from the existing
sunpospackage. No new setting, table, API field or UI. Ingo/internal/statethis PR adds only a comment and a test.Evidence
TestDarkPVByTimeOfDay, Västerås on 19 October (sunset 17:38, civil dusk about 18:20), a snapshot with PV unknown:EstimatedLoadTestSleepingInverterNightIsMeasured: eight hours on the equator, past civil dusk in every season. A 1000 W house; the inverter reports 0 W for ten minutes, then sleeps, and a minute later the watchdog takes it offline. Snapshots go throughhistorySources,darkPVandhistoryDevices, as inpersistTelemetryTick, into #1753's writer.TestSourceLoadMarksIntervalsOfAnEstimatedSnapshotpins the contract this relies on: a marked snapshot marks the minutes it bounds and no others.Each part fails its test when switched off: no dark rule, a mark at every dark snapshot, no mark in twilight, no sleeping device (2 topologies), and Load cleared along with PV.
With #1754 (
fix/load-models-use-history-intervalsat fe42b90, merged with this branch outside the repo;go test ./internal/state ./internal/loadmodel ./cmd/ftwpasses):These tests need
HouseholdIntervals, so they can join whichever of #1754 and this lands second.make verify: passed on cc892be. All 77 Go packages, protocol and script tests, vet and build. Nothing skipped.Found on the way
historySourcesused to mark Load unknown whenever one source failed, which kept #1753's hold from working in Core. Reported here; #1753 fixed it in 85100d6. This PR's night test without a pin now checks Home use again.Not verified
For Fredrik to decide
Already answered: relax the day rule too (now in #1753, so #1756 is superseded); reuse
EstimatedLoadwith no new bit;pv_whknown at night.🤖 Generated with Claude Code