Skip to content

fix(history): keep the chart running when optional PV never reports - #1480

Merged
frahlg merged 2 commits into
masterfrom
1441-history-after-reload
Oct 1, 2026
Merged

frahlg merged 2 commits into
masterfrom
1441-history-after-reload

Conversation

@frahlg

@frahlg frahlg commented Oct 1, 2026

Copy link
Copy Markdown
Member

Thanks @segran2 for the detailed report. The exact timestamps, the cursor rows and the note that raw tables kept moving made this quick to find.

Problem

Adding a Zap P1 meter stopped history_dashboard and history_site_energy for good. Restarts did not help.

  • The Zap catalog lists meter, pv and battery. PV reading is off unless read_pv is set.
  • forecastMeasurementTopology (go/cmd/ftw/forecast_measurements.go) still adds sourceful-zap:pv to the expected flows when read_pv is missing. It marks it optional_pv_requires_measurement.
  • Since feat(forecast): use learned PV and load as primary forecasts #1089, buildHistoryPoint checks the balance with those forecast options. The Zap never reports PV, so the balance is missing:sourceful-zap:pv on every tick. The tick then stores no history point.
  • With no point, recordDashboardTx writes last=0 and nothing else. That is the cursor state in the report. It is a symptom, not stuck state.
  • The config is the same after a restart, so the same block comes back.

The forecast identity gate (unconfirmed_device_identity) blocks history the same way while any device identity is unconfirmed.

Change

History gets its own options, HistoryOptions:

  • the same expected flows, minus PV that config does not declare;
  • no identity gate.

PV that a source does report is still checked, so a stale reading still stops history. Missing known flows (battery, dedicated PV, EV) still stop it too. Forecast learning keeps its strict options. HistoryOptions is not part of any revision, so this resets no learned model.

After upgrade

No manual repair is needed. The next valid point sets last and writes a dashboard row. The gap since the freeze stays a gap. Until then, setting read_pv: false on the Zap driver also unblocks history on the current release.

Evidence

  • New TestHistoryKeepsRunningWithOptionalPVAndUnconfirmedIdentity builds the reported site: Zap site meter, SMA PV, Pixii battery, one unconfirmed identity. It fails on master with available=false, with or without the identity gap. It passes with this change. It also checks that an offline battery or a stale reported PV reading still stops history.
  • go test ./cmd/ftw -count=1 passes.
  • make verify passes.

Closes #1441

🤖 Generated with Claude Code

Adding a Zap P1 meter stopped history_dashboard and history_site_energy
for good. The Zap catalog lists pv, but PV reading is off unless
read_pv is set. The forecast topology still expects a PV reading from
it, and since #1089 the history point uses those same forecast options.
The Zap never reports PV, so every tick wrote no history point, and the
same config rebuilt the same block after each restart.

History now uses its own options: the same flows, minus PV that config
does not declare, and without the identity gate. PV that a source does
report is still checked for freshness. Forecast learning is unchanged.

Closes #1441

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-01T09:19:28.789453Z 76643ea PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 76643ea128

ℹ️ 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".

Comment on lines +29 to +30
if !optional[flow] {
flows = append(flows, flow)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep optional PV invalid until its driver is live

When a catalog entry combines PV with another capability and the configuration does not explicitly declare PV, this removes the PV flow even if the driver is offline or has not completed its first poll. If that device really supplies PV, the telemetry scan has no reading with which to add it back, so the site-meter-only balance is accepted and history permanently records PV as zero and grid power as household load until the first PV sample arrives—potentially throughout an outage. Treat the missing optional flow as absent only after the live driver has established that it will not publish PV, so freshness failures do not become measured energy.

AGENTS.md reference: AGENTS.md:L22-L23

Useful? React with 👍 / 👎.

@frahlg
frahlg merged commit 274ace8 into master Oct 1, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

history_dashboard/history_site_energy stop after config hot-reload

1 participant