Skip to content

OCPP: fix non-blocking RemoteStartTransaction#29210

Draft
Copilot wants to merge 2 commits intomasterfrom
copilot/fix-remote-start-transaction
Draft

OCPP: fix non-blocking RemoteStartTransaction#29210
Copilot wants to merge 2 commits intomasterfrom
copilot/fix-remote-start-transaction

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 18, 2026

OnStatusNotification called RemoteStartTransactionRequest synchronously while holding conn.mu. The ocpp-go library only sends the StatusNotification response after the handler returns. Charge points like Zaptec Go 2 won't process the incoming RemoteStartTransaction until they receive that response — deadlock until the 1-minute OCPP timeout fires, at which point the RemoteStartTransaction is silently lost. First session works; every subsequent plug-in fails.

  • charger/ocpp/connector_core.go: Launch RemoteStartTransactionRequest in a goroutine so the StatusNotification response is sent back immediately. Added error logging for failures.
// before: blocks handler, delays StatusNotification response
conn.RemoteStartTransactionRequest(conn.remoteIdTag)

// after: handler returns immediately, CP receives response before RemoteStartTransaction arrives
go func() {
    if err := conn.RemoteStartTransactionRequest(idTag); err != nil {
        conn.log.ERROR.Printf("RemoteStartTransaction: %v", err)
    }
}()
  • charger/ocpp/connector_test.go: Added TestStatusNotificationPreparingNonBlocking (verifies handler returns promptly) and TestRemoteStartAfterReconnect (verifies isWaitingForAuth state across full connect→charge→disconnect→reconnect cycle).

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 224.0.0.251
    • Triggering command: REDACTED, pid is -1 (packet block)

If you need me to access, download, or install something from one of these locations, you can either:

… handler

When OnStatusNotification was called with Preparing status and remoteStart
was enabled, RemoteStartTransactionRequest was called synchronously while
holding conn.mu. This blocked the handler goroutine, which delayed the
StatusNotification response back to the charge point. Some charge points
(like Zaptec Go 2) may not process the incoming RemoteStartTransaction
while still waiting for the StatusNotification response, causing a deadlock
that only resolved after the OCPP timeout (1 minute).

After the timeout, the RemoteStartTransaction was effectively lost. On
subsequent vehicle connections, the same pattern repeated, preventing
charging from starting.

The fix launches RemoteStartTransactionRequest in a separate goroutine so
that OnStatusNotification returns immediately, allowing the StatusNotification
response to be sent back to the charge point promptly. This ensures the
charge point is in the correct state to process the RemoteStartTransaction.

Fixes #19965

Agent-Logs-Url: https://github.com/evcc-io/evcc/sessions/043e1352-8e68-4325-af8b-38c78575a2d7

Co-authored-by: premultiply <4681172+premultiply@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix remote start transaction issue for Zaptec Go 2 fix: make RemoteStartTransaction non-blocking in OnStatusNotification Apr 18, 2026
Copilot AI requested a review from premultiply April 18, 2026 05:03
@premultiply premultiply changed the title fix: make RemoteStartTransaction non-blocking in OnStatusNotification OCPP: fix non-blocking RemoteStartTransaction Apr 18, 2026
@andig andig added the devices Specific device support label Apr 18, 2026
@premultiply premultiply marked this pull request as ready for review April 20, 2026 21:18
Copilot AI review requested due to automatic review settings April 20, 2026 21:18
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes an OCPP deadlock where OnStatusNotification synchronously triggered RemoteStartTransactionRequest, delaying the StatusNotification confirmation and preventing some charge points from processing the remote start until the OCPP timeout.

Changes:

  • Make RemoteStartTransactionRequest non-blocking by dispatching it in a goroutine from OnStatusNotification.
  • Add error logging for failed RemoteStartTransactionRequest attempts.
  • Add unit tests covering “Preparing” status handling and remote-start-related state transitions across a stop/start cycle.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
charger/ocpp/connector_core.go Avoids blocking the OCPP handler by running RemoteStartTransactionRequest asynchronously and logging failures.
charger/ocpp/connector_test.go Adds tests for non-blocking status handling and re-entering “waiting for auth” after a completed transaction.

Comment on lines 40 to +46
if conn.isWaitingForAuth() {
if conn.remoteIdTag != "" {
conn.RemoteStartTransactionRequest(conn.remoteIdTag)
if idTag := conn.remoteIdTag; idTag != "" {
go func() {
if err := conn.RemoteStartTransactionRequest(idTag); err != nil {
conn.log.ERROR.Printf("RemoteStartTransaction: %v", err)
}
}()
Comment on lines +170 to +179
done := make(chan struct{})
go func() {
_, err := suite.conn.OnStatusNotification(req)
suite.NoError(err)
close(done)
}()

select {
case <-done:
// handler returned promptly
@premultiply premultiply marked this pull request as draft April 20, 2026 21:33
@github-actions github-actions Bot added the stale Outdated and ready to close label Apr 27, 2026
@premultiply premultiply removed the stale Outdated and ready to close label Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

devices Specific device support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Zaptec Go 2 (OCPP)- RemoteStartTransaction not sent

4 participants