feat(ocpp): restore the OCPP 1.6J Central System - #732
Draft
HuggeK wants to merge 2 commits into
Draft
Conversation
Brings back go/internal/ocpp, retired as unused in srcfl#578, so EV chargers can connect to FTW directly instead of through a vendor cloud. The package is restored unchanged and still builds, vets and passes its own tests against the current tree. github.com/lorenzodonini/ocpp-go resolves to v0.19.0 at @latest — the same version that was removed, since upstream has not cut a release since August 2025. Nothing is wired into main.go yet, so this changes no runtime behaviour. Two known gaps are carried over from the original and must be closed before the server is enabled: - Config.Bind is advisory only. ocpp-go does not expose a bind address, so the listener takes 0.0.0.0 regardless, and Phase 1 has no TLS. - Handlers are read-only. Charge Amps needs SetChargingProfile-based control, because its RemoteStopTransaction is unreliable in the field. Co-authored-by: HuggeK <48095810+HuggeK@users.noreply.github.com>
Co-authored-by: HuggeK <48095810+HuggeK@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings back
go/internal/ocpp, retired as unused in #578, so EV chargers canconnect to FTW directly instead of through a vendor cloud.
Groundwork only — nothing is wired into
main.go, so runtime behaviour isunchanged. Opening early because the design questions below are worth settling
before the wiring lands.
Why this comes back
Bench testing six chargers turned up a gap: Charge Amps has no FTW driver at
all, and three of the six units are Charge Amps. Every current model speaks
OCPP 1.6J since Charge Amps migrated off its proprietary CAPI protocol.
The wider picture, from srcfl/device-drivers#52:
Easee and Zaptec need a one-time cloud commissioning step, Charge Amps needs
none — but after commissioning all three dial out to a local central system
and the cloud leaves the runtime path entirely. One server covers all of them.
State of the restore
Restored unchanged from
61c5250^. It still builds, vets, and passes its owntests against the current tree — the original deletion was clean.
go get github.com/lorenzodonini/ocpp-go@latestresolves to v0.19.0 — thesame version that was removed. Upstream has not cut a release since August 2025
(367★, 117 open issues, MIT, not archived).
Why a Go module and not a git submodule
A submodule was considered and rejected.
go buildresolves the dependencythrough
go.modand the module cache, so a submodule checkout would be inertunless paired with a
replacedirective — and that would make the repounbuildable for anyone cloning without
--recurse-submodules, breakgo install, and force submodule-aware checkout into CI,make build-arm64,Docker and the release flow. FTW uses no submodules today.
If we end up carrying patches upstream will not take, the right move is a
srcfl/ocpp-gofork plus areplacedirective — still an ordinary Go module.Given upstream's release cadence, that is the likely destination.
Gaps that must close before this is enabled
Both are carried over from the original, not introduced here.
Config.Bindis advisory only. ocpp-go exposes no bind address, so thelistener takes
0.0.0.0regardless of config, and Phase 1 has no TLS. On a Pithis is an unauthenticated-by-default WebSocket on every interface. Basic auth
is optional and off unless configured. This needs fixing before the server can
ship enabled.
Design questions
1. How should an OCPP charger surface as a device? The restored code writes
straight into
telemetry.Storefrom Go, keyed bychargePointId, with no Luadriver involved. That sits awkwardly against AGENTS.md, which says drivers own
vendor protocols and are the only place power signs are converted. It is also
inverted from the driver model: Lua drivers poll, OCPP chargers dial in and push.
Either OCPP stays a core service that synthesises device entries and handles
vendor quirks in Go, or the server exposes a host API so Lua drivers consume
OCPP messages. Worth deciding before the wiring.
2. Control should be current-based, not
RemoteStopTransaction. Charge Ampsremote stop is unreliable in other OCPP integrations — units bounce straight back
to on. The path that works is
SetChargingProfileat 0 A to stop and targetamps to start. Phase 2 should model stop that way.
🤖 Generated with Claude Code