gocpp

module
v0.1.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 17, 2026 License: MIT

README

gocpp

A generics-first OCPP (Open Charge Point Protocol) implementation in Go, supporting OCPP 1.6, 2.0.1, and 2.1 from a single module.

Status: pre-v1, under active development. Public API may still change before v1.0.

Why gocpp

A from-scratch alternative to lorenzodonini/ocpp-go with:

  • All three versions (1.6 / 2.0.1 / 2.1) generated from the official OCA JSON schemas — no hand-written, drift-prone message structs.
  • Generics-first API — typed On[Req,Resp] handlers and Call[Req,Resp], so request/response types are inferred from a single message value.
  • Context-native concurrency — every connection owns reader/writer/dispatch goroutines bound to a context; teardown flows from one cancel(cause). Race- and goroutine-leak-tested (-race + goleak).
  • Two-layer validation — JSON-Schema validation against the embedded official schemas (source of truth), plus generated validate struct tags.
  • Pluggable Storage / Auth / Observability with in-memory / NoOp defaults and Prometheus + OpenTelemetry adapters.

Install

go get github.com/shiv3/gocpp

Requires Go 1.25+.

Quick start

CSMS (central system)
srv := csms.NewServer(csms.WithSubProtocols("ocpp2.1", "ocpp2.0.1", "ocpp1.6"))

csms.On(srv, v16p.BootNotification, func(ctx context.Context, c *csms.Conn, req v16msg.BootNotificationRequest) (v16msg.BootNotificationResponse, error) {
    return v16msg.BootNotificationResponse{
        Status:      v16msg.RegistrationStatusAccepted,
        CurrentTime: time.Now(),
        Interval:    300,
    }, nil
})

log.Fatal(srv.ListenAndServe(":8080")) // ws://host:8080/ocpp/{cpId}
Charge point (client)
client := cp.NewClient("CP_1", "ws://localhost:8080/ocpp/CP_1", cp.WithSubProtocols("ocpp1.6"))
if err := client.Connect(ctx); err != nil { log.Fatal(err) }
defer client.Close()

resp, err := cp.Call(ctx, client, v16p.BootNotification, v16msg.BootNotificationRequest{
    ChargePointVendor: "Acme", ChargePointModel: "Model-X",
})

Runnable examples: examples/csms-minimal, examples/cp-minimal.

Packages

Import Purpose
csms CSMS server: NewServer, On, Call, Get
cp Charge point client: NewClient, Connect, On, Call, Run
v16, v201, v21 Per-version metadata + RegisterSchemas
v16/messages, …/profiles Generated message structs + ocppj.Message profile vars
core/ocppj OCPP-J framing (Call/CallResult/CallError), errors
core/dispatcher Version-agnostic connection lifecycle + pending-call tracking
core/schema JSON-Schema validator + registry
core/auth Authenticator: None, BasicAuth, MTLSFromClientCert
core/storage (+ /memory) ConnectionRegistry, MessageRouter, TransactionStore, ConfigStore
core/observability (+ /metrics/{prom,otel}) Metrics (NoOp/Prometheus/OpenTelemetry), OTel tracer

Addons

Optional extensions live under addons/, each a separate nested module so their heavy dependencies stay out of the core dependency tree:

Addon Purpose
addons/router-redis storage.MessageRouter over Redis Pub/Sub (multi-instance CSMS)
addons/router-nats storage.MessageRouter over NATS request/reply
addons/router-temporal Durable Temporal-backed MessageRouter (experimental)
addons/statefsm OCPP 1.6 connector state-machine helper
addons/tenant Multi-tenant partitioning of the pluggable stores
go get github.com/shiv3/gocpp/addons/router-redis

See addons/README.md for details.

Validation

Layer 1 (wire): enable strict schema validation on the connection so malformed inbound messages are rejected with a CallError before reaching your handler:

reg := schema.NewRegistry()
v201.RegisterSchemas(reg)
srv := csms.NewServer(
    csms.WithSubProtocols("ocpp2.0.1"),
    csms.WithSchemaRegistry(reg),
    csms.WithStrictSchema(true),
)

Schema handling is three-state. With a registry set:

  • WithStrictSchema(true) — reject invalid messages with FormationViolation.
  • WithTolerantSchema() — log a warning and process anyway (for real chargers that send undefined enums or extra fields).
  • WithStrictSchema(false) (default) — validation off.

cp.WithTolerantSchema() / cp.WithStrictSchema() do the same on the charge-point side.

Production features

srv := csms.NewServer(
    csms.WithAuthenticator(auth.BasicAuth(verify)),     // Security Profile 1/2 (verify(cpID, password))
    csms.WithMetrics(otelmetrics.New(meterProvider)),   // OpenTelemetry metrics (or prom.New for Prometheus)
    csms.WithTracerProvider(tp),                        // OpenTelemetry spans
    csms.WithConnectionRegistry(myRegistry),            // pluggable
    csms.WithCPIDExtractor(extractCPID),                // dynamic path routing, e.g. /{org}/{cpId}
    csms.WithDuplicatePolicy(csms.DuplicatePolicyRejectNew), // or CloseExisting (default)
)

Handlers can read connection metadata from the *csms.Conn: c.RemoteAddr(), c.RequestHeader(), c.TLS(), c.Subprotocol(). The authenticator receives the parsed charge point id: Authenticate(r *http.Request, cpID string). To send an untyped CSMS→CP operation, use csms.CallRaw(ctx, conn, action, payloadJSON).

Tooling

go install github.com/shiv3/gocpp/cmd/gocpp-validate@latest
go install github.com/shiv3/gocpp/cmd/gocpp-sim@latest
  • gocpp-validate --version 2.0.1 --action BootNotification msg.json — validate a message against the official schema.
  • gocpp-sim run -s scenario.yaml — drive a simulated charge point through a YAML scenario against a CSMS.

Testing

make test          # go test ./...
make test-race     # go test -race ./...
make codegen       # regenerate v16/v201/v21 from schemas/

The internal/conformance suite ports lorenzodonini/ocpp-go's per-message test cases (validation tables + direction enforcement) across all 188 messages of 1.6/2.0.1/2.1.

Documentation

License

MIT

Directories

Path Synopsis
addons
router-redis module
Package benchmarks holds performance benchmarks for gocpp.
Package benchmarks holds performance benchmarks for gocpp.
cmd
gocpp-sim command
Command gocpp-sim simulates an OCPP charge point.
Command gocpp-sim simulates an OCPP charge point.
gocpp-sim/cmd
Package cmd implements the gocpp-sim CLI.
Package cmd implements the gocpp-sim CLI.
gocpp-sim/sim
Package sim implements a charge point simulator driven by YAML scenarios.
Package sim implements a charge point simulator driven by YAML scenarios.
gocpp-validate command
Command gocpp-validate validates OCPP JSON messages against official schemas.
Command gocpp-validate validates OCPP JSON messages against official schemas.
gocpp-validate/cmd
Package cmd implements the gocpp-validate CLI.
Package cmd implements the gocpp-validate CLI.
core
auth
Package auth provides connection authentication for the CSMS.
Package auth provides connection authentication for the CSMS.
codec
Package codec is the internal JSON seam.
Package codec is the internal JSON seam.
datatransfer
Package datatransfer provides typed helpers for the free-form DataTransfer payload, whose Data field is an optional JSON string (*string) in every OCPP version.
Package datatransfer provides typed helpers for the free-form DataTransfer payload, whose Data field is an optional JSON string (*string) in every OCPP version.
dispatcher
Package dispatcher implements the version-agnostic OCPP connection lifecycle, pending-call tracking, and concurrency control.
Package dispatcher implements the version-agnostic OCPP connection lifecycle, pending-call tracking, and concurrency control.
observability
Package observability defines logging, tracing, and metrics abstractions.
Package observability defines logging, tracing, and metrics abstractions.
observability/metrics/otel
Package otel implements observability.Metrics on top of the OpenTelemetry metrics API.
Package otel implements observability.Metrics on top of the OpenTelemetry metrics API.
observability/metrics/prom
Package prom implements observability.Metrics using Prometheus.
Package prom implements observability.Metrics using Prometheus.
ocppj
Package ocppj implements OCPP-J (JSON over WebSocket) framing.
Package ocppj implements OCPP-J (JSON over WebSocket) framing.
schema
Package schema provides JSON Schema validation backed by santhosh-tekuri/jsonschema.
Package schema provides JSON Schema validation backed by santhosh-tekuri/jsonschema.
storage
Package storage defines pluggable persistence and routing abstractions.
Package storage defines pluggable persistence and routing abstractions.
storage/memory
Package memory provides in-memory implementations of the storage interfaces.
Package memory provides in-memory implementations of the storage interfaces.
transport
Package transport abstracts the WebSocket layer so the dispatcher never touches a concrete websocket library.
Package transport abstracts the WebSocket layer so the dispatcher never touches a concrete websocket library.
Package cp implements the OCPP Charge Point (client) side.
Package cp implements the OCPP Charge Point (client) side.
Package csms implements the OCPP Central System (CSMS / server) side.
Package csms implements the OCPP Central System (CSMS / server) side.
examples
cp-minimal command
Command cp-minimal is a minimal OCPP 1.6 charge point.
Command cp-minimal is a minimal OCPP 1.6 charge point.
csms-full command
Command csms-full is a fairly complete OCPP 1.6 CSMS built on gocpp, wiring the pluggable storage (transactions, config, connection registry), OpenTelemetry metrics and traces, structured logging, health endpoints, and graceful shutdown.
Command csms-full is a fairly complete OCPP 1.6 CSMS built on gocpp, wiring the pluggable storage (transactions, config, connection registry), OpenTelemetry metrics and traces, structured logging, health endpoints, and graceful shutdown.
csms-minimal command
Command csms-minimal is a minimal OCPP 1.6 CSMS.
Command csms-minimal is a minimal OCPP 1.6 CSMS.
migration-after command
Command migration-after is the gocpp rewrite of a minimal lorenzodonini/ocpp-go CSMS handling BootNotification and Heartbeat — see docs/migration-from-lorenzodonini.md.
Command migration-after is the gocpp rewrite of a minimal lorenzodonini/ocpp-go CSMS handling BootNotification and Heartbeat — see docs/migration-from-lorenzodonini.md.
internal
codegen command
Command codegen generates OCPP message types and profile vars from JSON schemas and a profile YAML.
Command codegen generates OCPP message types and profile vars from JSON schemas and a profile YAML.
codegen/cmd/diff command
Command diff emits a markdown changelog of message-set differences between two generated OCPP versions (e.g.
Command diff emits a markdown changelog of message-set differences between two generated OCPP versions (e.g.
codegen/diff
Package diff computes message-set differences between two OCPP versions.
Package diff computes message-set differences between two OCPP versions.
codegen/ir
Package ir is the version-agnostic intermediate representation used by codegen.
Package ir is the version-agnostic intermediate representation used by codegen.
codegen/loader
Package loader reads codegen inputs: JSON schemas and profile YAML.
Package loader reads codegen inputs: JSON schemas and profile YAML.
codegen/naming
Package naming converts schema names into Go identifiers.
Package naming converts schema names into Go identifiers.
codegen/render
Package render turns codegen IR into formatted Go source.
Package render turns codegen IR into formatted Go source.
conformance
Package conformance provides shared helpers for porting message-level OCPP conformance tests.
Package conformance provides shared helpers for porting message-level OCPP conformance tests.
conformance/conf16a
Package conf16a contains OCPP 1.6 per-message conformance tests.
Package conf16a contains OCPP 1.6 per-message conformance tests.
conformance/conf16b
Package conf16b contains OCPP 1.6 Group B conformance tests.
Package conf16b contains OCPP 1.6 Group B conformance tests.
conformance/conf16c
Package conf16c contains OCPP 1.6 per-message conformance tests for group C.
Package conf16c contains OCPP 1.6 per-message conformance tests for group C.
conformance/conf201a
Package conf201a contains OCPP 2.0.1 per-message conformance tests.
Package conf201a contains OCPP 2.0.1 per-message conformance tests.
conformance/conf201b
Package conf201b contains OCPP 2.0.1 per-message conformance tests.
Package conf201b contains OCPP 2.0.1 per-message conformance tests.
conformance/conf201c
Package conf201c contains OCPP 2.0.1 message-level conformance tests.
Package conf201c contains OCPP 2.0.1 message-level conformance tests.
conformance/conf201d
Package conf201d contains OCPP 2.0.1 per-message conformance tests for group 201-D.
Package conf201d contains OCPP 2.0.1 per-message conformance tests for group 201-D.
conformance/conf201e
Package conf201e contains OCPP 2.0.1 group 201-E message-level conformance tests.
Package conf201e contains OCPP 2.0.1 group 201-E message-level conformance tests.
conformance/conf201f
Package conf201f contains OCPP 2.0.1 per-message conformance tests for group 201-F.
Package conf201f contains OCPP 2.0.1 per-message conformance tests for group 201-F.
conformance/conf21a
Package conf21a contains GROUP 21-A per-message conformance tests for OCPP 2.1.
Package conf21a contains GROUP 21-A per-message conformance tests for OCPP 2.1.
conformance/conf21b
Package conf21b contains OCPP 2.1 GROUP 21-B per-message conformance tests.
Package conf21b contains OCPP 2.1 GROUP 21-B per-message conformance tests.
conformance/conf21c
Package conf21c contains OCPP 2.1 per-message conformance tests for group 21-C.
Package conf21c contains OCPP 2.1 per-message conformance tests for group 21-C.
conformance/conf21d
Package conf21d contains OCPP 2.1 group D conformance tests.
Package conf21d contains OCPP 2.1 group D conformance tests.
conformance/conf21e
Package conf21e contains OCPP 2.1 GROUP 21-E per-message conformance tests.
Package conf21e contains OCPP 2.1 GROUP 21-E per-message conformance tests.
conformance/conf21f
Package conf21f contains OCPP 2.1 per-message conformance tests (GROUP 21-F).
Package conf21f contains OCPP 2.1 per-message conformance tests (GROUP 21-F).
conformance/conf21g
Package conf21g contains OCPP 2.1 group G per-message conformance tests.
Package conf21g contains OCPP 2.1 group G per-message conformance tests.
e2e
Package e2e holds cross-package end-to-end tests for gocpp.
Package e2e holds cross-package end-to-end tests for gocpp.
Package interop holds tests that run gocpp against real external OCPP implementations (CitrineOS, SteVe, EVerest, simulators).
Package interop holds tests that run gocpp against real external OCPP implementations (CitrineOS, SteVe, EVerest, simulators).
v16
Package v16 provides OCPP 1.6 version metadata and profile wiring.
Package v16 provides OCPP 1.6 version metadata and profile wiring.
Package v201 provides OCPP 2.0.1 version metadata and profile wiring.
Package v201 provides OCPP 2.0.1 version metadata and profile wiring.
v21
Package v21 provides OCPP 2.1 version metadata and profile wiring.
Package v21 provides OCPP 2.1 version metadata and profile wiring.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL