Skip to content

feat(zap): opt-in read-only PV and battery ingest - #100

Merged
frahlg merged 1 commit into
mainfrom
zap-opt-in-read
Aug 24, 2026
Merged

feat(zap): opt-in read-only PV and battery ingest#100
frahlg merged 1 commit into
mainfrom
zap-opt-in-read

Conversation

@frahlg

@frahlg frahlg commented Aug 23, 2026

Copy link
Copy Markdown
Member

Summary

Zap 3.1.0 keeps P1/HAN as the default and brings back opt-in, read-only ingest of PV and battery from devices Zap already talks to.

That matches the field case where a native inverter driver cannot be used (SolarEdge Modbus closed, no SetApp; or Zap already owns the RS-485 bus). Dual-Modbus sites stay on the 3.0 path: flags default off, so a native FTW driver is not doubled.

The driver still never writes. Chargers stay out — add those in FTW.

Config

config:
  host: zap.local
  read_pv: true        # default false
  read_battery: true   # default false

FTW Settings → Devices will expose the same switches once the bundled pin moves.

Test plan

  • make test-driver ID=zap
  • catalog generate (index, devices, support-status, manifests sha)
  • full pytest + host-api + sandbox + baseline check
  • FTW go test ./internal/drivers -run Zap against this commit (companion PR)

Note

Medium Risk
Core production driver now emits extra DERs when flags are on, so a misconfigured site can double-count PV/battery against a native driver. Still read-only; flags default off.

Overview
Zap 3.1.0 keeps P1/HAN as the default and adds opt-in, read-only PV and battery ingest from devices Zap already talks to (read_pv / read_battery, off by default). Chargers stay out; the driver still never writes.

Discovery now tracks per-serial meter/PV/battery records. When opted in, poll fetches those device snapshots, aggregates power (PV forced generation-negative; battery SoC capacity-weighted when possible), and drops overflow sentinels via a 10× nameplate sane_power guard. Catalog/manifest ders become [meter, pv, battery].

Reviewed by Cursor Bugbot for commit 5342bf2. Bugbot is set up for automated code reviews on this repo. Configure here.

@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: 60021a0b07

ℹ️ 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 thread drivers/lua/zap.lua
end
end

if any_power then

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 Suppress aggregates when any tracked source fails

When read_pv tracks multiple resources and one /data/json request fails or lacks a valid W, any_power can remain true because another resource succeeded, so this publishes a partial sum as the complete site PV value; the battery aggregate has the same behavior. Downstream consumers cannot distinguish that undercount from a real production or battery-power change, so suppress or explicitly invalidate the aggregate unless every tracked source contributes a current valid sample.

Useful? React with 👍 / 👎.

Comment thread manifests/zap.yaml
Comment on lines +15 to +16
notes: "P1/HAN site meter from a Sourceful Zap. PV and battery telemetry from devices on Zap are opt-in (read_pv / read_battery) and read-only. Prefer a native FTW driver; use Zap as the reader only when it already owns the bus."
min_driver_version: "3.1.0"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Record the Zap API in upstream_docs

The new PV and battery serializers are decoded from the Zap Local API referenced by the driver, but the updated manifest still has no upstream_docs entry. Consequently, the repository's weekly documentation watcher cannot detect when the payload contract changes or disappears; add that API URL and its metadata to this manifest.

AGENTS.md reference: AGENTS.md:L60-L66

Useful? React with 👍 / 👎.

@frahlg

frahlg commented Aug 23, 2026

Copy link
Copy Markdown
Member Author

Companion FTW PR: srcfl/ftw#974 — Settings → Devices opt-in, tests, docs, bundled pin.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 60021a0. Configure here.

Comment thread drivers/lua/zap.lua
else
host.log("warn", "Zap: site-meter fetch failed: " .. tostring(err))
end
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Duplicate meter fetch on failure

Medium Severity

After a successful discovery the site meter is always in tracked and already requested in the first loop of snapshot_map. When that request fails, the trailing fallback fetches the same URL again and logs the same warn a second time. Each failed poll therefore pays two HTTP round-trips and duplicate warnings before emit_meter also reports the gap.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 60021a0. Configure here.

Comment thread drivers/lua/zap.lua
end
end

if not any_power then return end

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Battery emit drops valid SoC

Medium Severity

emit_battery accumulates SoC and energy, then returns early unless sane_power accepted W. The driver comment notes Zap can return integer overflow sentinels when a unit is offline; with a known nameplate those values are rejected, so a still-valid SoC_nom_fract never reaches host.emit("battery", ...). Catalog guidance is to emit the battery DER when any answered field is usable, not only power.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 60021a0. Configure here.

@cursor
cursor Bot requested review from Leitet and davmoz August 23, 2026 16:59

@cursor cursor 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.

Stale comment

Left a non-blocking comment: Cursor Bugbot found two unresolved medium-severity issues, so this is not approved. Assigned Leitet and davmoz for human review.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

P1/HAN stays the default. Sites where Zap is the only reader — closed
inverter Modbus, or an RS-485 bus Zap already owns — can set read_pv
or read_battery. The driver still never writes. Chargers stay out.

Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
@frahlg
frahlg merged commit 19dd64c into main Aug 24, 2026
9 checks passed
@frahlg
frahlg deleted the zap-opt-in-read branch August 24, 2026 08:49
frahlg added a commit to srcfl/ftw that referenced this pull request Aug 24, 2026
srcfl/device-drivers#100 landed as 19dd64cc. Point the recovery snapshot
at that commit instead of the PR head.

Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>

@cursor cursor 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.

Left a non-blocking comment: Cursor Bugbot skipped on this head (neutral/skipped), so this is not approved. Leitet and davmoz are already assigned; no additional reviewers were added.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

frahlg added a commit to srcfl/ftw that referenced this pull request Aug 24, 2026
* feat(zap): opt-in read of PV and battery from Zap

Keep Zap as the P1/HAN meter by default. Settings → Devices can turn on
read-only PV or battery ingest when Zap is the only reader. The driver
never writes. Bundled pin moves to srcfl/device-drivers@60021a0
(srcfl/device-drivers#100).

Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>

* chore(drivers): pin Zap 3.1.0 at the device-drivers merge

srcfl/device-drivers#100 landed as 19dd64cc. Point the recovery snapshot
at that commit instead of the PR head.

Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>

---------

Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
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.

1 participant