Skip to content

fix(ocpp): take up a running 1.6 transaction after a Core restart - #1787

Draft
frahlg wants to merge 1 commit into
masterfrom
fix/ocpp-resume-transaction
Draft

frahlg wants to merge 1 commit into
masterfrom
fix/ocpp-resume-transaction

Conversation

@frahlg

@frahlg frahlg commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Draft for the next beta (owner's scope decision, 21 Oct 2026). Do not merge before that beta is cut.

Problem

Core restarts on every update. An OCPP 1.6 charger keeps its transaction through the restart and goes on naming it in MeterValues. Core started every charger with no transaction (transactionID −1) and handed out ids from 1 again. For a session that spans a restart:

  • session_wh stayed at 0 until unplug, because OnMeterValues counts energy only while a transaction is known. The rig shows it: s7-25 with fix(loadpoint): Charge now keeps charging after a restart #1778 ended with ev_session_wh 0 while the car drew 11 kW.
  • The stop computed MeterStop − 0, which is the charger's lifetime meter total. The simulator starts its meter at 0, which hides this; a real charger reports its lifetime register.
  • A new transaction could get id 1 while another charger still held 1.

Change

All in go/internal/ocpp/handlers.go:

  • The first MeterValues that names a transaction while none is known takes it up. Energy counts from that reading. A transaction the charger already stopped is not taken up again, so a late meter value cannot drop session_wh to 0 while the car is plugged in.
  • A stop for a transaction Core never saw keeps session_wh as it was and records no ev_session_wh metric.
  • Transaction ids start at the seconds since 1 January 2026. A restart starts above the ids the last run used unless that run started more transactions than it ran seconds, and the ids stay far inside 32 bits. A taken-up id also moves the next id past it.

OCPP 2.0.1 is unchanged. It has the same gap in OnTransactionEvent (Updated with no known transaction).

What this does not fix

  • Energy from before the restart is still lost. The start reading lived only in the old process, so delivered_wh_session still restarts near 0.
  • FTW's saved last order (restoreOffers) is still not restored for OCPP. It needs session_wh that has not gone back. After a restart Core also sends its first command about 1 s after the charger reconnects, before the first MeterValues (8 s later in the rig, often a minute on real chargers). A fix needs the start reading kept in state.db and a first command that waits for a reading or asks for one.

Evidence

🤖 Generated with Claude Code

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 21, 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-21T15:50:10.571516Z 89f2cce 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: 89f2cceea6

ℹ️ 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 +609 to +610
s.transactionID = txID
s.sessionStartMeterWh = meterWh

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 Reject non-finite readings before adopting a transaction

If the first energy register received after restart contains "NaN" or "Inf", strconv.ParseFloat accepts it without an error, and this assignment permanently stores a non-finite session baseline. Every subsequent valid reading then produces non-finite session energy, and pushReading cannot marshal its telemetry payload because JSON rejects these values. Unlike a bad sample during an ordinarily started transaction, later valid samples cannot recover this session. Check that the converted meter reading is finite before adopting the transaction so a later valid reading can establish its baseline.

Useful? React with 👍 / 👎.

@frahlg
frahlg marked this pull request as draft October 21, 2026 16:20
A charger keeps its transaction while Core restarts and keeps naming it in
MeterValues. Core started every charger with no transaction, so session
energy stayed at 0 until unplug and the stop reported the lifetime meter
total. Take the transaction up from its first meter value, count energy
from that reading, and start transaction ids from the clock so a restart
does not hand out an id a charger still holds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@frahlg
frahlg force-pushed the fix/ocpp-resume-transaction branch from 89f2cce to f5ca0f6 Compare October 21, 2026 16:23
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