ocpp

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: Apache-2.0 Imports: 40 Imported by: 0

README

ocpp

The protocol core of the Open Charge Point Protocol (OCPP 1.6J, OCPP-S 1.6, 2.0.1 and 2.1) in pure Go: RPC, schema validation in both directions, the SOAP binding, signed messages; not affiliated with the Open Charge Alliance.

Go Reference test Go

One Conn speaks OCPP-J on either side of the connection, for every version, including the 2.1 SEND and CALLRESULTERROR message kinds. Every message can be checked, in both directions, against the Open Charge Alliance's own JSON schemas, which this module embeds unmodified and compiles when a version is first used; a failure comes back with the CALLERROR code of that version. Around that: the OCPP-S 1.6 SOAP binding, 2.x signed messages, the checks behind security profiles 1 to 3, the 2.0.1 and 2.1 device model appendices, and helpers for the deviations real chargers send. Since v0.2.0 both roles are library packages too: csms (a central system listener that admits, routes and checks stations) and chargepoint (a charging station connection that reconnects), with Go types for every 2.1 message in v21. It was written for SigmaM2M, a oneM2M platform, whose charging station management system (CSMS) is built on it; the CSMS's business logic (charger state, authorization, tariffs, smart charging) is not part of this module.

Features

Feature Status
OCPP-J for 1.6, 2.0.1 and 2.1: CALL, CALLRESULT, CALLERROR, one outstanding CALL per direction, message IDs, time-outs, ping (Conn, NewConn) yes
2.1 SEND (Conn.Send) and CALLRESULTERROR (Conn.CheckResult, OnResultError) yes
Unknown message types ignored (2.x errata 2026-06); unreadable message IDs answered with -1 (2.x) yes
CALLs carried another way, as OCPP-S does (NewSenderConn) yes
Validation of every 1.6, 2.0.1 and 2.1 request and response against the OCA schemas (ValidateMessage, ValidateJSON, DecodeIn, CheckAnswer); failures as *RPCError with the version's code (1.6's FormationViolation and OccurenceConstraintViolation spellings included) yes
Go types for the 1.6 messages (with the security whitepaper's, which have no OCA schema) and the 2.0.1 messages (V16In, V16Out, V201In, V201Out); 2.1 direction tables (In21, Out21, SendActions21) yes
Go types for every 2.1 request, response and SEND, generated from the embedded OCA schemas: enumerations as named string types with constants, optional properties as pointers, unknown CustomData properties kept (v21, v21.Decode, v21.Call) yes (since v0.2.0)
Central system role: one http.Handler for 1.6, 2.0.1 and 2.1 at <path>/<identity>, an admission hook for security profiles 1 to 3, routing by action (and version), schema checks of every request and of our own answers, NotSupported and NotImplemented for unhandled actions, a registry of stations with typed calls, a newer connection replacing an older one, the profile 3 serial number check, a hook to tolerate deviations (csms.New, Server.Handle, Station.Call, Config.OnInvalid) yes (since v0.2.0)
Charging station role: dial with the identity in the path, offered versions, basic authentication and TLS; routing of the central system's CALLs; schema checks both ways; 2.1 SEND; Run reconnects with the randomised doubling back-off of the 2.x RetryBackOff variables (chargepoint.New, Dial, Client.Run, Backoff) yes (since v0.2.0)
ValidateRequest and ValidateResponse for any version and either direction; ActionOf gives a handler its action yes (since v0.2.0)
ISO 15118 Plug & Charge over 1.6J as the OCA application note (2020) has it: the nine messages as Go types, wrapped in and read from DataTransfer with the note's vendorId (PnC16, PnC16Wrap, PnC16Unwrap, PnC16Answer, PnC16ReadAnswer) yes (since v0.2.0)
OCPP-S 1.6: Central System requests in, Charge Point calls out, faults with OCPP sub-codes, gzip and deflate, elements in the WSDLs' order, envelope check against the WSDLs (ReadSOAPRequest, WriteSOAPResponse, WriteSOAPFault, SOAPCall, CheckSOAPEnvelope) yes
2.x signed messages, ES256, RS256 and RS384 (MsgSigner) yes
Security profiles 1 to 3: the pieces a listener needs (subprotocol, TLS or plain WebSocket, the BootNotification serial number to compare with the client certificate), used by csms yes; the password store and certificate trust are the application's
Subprotocol negotiation that takes variant spellings (Subprotocols, VersionOf, OfferedSubprotocols) yes
Deviations real chargers send: zone-less timestamps (Rezone), vendor properties, lengths and enumeration values (Deviations, DecodeLoose, EchoesOnly); an optional property sent as null is read as absent (since v0.1.0) yes
2.0.1 and 2.1 device model appendices: components, variables, security event criticality (DeviceModelOf) yes
OCPP 1.5 and earlier, OCPP-S 1.5 no
WebSocket compression the application's choice (websocket.AcceptOptions)

Choosing an OCPP library

Compared from each project's source at the version named, on 2026-10-11 (seanlee0923/ocpp on 2026-10-12). Check the projects themselves before relying on a row.

this module lorenzodonini/ocpp-go v0.19.0 seanlee0923/ocpp v0.3.0 mobilityhouse/ocpp 2.1.0 (Python) SteVe 3.14.1 (Java)
What it is protocol library: RPC, central system and charging station roles protocol library: central system and charge point roles protocol library: CSMS server and station client protocol library, both sides a CSMS application with a web UI and a database
OCPP-J 1.6 yes, with the security extension yes, with the security extension yes yes yes, with the security extension
OCPP-S 1.6 (SOAP) yes no (its README rules it out) no no yes, and 1.2 and 1.5
OCPP 2.0.1 yes yes yes yes no
OCPP 2.1 yes, with SEND and CALLRESULTERROR no yes, with SEND (received by its CSMS; its station cannot send one); no CALLRESULTERROR yes, without SEND and CALLRESULTERROR (message types 2 to 4 only) no
Message validation the OCA JSON schemas, embedded unmodified, both directions validator struct tags written from the specification Go validation generated from the OCA schemas JSON schemas shipped with the package, both directions JAXB types
Typed messages 1.6, 2.0.1 and 2.1 (2.1 generated from the schemas) 1.6 and 2.0.1 1.6, 2.0.1 and 2.1, generated 1.6, 2.0.1 and 2.1 dataclasses 1.2 to 1.6
Reconnecting charging station yes, the 2.x back-off variables' rule yes yes, exponential back-off yes n/a
2.x signed messages yes no no no n/a
ISO 15118 Plug & Charge over 1.6 (OCA application note) yes no no no no
Charge point simulator yes, every version, OCPP-S included, separate module example programs example programs no no
Interop evidence against mobilityhouse/ocpp, ocpp-go and seanlee0923/ocpp, both roles (below) none stated in the repository none stated in the repository none stated in the repository its README reports an OCA 1.6 certification of a product built on it
Licence Apache-2.0 (OCA files CC BY-ND 4.0) MIT MIT MIT GPL-3.0

Pick this module when you build a CSMS or a charger in Go and need 2.1 with SEND and CALLRESULTERROR, OCPP-S, Plug & Charge over 1.6, signed messages, or the OCA schemas as the arbiter of what is valid, or a simulator of every version for your tests. Pick ocpp-go when you need typed 1.6 and 2.0.1 on both sides and do not need 2.1; it has the most Go users. seanlee0923/ocpp is the closest Go alternative for 2.1 and has more server operations tooling (metrics hooks, handshake rate limits, graceful shutdown); pick it if those matter more than the rows above. Pick mobilityhouse/ocpp in Python. Pick SteVe when you want a running 1.6 back office rather than a library.

Install

go get github.com/cB-Sigma/ocpp@latest

Requires Go 1.26.0 or later.

Quick start

import "github.com/cB-Sigma/ocpp"

ws, _ := websocket.Accept(w, r, &websocket.AcceptOptions{Subprotocols: ocpp.Subprotocols([]string{ocpp.V21, ocpp.V201, ocpp.V16})})
version := ocpp.VersionOf(ws.Subprotocol())
c := ocpp.NewConn(ws, version, 30*time.Second, func(ctx context.Context, action string, p json.RawMessage) (any, error) {
	if _, verr := ocpp.ValidateJSON(version, action, false, p); verr != nil {
		return nil, verr // a CALLERROR with the version's code
	}
	return ocpp.CheckAnswer(version, action, answerFor(action), p)
})
go c.Serve(ctx, time.Minute)
res, err := c.Call(ctx, "GetVariables", req) // a *CallError when the charger refuses

This mirrors ExampleNewConn in example_test.go, which compiles with the tests but does not run (it needs a listener). ExampleValidateMessage and ExampleDecodeIn run and check their output.

With the role packages (v0.2.0), both sides are a few lines each:

srv := csms.New(csms.Config{Authenticate: checkPassword})
srv.Handle("BootNotification", func(ctx context.Context, st *csms.Station, p json.RawMessage) (any, error) {
	return v21.BootNotificationResponse{CurrentTime: now(), Interval: 300, Status: v21.RegistrationStatusAccepted}, nil
})
http.Handle("/ocpp/", srv)

cp := chargepoint.New(chargepoint.Config{URL: "wss://csms.example/ocpp", ID: "CP1", Password: pw})
cp.Handle("Reset", onReset)
go cp.Run(ctx) // reconnects
res, err := v21.Call[v21.BootNotificationResponse](ctx, cp, v21.BootNotificationRequest{...})

TestRolesEveryVersion (csms/roles_test.go) and TestTypedCall (v21/v21_test.go) run this. ocpp-sim has a charge point of every version to test a central system with.

Documentation

API reference: https://pkg.go.dev/github.com/cB-Sigma/ocpp

Package What it does
ocpp (module root) Conn, NewConn, NewSenderConn, CallError, RPCError, ErrKind, ActionOf; ValidateMessage, ValidateJSON, ValidateRequest, ValidateResponse, Known, DecodeIn, CheckAnswer, HasSchema, LoadSchemas, OCAFiles, SchemaFiles; the 1.6 and 2.0.1 message types and direction tables, the 2.1 direction tables; the OCPP-S 1.6 functions; MsgSigner; Subprotocols, VersionOf, OfferedSubprotocols; Rezone, Deviations, DecodeLoose, EchoesOnly; DeviceModelOf; the 1.6 Plug & Charge functions (PnC16...)
csms the central system role: New, Server (Handle, HandleVersion, Station, Stations), Station (Call, CallInto, Send, Close, Set, Get), Identity
chargepoint the charging station role: New, Client (Connect, Run, Handle, Call, CallInto, Send, WaitConnected), Dial, EndpointURL, Backoff
v21 generated Go types of every 2.1 message (messages.go, by go generate ./v21 from the embedded schemas), Messages, Decode, Call
oca/ (data) the OCA files, unmodified: the 1.6 JSON schemas and OCPP-S WSDLs, the 2.0.1 and 2.1 JSON schemas and appendix CSV files, with each folder's attribution and SHA256SUMS
interop (nested module, tests only) mobilityhouse/ocpp's charge point (in a container), ocpp-go's charge point and central systems and seanlee0923/ocpp's station and CSMS (in process) against the csms and chargepoint packages

Changes per version are in CHANGELOG.md.

Testing

go test -race ./...
cd interop && go test -v ./...                          # ocpp-go and seanlee0923/ocpp, in process
cd interop && SIGMA_OCPP_INTEROP=1 go test -v ./...     # and mobilityhouse/ocpp, needs Docker

TestOCASchemaFilesUnmodified checks every embedded OCA file against its published digest. Tests carry // Covers: SIG-... comments: requirement IDs of the SigmaM2M project's compliance report, with no meaning outside it; the tests added for the first release carry none. Comments that name F-numbers (F-1412, say) refer to entries in that project's register of specification defects; PROVENANCE.md says what each choice is.

TestEveryMessageRoundTrips (v21) builds, for each of the 181 2.1 schemas, a payload with only the required properties and one with every property, and checks that each decodes into the generated type and encodes back to the same JSON, still valid; TestGeneratedUpToDate fails when messages.go no longer matches the schemas.

interop/ is a nested module with its own go.mod, so ocpp-go and seanlee0923/ocpp stay out of this one; seanlee0923/ocpp v0.3.0 asks for Go 1.26.5, so the interop module does too (the module itself stays on 1.26.0). Its mobilityhouse tests build an image from interop/peer (python:3.12.10-slim with ocpp 2.1.0 and websockets 15.0.1 from PyPI) and are skipped unless SIGMA_OCPP_INTEROP=1 is set and Docker answers.

Interop tested against
  • mobilityhouse/ocpp 2.1.0 (2026-10-11, python:3.12.10-slim in Docker Desktop 29.4.3 on arm64; interop): its ChargePoint for 1.6, 2.0.1 and 2.1 against a central system on this module (since v0.2.0 the csms package; 2026-10-11 again on it). Passed for every version: BootNotification, Heartbeat, StatusNotification, Authorize, a transaction (StartTransaction, MeterValues, StopTransaction in 1.6; TransactionEvent Started, Updated, Ended in 2.x), all accepted by our schema check; a StatusNotification with a string where the schema wants an integer, sent past mobilityhouse's own check, answered with TypeConstraintViolation, which mobilityhouse read as such; then RemoteStartTransaction, RemoteStopTransaction, Reset and GetConfiguration (1.6) or RequestStartTransaction, RequestStopTransaction, Reset, SetVariables and GetVariables (2.x) from our side, each answer valid against the OCA schema; a Reset outside the enumeration came back as a CALLERROR, and the connection carried on. mobilityhouse answers that with FormatViolation in 1.6 too, where OCPP-J 1.6 names the code FormationViolation; Conn takes any code.
  • lorenzodonini/ocpp-go v0.19.0 (2026-10-11, in process; interop): its 1.6 ChargePoint and 2.0.1 ChargingStation against the same central system, the same session and commands. Passed. ocpp-go's 2.0.1 Reset answer carries "statusInfo": null, which the 2.0.1 schema refuses; Deviations counted it as a type error until v0.1.0, which reads a null optional property as absent (TestDeviationsNullProperty). ocpp-go answers a Reset outside the enumeration with GenericError. Since v0.2.0 also the other role: this module's chargepoint (1.6 and 2.0.1; offered 2.1 and 2.0.1, ocpp-go chose 2.0.1) against ocpp-go's 1.6 central system and 2.0.1 CSMS: BootNotification, Heartbeat, StatusNotification and Authorize read by ocpp-go's handlers with the values sent, and a Reset from ocpp-go answered and read as Accepted.
  • seanlee0923/ocpp v0.3.0 (2026-10-12, in process; interop), both roles in 2.1: its typed station booted and sent a heartbeat to the csms package, which checked both against the OCA schemas, and answered our Reset; our chargepoint booted against its CSMS, sent a 2.1 SEND (NotifyPeriodicEventStream) that its typed SEND handler decoded, and answered its Reset. Passed. This is the first run of a SEND against another implementation. Its CSMS takes the whole request path as the identity, so the test mounts it under a prefix.
  • The other way round for the simulator (their central systems against it) is in ocpp-sim.
  • SigmaM2M's CSMS, built on this module, against mobilityhouse/ocpp's charge point for all three versions (session, the refused request and commands from the platform), and the OCA part 6 CSMS test cases it runs against the simulator.
  • Not yet: a real charger, the OCA's own test tool, OCPP-S against another implementation (SteVe speaks it; not run yet), CALLRESULTERROR and signed messages against another implementation (none of the peers above has them), Plug & Charge over 1.6 against another implementation (none of them has it).

Not yet

What Why
OCPP 1.5 and OCPP-S 1.5 the 1.5 documents are behind the OCA's download form; no user has asked
OCPP-S 1.6 against SteVe SteVe is free (GPL-3.0) and speaks OCPP-S; the run needs its MySQL and Maven build in Docker and is planned for the next release
A run against real chargers and the OCA test tool needs hardware and OCA membership
  • ocpp-sim: a simulated charge point of every version, as a Go package and a command.
  • jsonschema: the JSON Schema layer this module validates with, including the OCA's dialect.

Status

v0.x: the API may change before v1.

Contributing

See CONTRIBUTING.md.

Security

See SECURITY.md to report a vulnerability privately.

Licence

Apache-2.0 (see LICENSE and NOTICE), except the files in oca/, which are the Open Charge Alliance's, under CC BY-ND 4.0, unmodified. Copyright 2026 Abhinav Gautam. OCPP and Open Charge Alliance are names of the Open Charge Alliance; they are used only to say which protocol this module implements. This module is not made, endorsed, certified or supported by the Open Charge Alliance.

Documentation

Index

Examples

Constants

View Source
const (
	MsgCall            = 2
	MsgCallResult      = 3
	MsgCallError       = 4
	MsgCallResultError = 5 // 2.1: error answer to a CALLRESULT
	MsgSend            = 6 // 2.1: unconfirmed message, never answered
)

OCPP-J message type numbers (OCPP-J 1.6 clause 4.1.3; OCPP 2.0.1 part 4 clause 4.1.3; OCPP 2.1 part 4 clause 4.1.3 adds CALLRESULTERROR and SEND).

View Source
const (
	V16  = "ocpp1.6"
	V201 = "ocpp2.0.1"
	V21  = "ocpp2.1"
)

Subprotocol names negotiated in Sec-WebSocket-Protocol.

View Source
const PnC16VendorID = "org.openchargealliance.iso15118pnc"

PnC16VendorID is the DataTransfer vendorId of the application note.

View Source
const SignedSuffix = "-Signed"

SignedSuffix is appended to the action of a signed message.

View Source
const WSAAnonymous = "http://www.w3.org/2005/08/addressing/anonymous"

WSAAnonymous is the WS-Addressing anonymous address.

Variables

View Source
var (
	V16In   = v16In
	V16Out  = v16Out
	V201In  = v201In
	V201Out = v201Out
)

V16In, V16Out, V201In and V201Out are the actions of each version we have Go types for, by who sends them: In a charging station, Out the CSMS. The 1.6 tables include the 1.6 security extension messages.

View Source
var (
	In21          = in21
	Out21         = out21
	SendActions21 = sendActions21
)

In21, Out21 and SendActions21 are the OCPP 2.1 actions by direction: CALLs a charging station sends, CALLs the CSMS sends, and SEND messages (unconfirmed, from a charging station).

View Source
var ErrClosed = errors.New("the connection is closed")

ErrClosed is returned by Call on a closed connection.

View Source
var ErrTimeout = errors.New("no answer from the peer in time")

ErrTimeout is returned by Call when no answer arrived in time.

View Source
var PnC16 = map[string]PnC16Def{
	"Authorize":                  {Def[PnCAuthorize16, PnCAuthorize16Conf](), true},
	"CertificateSigned":          {Def[PnCCertificateSigned16, PnCStatusConf16](), false},
	"DeleteCertificate":          {Def[PnCDeleteCertificate16, PnCStatusConf16](), false},
	"Get15118EVCertificate":      {Def[PnCGet15118EVCertificate16, PnCGet15118EVCertificate16Conf](), true},
	"GetCertificateStatus":       {Def[PnCGetCertificateStatus16, PnCGetCertificateStatus16Conf](), true},
	"GetInstalledCertificateIds": {Def[PnCGetInstalledCertificateIDs16, PnCGetInstalledCertificateIDs16Conf](), false},
	"InstallCertificate":         {Def[PnCInstallCertificate16, PnCStatusConf16](), false},
	"SignCertificate":            {Def[PnCSignCertificate16, PnCStatusConf16](), true},
	"TriggerMessage":             {Def[Empty, PnCStatusConf16](), false},
}

PnC16 are the application note's messages by name: their request and confirmation types, and whether the charge point sends them (FromCP).

Functions

func ActionOf added in v0.2.0

func ActionOf(ctx context.Context) string

ActionOf is the action of the CALL or SEND a handler runs for.

func BaseAction

func BaseAction(a string) (string, bool)

BaseAction is the action of a possibly signed message without the suffix, and whether it had it.

func BasicAuthPassword

func BasicAuthPassword(r *http.Request, id string) (pass string, ok bool)

BasicAuthPassword is the password of a profile 1 or 2 request from charging station id: ok is false when the request has no basic authentication or its user name is not id.

func CheckAnswer

func CheckAnswer(version, action string, res any, request ...json.RawMessage) (any, error)

CheckAnswer validates our own answer to a 2.x CALL against its response schema: a failure is our defect, answered with an InternalError rather than an invalid CALLRESULT.

An answer that echoes a value the charger sent outside an enumeration (a newer or vendor value the application tolerated) is sent as it is: the charger knows its own value. request is the charger's payload.

func CheckIdentity

func CheckIdentity(id string) error

CheckIdentity accepts a charging station identity: 1 to 48 characters, none of them '/', ':' (a basic authentication user name cannot hold it) or a control or space character.

func CheckSOAPEnvelope

func CheckSOAPEnvelope(raw []byte) error

CheckSOAPEnvelope checks the one element in a SOAP envelope's Body against the embedded OCPP-S 1.6 WSDL of its namespace, as a schema-validating SOAP stack would: the element is declared, its children are in the WSDL's sequence order and namespace, required elements are there and none repeats more than allowed, and values have their simple type (enumeration, length, int, decimal digits, dateTime, boolean, URI). A SOAP Fault passes. SigmaM2M's CSMS does not call it (it reads any order); the simulator does unless it is lenient.

func ClientCertNames

func ClientCertNames(st *tls.ConnectionState, id string) bool

ClientCertNames reports whether the TLS client certificate of a profile 3 connection names charging station id as its common name.

func Deviations

func Deviations(version, action string, response bool, raw json.RawMessage, verr *RPCError) (ok, enum, other bool)

Deviations sorts the validation failures of a charger's message (verr, from DecodeIn or ValidateJSON): ok when every one is tolerable, enum when one is a value outside an enumeration, other when one is a property the schema does not define or a text of the wrong length.

func EchoesOnly

func EchoesOnly(version, action string, b, request json.RawMessage) bool

EchoesOnly reports whether every schema failure of our answer b is a value outside an enumeration that the charger's request carries.

func HasSchema

func HasSchema(version, action string) bool

HasSchema reports whether the OCA publishes a schema for the request of action in version.

func Is2

func Is2(version string) bool

Is2 reports whether version is OCPP 2.0.1 or 2.1 (the 2.x message family and error code names).

func IsJWS

func IsJWS(p json.RawMessage) bool

IsJWS reports whether a payload is a flattened JWS.

func IsSend

func IsSend(ctx context.Context) bool

IsSend reports whether a handler runs for a SEND message, whose result is never sent.

func Known added in v0.2.0

func Known(version, action string) bool

Known reports whether version has a schema or a Go type for action, sent by either side.

func LoadSchemas

func LoadSchemas() error

LoadSchemas reads and compiles the schemas of every version now rather than on first use, and reports a problem with them.

func MessageID

func MessageID(ctx context.Context) string

MessageID is the ID of the CALL a handler runs for.

func NewMessageID

func NewMessageID() string

NewMessageID is a random UUID (version 4) message ID.

func OCAFiles

func OCAFiles() fs.FS

OCAFiles is the embedded OCA files, rooted at the version folders ("1.6", "2.0.1", "2.1").

func OfferedSubprotocols

func OfferedSubprotocols(r *http.Request) []string

OfferedSubprotocols are the subprotocols a WebSocket upgrade request offers.

func PasswordOK

func PasswordOK(want, got string) bool

PasswordOK compares a basic authentication password with the stored one in constant time: want is the password itself or "sha256:" and the hex SHA-256 of it.

func ReadSOAPRequest

func ReadSOAPRequest(r *http.Request) (*SOAPRequest, *SOAPFault)

ReadSOAPRequest reads a SOAP 1.2 envelope from a POSTed request (gzip and deflate bodies too).

func Rezone

func Rezone(version, action string, response bool, raw json.RawMessage, loc *time.Location) (json.RawMessage, []string)

Rezone rewrites the zone-less date-times of a message from a charger (a request when response is false, else the answer to a CALL), reading them in loc, as RFC 3339 UTC date-times. Only properties the OCA schema (or, for the 1.6 security extension messages that have no schema, our Go type) declares a date-time are rewritten. It returns the payload and the values it rewrote; the payload is returned unchanged when it holds none or is not JSON.

func SOAPCall

func SOAPCall(ctx context.Context, client *http.Client, identity, own, to, action string, payload json.RawMessage) (json.RawMessage, error)

SOAPCall POSTs one Charge Point service request for charger identity to the address to, with own (our Central System service URL, "" for anonymous) in From, and returns the answer as the OCPP-J 1.6 payload. A SOAP Fault is returned as a *CallError, an HTTP failure as an *UnreachableError.

func SOAPCallCentralSystem

func SOAPCallCentralSystem(ctx context.Context, client *http.Client, identity, own, to, action string, payload json.RawMessage) (json.RawMessage, error)

SOAPCallCentralSystem POSTs one Central System service request, as charge point identity, to the Central System at to, with own (where the charge point takes calls, "" for anonymous) in From, as a charge point does (the simulator). Answers and errors are as for SOAPCall.

func SOAPFaultOf

func SOAPFaultOf(e *RPCError) (string, string)

SOAPFaultOf is the fault code ("Sender" or "Receiver") and OCPP sub-code of an RPC error.

func SchemaFile

func SchemaFile(version, action string, response bool) []byte

SchemaFile is the OCA schema file of action's request or response in version, as published, or nil when there is none.

func SchemaFiles

func SchemaFiles(dir string) (map[string][]byte, error)

SchemaFiles reads the schema files of an oca/ folder ("1.6", "2.0.1" or "2.1"), by file name without .json, as published.

func SerialMismatch

func SerialMismatch(serial, cn string) bool

SerialMismatch reports whether a 2.x BootNotification's serial number differs from the common name of the profile 3 client certificate (both known), in which case the connection is to be closed.

func Subprotocols

func Subprotocols(versions []string) []string

Subprotocols are the names a listener for versions accepts: the versions first, then their variant spellings.

func ValidateMessage

func ValidateMessage(version, action string, response bool, raw json.RawMessage) error

ValidateMessage checks a 2.0.1 or 2.1 payload against the OCA schema of action's request (or response): nil when it is valid. For the simulator and tests.

Example

A payload is checked against the OCA schema of its version; a failure carries the CALLERROR code of that version.

package main

import (
	"encoding/json"
	"fmt"

	"github.com/cB-Sigma/ocpp"
)

func main() {
	err := ocpp.ValidateMessage(ocpp.V21, "Heartbeat", false, json.RawMessage(`{"extra":1}`))
	fmt.Println(err.(*ocpp.SchemaError).Code)
	fmt.Println(ocpp.ValidateMessage(ocpp.V16, "BootNotification", false, json.RawMessage(`{"chargePointVendor":"v","chargePointModel":"m"}`)))
}
Output:
FormatViolation
<nil>

func VersionOf

func VersionOf(name string) string

VersionOf is the version a subprotocol name stands for, or "".

func WithMessageID

func WithMessageID(ctx context.Context, id string) context.Context

WithMessageID makes Call use id (a Local Controller relaying a message).

func WriteChargePointSOAPResponse

func WriteChargePointSOAPResponse(w http.ResponseWriter, msgID, action string, res any)

WriteChargePointSOAPResponse answers a Charge Point service request (MessageID msgID) to action with res, as a charge point does (the simulator).

func WriteSOAPFault

func WriteSOAPFault(w http.ResponseWriter, relatesTo, sender, sub, reason string)

WriteSOAPFault answers a SOAP Fault with an OCPP sub-code.

func WriteSOAPResponse

func WriteSOAPResponse(w http.ResponseWriter, msgID, action string, res any)

WriteSOAPResponse answers a Central System service request (MessageID msgID) to action with res, the OCPP-J 1.6 answer, as <action>Response.

Types

type AdditionalInfo

type AdditionalInfo struct {
	AdditionalIDToken string `json:"additionalIdToken" ocpp:"req,max=36"`
	Type              string `json:"type" ocpp:"req,max=50"`
}

type AuthorizationData16

type AuthorizationData16 struct {
	IDTag     string       `json:"idTag" ocpp:"req,max=20"`
	IDTagInfo *IDTagInfo16 `json:"idTagInfo,omitempty"`
}

type AuthorizationData201

type AuthorizationData201 struct {
	IDToken     IDToken      `json:"idToken" ocpp:"req"`
	IDTokenInfo *IDTokenInfo `json:"idTokenInfo,omitempty"`
}

type Authorize16

type Authorize16 struct {
	IDTag string `json:"idTag" ocpp:"req,max=20"`
}

type Authorize16Conf

type Authorize16Conf struct {
	IDTagInfo IDTagInfo16 `json:"idTagInfo" ocpp:"req"`
}

type Authorize201

type Authorize201 struct {
	IDToken                     IDToken           `json:"idToken" ocpp:"req"`
	Certificate                 string            `json:"certificate,omitempty" ocpp:"max=5500"`
	ISO15118CertificateHashData []OCSPRequestData `json:"iso15118CertificateHashData,omitempty" ocpp:"minItems=1,maxItems=4"`
}

type Authorize201Conf

type Authorize201Conf struct {
	IDTokenInfo       IDTokenInfo `json:"idTokenInfo" ocpp:"req"`
	CertificateStatus string      `` /* 164-byte string literal not displayed */
}

type BootNotification16

type BootNotification16 struct {
	ChargePointVendor       string `json:"chargePointVendor" ocpp:"req,max=20"`
	ChargePointModel        string `json:"chargePointModel" ocpp:"req,max=20"`
	ChargePointSerialNumber string `json:"chargePointSerialNumber,omitempty" ocpp:"max=25"`
	ChargeBoxSerialNumber   string `json:"chargeBoxSerialNumber,omitempty" ocpp:"max=25"`
	FirmwareVersion         string `json:"firmwareVersion,omitempty" ocpp:"max=50"`
	ICCID                   string `json:"iccid,omitempty" ocpp:"max=20"`
	IMSI                    string `json:"imsi,omitempty" ocpp:"max=20"`
	MeterType               string `json:"meterType,omitempty" ocpp:"max=25"`
	MeterSerialNumber       string `json:"meterSerialNumber,omitempty" ocpp:"max=25"`
}

type BootNotification16Conf

type BootNotification16Conf struct {
	Status      string `json:"status" ocpp:"req,enum=Accepted|Pending|Rejected"`
	CurrentTime string `json:"currentTime" ocpp:"req,dt"`
	Interval    int    `json:"interval" ocpp:"req"`
}

type BootNotification201

type BootNotification201 struct {
	ChargingStation ChargingStation `json:"chargingStation" ocpp:"req"`
	Reason          string          `` /* 134-byte string literal not displayed */
}

type BootNotification201Conf

type BootNotification201Conf struct {
	CurrentTime string      `json:"currentTime" ocpp:"req,dt"`
	Interval    int         `json:"interval" ocpp:"req"`
	Status      string      `json:"status" ocpp:"req,enum=Accepted|Pending|Rejected"`
	StatusInfo  *StatusInfo `json:"statusInfo,omitempty"`
}

type CallError

type CallError struct {
	Code        string
	Description string
	Details     any
}

CallError is a CALLERROR received from the peer.

func (*CallError) Error

func (e *CallError) Error() string

type CancelReservation16

type CancelReservation16 struct {
	ReservationID int `json:"reservationId" ocpp:"req"`
}

type CancelReservation201

type CancelReservation201 struct {
	ReservationID int `json:"reservationId" ocpp:"req"`
}

type CertificateHashData

type CertificateHashData struct {
	HashAlgorithm  string `json:"hashAlgorithm" ocpp:"req,enum=SHA256|SHA384|SHA512"`
	IssuerNameHash string `json:"issuerNameHash" ocpp:"req,max=128"`
	IssuerKeyHash  string `json:"issuerKeyHash" ocpp:"req,max=128"`
	SerialNumber   string `json:"serialNumber" ocpp:"req,max=40"`
}

type CertificateHashDataChain

type CertificateHashDataChain struct {
	CertificateType          string                `` /* 143-byte string literal not displayed */
	CertificateHashData      CertificateHashData   `json:"certificateHashData" ocpp:"req"`
	ChildCertificateHashData []CertificateHashData `json:"childCertificateHashData,omitempty" ocpp:"minItems=1,maxItems=4"`
}

type CertificateSigned16

type CertificateSigned16 struct {
	CertificateChain string `json:"certificateChain" ocpp:"req,max=10000"`
}

type CertificateSigned201

type CertificateSigned201 struct {
	CertificateChain string `json:"certificateChain" ocpp:"req,max=10000"`
	CertificateType  string `json:"certificateType,omitempty" ocpp:"enum=ChargingStationCertificate|V2GCertificate"`
}

type CertificateSigned201Conf

type CertificateSigned201Conf struct {
	Status     string      `json:"status" ocpp:"req,enum=Accepted|Rejected"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
}

type ChangeAvailability16

type ChangeAvailability16 struct {
	ConnectorID int    `json:"connectorId" ocpp:"req,min=0"`
	Type        string `json:"type" ocpp:"req,enum=Inoperative|Operative"`
}

type ChangeAvailability201

type ChangeAvailability201 struct {
	EVSE              *EVSE  `json:"evse,omitempty"`
	OperationalStatus string `json:"operationalStatus" ocpp:"req,enum=Inoperative|Operative"`
}

type ChangeConfiguration16

type ChangeConfiguration16 struct {
	Key   string `json:"key" ocpp:"req,max=50"`
	Value string `json:"value" ocpp:"req,max=500"`
}

type ChargingProfile16

type ChargingProfile16 struct {
	ChargingProfileID      int                `json:"chargingProfileId" ocpp:"req"`
	TransactionID          *int               `json:"transactionId,omitempty"`
	StackLevel             int                `json:"stackLevel" ocpp:"req,min=0"`
	ChargingProfilePurpose string             `json:"chargingProfilePurpose" ocpp:"req,enum=ChargePointMaxProfile|TxDefaultProfile|TxProfile"`
	ChargingProfileKind    string             `json:"chargingProfileKind" ocpp:"req,enum=Absolute|Recurring|Relative"`
	RecurrencyKind         string             `json:"recurrencyKind,omitempty" ocpp:"enum=Daily|Weekly"`
	ValidFrom              string             `json:"validFrom,omitempty" ocpp:"dt"`
	ValidTo                string             `json:"validTo,omitempty" ocpp:"dt"`
	ChargingSchedule       ChargingSchedule16 `json:"chargingSchedule" ocpp:"req"`
}

type ChargingProfile201

type ChargingProfile201 struct {
	ID                     int                   `json:"id" ocpp:"req"`
	StackLevel             int                   `json:"stackLevel" ocpp:"req,min=0"`
	ChargingProfilePurpose string                `` /* 133-byte string literal not displayed */
	ChargingProfileKind    string                `json:"chargingProfileKind" ocpp:"req,enum=Absolute|Recurring|Relative"`
	RecurrencyKind         string                `json:"recurrencyKind,omitempty" ocpp:"enum=Daily|Weekly"`
	ValidFrom              string                `json:"validFrom,omitempty" ocpp:"dt"`
	ValidTo                string                `json:"validTo,omitempty" ocpp:"dt"`
	TransactionID          string                `json:"transactionId,omitempty" ocpp:"max=36"`
	ChargingSchedule       []ChargingSchedule201 `json:"chargingSchedule" ocpp:"req,minItems=1,maxItems=3"`
}

type ChargingProfileCriterion

type ChargingProfileCriterion struct {
	ChargingProfilePurpose string   `` /* 139-byte string literal not displayed */
	StackLevel             *int     `json:"stackLevel,omitempty"`
	ChargingProfileID      []int    `json:"chargingProfileId,omitempty" ocpp:"minItems=1"`
	ChargingLimitSource    []string `json:"chargingLimitSource,omitempty" ocpp:"minItems=1,maxItems=4,enum=EMS|Other|SO|CSO"`
}

type ChargingSchedule16

type ChargingSchedule16 struct {
	Duration               *int                       `json:"duration,omitempty"`
	StartSchedule          string                     `json:"startSchedule,omitempty" ocpp:"dt"`
	ChargingRateUnit       string                     `json:"chargingRateUnit" ocpp:"req,enum=A|W"`
	ChargingSchedulePeriod []ChargingSchedulePeriod16 `json:"chargingSchedulePeriod" ocpp:"req,minItems=1"`
	MinChargingRate        *float64                   `json:"minChargingRate,omitempty"`
}

type ChargingSchedule201

type ChargingSchedule201 struct {
	ID                     int                         `json:"id" ocpp:"req"`
	StartSchedule          string                      `json:"startSchedule,omitempty" ocpp:"dt"`
	Duration               *int                        `json:"duration,omitempty"`
	ChargingRateUnit       string                      `json:"chargingRateUnit" ocpp:"req,enum=W|A"`
	ChargingSchedulePeriod []ChargingSchedulePeriod201 `json:"chargingSchedulePeriod" ocpp:"req,minItems=1,maxItems=1024"`
	MinChargingRate        *float64                    `json:"minChargingRate,omitempty"`
	SalesTariff            json.RawMessage             `json:"salesTariff,omitempty"`
}

type ChargingSchedulePeriod16

type ChargingSchedulePeriod16 struct {
	StartPeriod  int     `json:"startPeriod" ocpp:"req"`
	Limit        float64 `json:"limit" ocpp:"req"`
	NumberPhases *int    `json:"numberPhases,omitempty"`
}

type ChargingSchedulePeriod201

type ChargingSchedulePeriod201 struct {
	StartPeriod  int     `json:"startPeriod" ocpp:"req"`
	Limit        float64 `json:"limit" ocpp:"req"`
	NumberPhases *int    `json:"numberPhases,omitempty"`
	PhaseToUse   *int    `json:"phaseToUse,omitempty"`
}

type ChargingStation

type ChargingStation struct {
	SerialNumber    string `json:"serialNumber,omitempty" ocpp:"max=25"`
	Model           string `json:"model" ocpp:"req,max=20"`
	Modem           *Modem `json:"modem,omitempty"`
	VendorName      string `json:"vendorName" ocpp:"req,max=50"`
	FirmwareVersion string `json:"firmwareVersion,omitempty" ocpp:"max=50"`
}

type ClearChargingProfile16

type ClearChargingProfile16 struct {
	ID                     *int   `json:"id,omitempty"`
	ConnectorID            *int   `json:"connectorId,omitempty"`
	ChargingProfilePurpose string `json:"chargingProfilePurpose,omitempty" ocpp:"enum=ChargePointMaxProfile|TxDefaultProfile|TxProfile"`
	StackLevel             *int   `json:"stackLevel,omitempty"`
}

type ClearChargingProfile201

type ClearChargingProfile201 struct {
	ChargingProfileID       *int                          `json:"chargingProfileId,omitempty"`
	ChargingProfileCriteria *ClearChargingProfileCriteria `json:"chargingProfileCriteria,omitempty"`
}

type ClearChargingProfileCriteria

type ClearChargingProfileCriteria struct {
	EVSEID                 *int   `json:"evseId,omitempty"`
	ChargingProfilePurpose string `` /* 139-byte string literal not displayed */
	StackLevel             *int   `json:"stackLevel,omitempty"`
}

type ClearMonitoringResult

type ClearMonitoringResult struct {
	Status     string      `json:"status" ocpp:"req,enum=Accepted|Rejected|NotFound"`
	ID         int         `json:"id" ocpp:"req"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
}

type ClearVariableMonitoring201

type ClearVariableMonitoring201 struct {
	ID []int `json:"id" ocpp:"req,minItems=1"`
}

type ClearVariableMonitoring201Conf

type ClearVariableMonitoring201Conf struct {
	ClearMonitoringResult []ClearMonitoringResult `json:"clearMonitoringResult" ocpp:"req,minItems=1"`
}

type Component

type Component struct {
	Name     string `json:"name" ocpp:"req,max=50"`
	Instance string `json:"instance,omitempty" ocpp:"max=50"`
	EVSE     *EVSE  `json:"evse,omitempty"`
}

type ComponentVariable

type ComponentVariable struct {
	Component Component `json:"component" ocpp:"req"`
	Variable  *Variable `json:"variable,omitempty"`
}

type CompositeSchedule201

type CompositeSchedule201 struct {
	ChargingSchedulePeriod []ChargingSchedulePeriod201 `json:"chargingSchedulePeriod" ocpp:"req,minItems=1"`
	EVSEID                 int                         `json:"evseId" ocpp:"req"`
	Duration               int                         `json:"duration" ocpp:"req"`
	ScheduleStart          string                      `json:"scheduleStart" ocpp:"req,dt"`
	ChargingRateUnit       string                      `json:"chargingRateUnit" ocpp:"req,enum=W|A"`
}

type Conn

type Conn struct {

	// CheckResult, when set on a 2.1 connection, validates a CALLRESULT
	// to one of our CALLs; a failure is answered with a CALLRESULTERROR
	// (part 4 clause 4.2.3) and returned by Call as a *ResultError.
	CheckResult func(action string, payload json.RawMessage) error
	// OnResultError is told about a CALLRESULTERROR the peer sent about one
	// of our CALLRESULTs.
	OnResultError func(id, code, desc string)
	// contains filtered or unexported fields
}

Conn is one OCPP-J connection, either side. At most one CALL is outstanding in each direction: Call waits for the previous one to end, and received CALLs are handled one after the other.

func NewConn

func NewConn(ws *websocket.Conn, version string, timeout time.Duration, h Handler) *Conn

NewConn wraps an accepted or dialled WebSocket. Serve must run for calls to be answered.

Example

A central system accepts a charger's WebSocket in any version, answers its CALLs from a handler, and checks its own answers before they go out.

package main

import (
	"context"
	"encoding/json"
	"net/http"
	"time"

	"github.com/coder/websocket"

	"github.com/cB-Sigma/ocpp"
)

func main() {
	http.HandleFunc("/ocpp/", func(w http.ResponseWriter, r *http.Request) {
		ws, err := websocket.Accept(w, r, &websocket.AcceptOptions{Subprotocols: ocpp.Subprotocols([]string{ocpp.V21, ocpp.V201, ocpp.V16})})
		if err != nil {
			return
		}
		version := ocpp.VersionOf(ws.Subprotocol())
		c := ocpp.NewConn(ws, version, 30*time.Second, func(ctx context.Context, action string, payload json.RawMessage) (any, error) {
			if _, verr := ocpp.ValidateJSON(version, action, false, payload); verr != nil {
				return nil, verr // answered with the version's CALLERROR code
			}
			switch action {
			case "BootNotification":
				res := map[string]any{"status": "Accepted", "currentTime": time.Now().UTC().Format(time.RFC3339), "interval": 300}
				return ocpp.CheckAnswer(version, action, res, payload)
			}
			return nil, ocpp.RPCErrorf(ocpp.KindNotImplemented, "%s is not handled", action)
		})
		_ = c.Serve(r.Context(), time.Minute)
	})
}

func NewSenderConn

func NewSenderConn(version string, timeout time.Duration, send func(ctx context.Context, action string, payload json.RawMessage) (json.RawMessage, error)) *Conn

NewSenderConn is a connection whose CALLs are carried by send instead of a WebSocket (OCPP-S: each CALL is an HTTP request to the charger).

func (*Conn) Call

func (c *Conn) Call(ctx context.Context, action string, req any) (json.RawMessage, error)

Call sends a CALL and waits for its CALLRESULT (returned) or CALLERROR (a *CallError). Only one CALL is outstanding at a time; a second caller waits its turn within ctx.

func (*Conn) Close

func (c *Conn) Close(reason string)

Close ends the connection with a normal closure.

func (*Conn) Done

func (c *Conn) Done() <-chan struct{}

Done is closed when the connection ended.

func (*Conn) Err

func (c *Conn) Err() error

Err is why the connection ended.

func (*Conn) IsSender

func (c *Conn) IsSender() bool

IsSender reports whether c was made by NewSenderConn.

func (*Conn) Send

func (c *Conn) Send(ctx context.Context, action string, payload any) error

Send sends a SEND message (OCPP 2.1 part 4 clause 4.2.4): not answered, and not bound to the one-outstanding-CALL rule.

func (*Conn) Serve

func (c *Conn) Serve(ctx context.Context, ping time.Duration) error

Serve reads messages until the connection ends; received CALLs are handled in order on a second goroutine.

func (*Conn) SetHandler

func (c *Conn) SetHandler(h Handler)

SetHandler sets the handler of received CALLs; call it before Serve.

func (*Conn) Version

func (c *Conn) Version() string

Version is the negotiated OCPP version.

func (*Conn) WriteRaw

func (c *Conn) WriteRaw(ctx context.Context, b []byte) error

WriteRaw writes a frame as is (tests of the RPC framework).

type DMVar

type DMVar struct {
	Component, Variable, Instance, Required, DataType, Unit string
}

DMVar is one row of a device model appendix (dm_components_vars.csv): the component ("<generic>" for a variable any component may have), the variable, its instance, the Required? column as written, the data type and the unit.

type DataTransfer16

type DataTransfer16 struct {
	VendorID  string `json:"vendorId" ocpp:"req,max=255"`
	MessageID string `json:"messageId,omitempty" ocpp:"max=50"`
	Data      string `json:"data,omitempty"`
}

func PnC16Wrap added in v0.2.0

func PnC16Wrap(name string, payload any) (DataTransfer16, error)

PnC16Wrap makes the DataTransfer request carrying application note message name with payload, checked first.

type DataTransfer16Conf

type DataTransfer16Conf struct {
	Status string `json:"status" ocpp:"req,enum=Accepted|Rejected|UnknownMessageId|UnknownVendorId"`
	Data   string `json:"data,omitempty"`
}

func PnC16Answer added in v0.2.0

func PnC16Answer(name string, answer any) (DataTransfer16Conf, error)

PnC16Answer makes the DataTransfer confirmation carrying the answer to message name, checked first.

type DataTransfer201

type DataTransfer201 struct {
	MessageID string          `json:"messageId,omitempty" ocpp:"max=50"`
	Data      json.RawMessage `json:"data,omitempty"`
	VendorID  string          `json:"vendorId" ocpp:"req,max=255"`
}

type DataTransfer201Conf

type DataTransfer201Conf struct {
	Status     string          `json:"status" ocpp:"req,enum=Accepted|Rejected|UnknownMessageId|UnknownVendorId"`
	StatusInfo *StatusInfo     `json:"statusInfo,omitempty"`
	Data       json.RawMessage `json:"data,omitempty"`
}

type DeleteCertificate16Conf

type DeleteCertificate16Conf struct {
	Status string `json:"status" ocpp:"req,enum=Accepted|Failed|NotFound"`
}

type DeleteCertificate201

type DeleteCertificate201 struct {
	CertificateHashData CertificateHashData `json:"certificateHashData" ocpp:"req"`
}

type DeleteCertificate201Conf

type DeleteCertificate201Conf struct {
	Status     string      `json:"status" ocpp:"req,enum=Accepted|Failed|NotFound"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
}

type DeviceModel

type DeviceModel struct {
	Vars           []DMVar
	Components     []string
	SecurityEvents map[string]bool // event name -> the Critical column says yes
}

DeviceModel is what a version's part 2 appendices say about the device model: its components and variables, the standardized component names, and the security events with their criticality. Descriptions are not read.

func DeviceModelOf

func DeviceModelOf(version string) (*DeviceModel, error)

DeviceModelOf parses the device model appendix of version (V201 or V21) from the embedded CSV files, once.

func MustDeviceModel

func MustDeviceModel(version string) *DeviceModel

MustDeviceModel is DeviceModelOf for the embedded files, which are known to parse (TestDeviceModelAppendices); it panics otherwise.

type DiagnosticsStatusNotification16

type DiagnosticsStatusNotification16 struct {
	Status string `json:"status" ocpp:"req,enum=Idle|Uploaded|UploadFailed|Uploading"`
}

type EVSE

type EVSE struct {
	ID          int  `json:"id" ocpp:"req,min=0"`
	ConnectorID *int `json:"connectorId,omitempty"`
}

type Empty

type Empty struct{}

type ErrKind

type ErrKind int

ErrKind is a version-neutral RPC error; Code gives the version's name.

const (
	KindFormat ErrKind = iota
	KindProperty
	KindOccurrence
	KindType
	KindNotImplemented
	KindNotSupported
	KindInternal
	KindProtocol
	KindSecurity
	KindGeneric
	KindRPCFramework
	KindMessageType
)

func (ErrKind) Code

func (k ErrKind) Code(version string) string

Code is the CALLERROR code of k in version.

type EventData

type EventData struct {
	EventID               int       `json:"eventId" ocpp:"req"`
	Timestamp             string    `json:"timestamp" ocpp:"req,dt"`
	Trigger               string    `json:"trigger" ocpp:"req,enum=Alerting|Delta|Periodic"`
	Cause                 *int      `json:"cause,omitempty"`
	ActualValue           string    `json:"actualValue" ocpp:"req,max=2500"`
	TechCode              string    `json:"techCode,omitempty" ocpp:"max=50"`
	TechInfo              string    `json:"techInfo,omitempty" ocpp:"max=500"`
	Cleared               *bool     `json:"cleared,omitempty"`
	TransactionID         string    `json:"transactionId,omitempty" ocpp:"max=36"`
	Component             Component `json:"component" ocpp:"req"`
	VariableMonitoringID  *int      `json:"variableMonitoringId,omitempty"`
	EventNotificationType string    `json:"eventNotificationType" ocpp:"req,enum=HardWiredNotification|HardWiredMonitor|PreconfiguredMonitor|CustomMonitor"`
	Variable              Variable  `json:"variable" ocpp:"req"`
}

type ExtendedTriggerMessage16

type ExtendedTriggerMessage16 struct {
	RequestedMessage string `` /* 173-byte string literal not displayed */
	ConnectorID      *int   `json:"connectorId,omitempty" ocpp:"min=0"`
}

type ExtendedTriggerMessage16Conf

type ExtendedTriggerMessage16Conf struct {
	Status string `json:"status" ocpp:"req,enum=Accepted|Rejected|NotImplemented"`
}

type Firmware

type Firmware struct {
	Location           string `json:"location" ocpp:"req,max=512"`
	RetrieveDateTime   string `json:"retrieveDateTime" ocpp:"req,dt"`
	InstallDateTime    string `json:"installDateTime,omitempty" ocpp:"dt"`
	SigningCertificate string `json:"signingCertificate,omitempty" ocpp:"max=5500"`
	Signature          string `json:"signature,omitempty" ocpp:"max=800"`
}

type FirmwareStatusNotification16

type FirmwareStatusNotification16 struct {
	Status string `json:"status" ocpp:"req,enum=Downloaded|DownloadFailed|Downloading|Idle|InstallationFailed|Installing|Installed"`
}

type FirmwareStatusNotification201

type FirmwareStatusNotification201 struct {
	Status    string `` /* 240-byte string literal not displayed */
	RequestID *int   `json:"requestId,omitempty"`
}

type Get15118EVCertificate201

type Get15118EVCertificate201 struct {
	ISO15118SchemaVersion string `json:"iso15118SchemaVersion" ocpp:"req,max=50"`
	Action                string `json:"action" ocpp:"req,enum=Install|Update"`
	EXIRequest            string `json:"exiRequest" ocpp:"req,max=5600"`
}

type Get15118EVCertificate201Conf

type Get15118EVCertificate201Conf struct {
	Status      string      `json:"status" ocpp:"req,enum=Accepted|Failed"`
	StatusInfo  *StatusInfo `json:"statusInfo,omitempty"`
	EXIResponse string      `json:"exiResponse" ocpp:"req,max=5600"`
}

type GetBaseReport201

type GetBaseReport201 struct {
	RequestID  int    `json:"requestId" ocpp:"req"`
	ReportBase string `json:"reportBase" ocpp:"req,enum=ConfigurationInventory|FullInventory|SummaryInventory"`
}

type GetCertificateStatus201

type GetCertificateStatus201 struct {
	OCSPRequestData OCSPRequestData `json:"ocspRequestData" ocpp:"req"`
}

type GetCertificateStatus201Conf

type GetCertificateStatus201Conf struct {
	Status     string      `json:"status" ocpp:"req,enum=Accepted|Failed"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
	OCSPResult string      `json:"ocspResult,omitempty" ocpp:"max=5500"`
}

type GetChargingProfiles201

type GetChargingProfiles201 struct {
	RequestID       int                      `json:"requestId" ocpp:"req"`
	EVSEID          *int                     `json:"evseId,omitempty"`
	ChargingProfile ChargingProfileCriterion `json:"chargingProfile" ocpp:"req"`
}

type GetChargingProfiles201Conf

type GetChargingProfiles201Conf struct {
	Status     string      `json:"status" ocpp:"req,enum=Accepted|NoProfiles"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
}

type GetCompositeSchedule16

type GetCompositeSchedule16 struct {
	ConnectorID      int    `json:"connectorId" ocpp:"req,min=0"`
	Duration         int    `json:"duration" ocpp:"req,min=0"`
	ChargingRateUnit string `json:"chargingRateUnit,omitempty" ocpp:"enum=A|W"`
}

type GetCompositeSchedule16Conf

type GetCompositeSchedule16Conf struct {
	Status           string              `json:"status" ocpp:"req,enum=Accepted|Rejected"`
	ConnectorID      *int                `json:"connectorId,omitempty"`
	ScheduleStart    string              `json:"scheduleStart,omitempty" ocpp:"dt"`
	ChargingSchedule *ChargingSchedule16 `json:"chargingSchedule,omitempty"`
}

type GetCompositeSchedule201

type GetCompositeSchedule201 struct {
	Duration         int    `json:"duration" ocpp:"req"`
	ChargingRateUnit string `json:"chargingRateUnit,omitempty" ocpp:"enum=W|A"`
	EVSEID           int    `json:"evseId" ocpp:"req,min=0"`
}

type GetCompositeSchedule201Conf

type GetCompositeSchedule201Conf struct {
	Status     string                `json:"status" ocpp:"req,enum=Accepted|Rejected"`
	StatusInfo *StatusInfo           `json:"statusInfo,omitempty"`
	Schedule   *CompositeSchedule201 `json:"schedule,omitempty"`
}

type GetConfiguration16

type GetConfiguration16 struct {
	Key []string `json:"key,omitempty" ocpp:"max=50"`
}

type GetConfiguration16Conf

type GetConfiguration16Conf struct {
	ConfigurationKey []KeyValue16 `json:"configurationKey,omitempty"`
	UnknownKey       []string     `json:"unknownKey,omitempty" ocpp:"max=50"`
}

type GetDiagnostics16

type GetDiagnostics16 struct {
	Location      string `json:"location" ocpp:"req"`
	Retries       *int   `json:"retries,omitempty"`
	RetryInterval *int   `json:"retryInterval,omitempty"`
	StartTime     string `json:"startTime,omitempty" ocpp:"dt"`
	StopTime      string `json:"stopTime,omitempty" ocpp:"dt"`
}

type GetDiagnostics16Conf

type GetDiagnostics16Conf struct {
	FileName string `json:"fileName,omitempty" ocpp:"max=255"`
}

type GetInstalledCertificateIds16

type GetInstalledCertificateIds16 struct {
	CertificateType string `json:"certificateType" ocpp:"req,enum=CentralSystemRootCertificate|ManufacturerRootCertificate"`
}

type GetInstalledCertificateIds16Conf

type GetInstalledCertificateIds16Conf struct {
	Status              string                `json:"status" ocpp:"req,enum=Accepted|NotFound"`
	CertificateHashData []CertificateHashData `json:"certificateHashData,omitempty" ocpp:"minItems=1"`
}

type GetInstalledCertificateIds201

type GetInstalledCertificateIds201 struct {
	CertificateType []string `` /* 160-byte string literal not displayed */
}

type GetInstalledCertificateIds201Conf

type GetInstalledCertificateIds201Conf struct {
	Status                   string                     `json:"status" ocpp:"req,enum=Accepted|NotFound"`
	StatusInfo               *StatusInfo                `json:"statusInfo,omitempty"`
	CertificateHashDataChain []CertificateHashDataChain `json:"certificateHashDataChain,omitempty" ocpp:"minItems=1"`
}

type GetLocalListVersion16Conf

type GetLocalListVersion16Conf struct {
	ListVersion int `json:"listVersion" ocpp:"req"`
}

type GetLocalListVersion201Conf

type GetLocalListVersion201Conf struct {
	VersionNumber int `json:"versionNumber" ocpp:"req"`
}

type GetLog201

type GetLog201 struct {
	Log           LogParameters `json:"log" ocpp:"req"`
	LogType       string        `json:"logType" ocpp:"req,enum=DiagnosticsLog|SecurityLog"`
	RequestID     int           `json:"requestId" ocpp:"req"`
	Retries       *int          `json:"retries,omitempty"`
	RetryInterval *int          `json:"retryInterval,omitempty"`
}

type GetLog201Conf

type GetLog201Conf struct {
	Status     string      `json:"status" ocpp:"req,enum=Accepted|Rejected|AcceptedCanceled"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
	Filename   string      `json:"filename,omitempty" ocpp:"max=255"`
}

type GetMonitoringReport201

type GetMonitoringReport201 struct {
	RequestID          int                 `json:"requestId" ocpp:"req"`
	MonitoringCriteria []string            `json:"monitoringCriteria,omitempty" ocpp:"minItems=1,maxItems=3,enum=ThresholdMonitoring|DeltaMonitoring|PeriodicMonitoring"`
	ComponentVariable  []ComponentVariable `json:"componentVariable,omitempty" ocpp:"minItems=1"`
}

type GetReport201

type GetReport201 struct {
	RequestID         int                 `json:"requestId" ocpp:"req"`
	ComponentCriteria []string            `json:"componentCriteria,omitempty" ocpp:"minItems=1,maxItems=4,enum=Active|Available|Enabled|Problem"`
	ComponentVariable []ComponentVariable `json:"componentVariable,omitempty" ocpp:"minItems=1"`
}

type GetVariableData

type GetVariableData struct {
	AttributeType string    `json:"attributeType,omitempty" ocpp:"enum=Actual|Target|MinSet|MaxSet"`
	Component     Component `json:"component" ocpp:"req"`
	Variable      Variable  `json:"variable" ocpp:"req"`
}

type GetVariableResult

type GetVariableResult struct {
	AttributeStatus     string      `json:"attributeStatus" ocpp:"req,enum=Accepted|Rejected|UnknownComponent|UnknownVariable|NotSupportedAttributeType"`
	AttributeStatusInfo *StatusInfo `json:"attributeStatusInfo,omitempty"`
	AttributeType       string      `json:"attributeType,omitempty" ocpp:"enum=Actual|Target|MinSet|MaxSet"`
	AttributeValue      string      `json:"attributeValue,omitempty" ocpp:"max=2500"`
	Component           Component   `json:"component" ocpp:"req"`
	Variable            Variable    `json:"variable" ocpp:"req"`
}

type GetVariables201

type GetVariables201 struct {
	GetVariableData []GetVariableData `json:"getVariableData" ocpp:"req,minItems=1"`
}

type GetVariables201Conf

type GetVariables201Conf struct {
	GetVariableResult []GetVariableResult `json:"getVariableResult" ocpp:"req,minItems=1"`
}

type Handler

type Handler func(ctx context.Context, action string, payload json.RawMessage) (any, error)

Handler answers a CALL: a payload to send in a CALLRESULT, or an error (an *RPCError chooses the CALLERROR code; any other error is an InternalError).

type HeartbeatConf

type HeartbeatConf struct {
	CurrentTime string `json:"currentTime" ocpp:"req,dt"`
}

type IDTagInfo16

type IDTagInfo16 struct {
	ExpiryDate  string `json:"expiryDate,omitempty" ocpp:"dt"`
	ParentIDTag string `json:"parentIdTag,omitempty" ocpp:"max=20"`
	Status      string `json:"status" ocpp:"req,enum=Accepted|Blocked|Expired|Invalid|ConcurrentTx"`
}

type IDToken

type IDToken struct {
	IDToken        string           `json:"idToken" ocpp:"req,max=36"`
	Type           string           `json:"type" ocpp:"req,enum=Central|eMAID|ISO14443|ISO15693|KeyCode|Local|MacAddress|NoAuthorization"`
	AdditionalInfo []AdditionalInfo `json:"additionalInfo,omitempty" ocpp:"minItems=1"`
}

type IDTokenInfo

type IDTokenInfo struct {
	Status              string          `` /* 143-byte string literal not displayed */
	CacheExpiryDateTime string          `json:"cacheExpiryDateTime,omitempty" ocpp:"dt"`
	ChargingPriority    *int            `json:"chargingPriority,omitempty"`
	Language1           string          `json:"language1,omitempty" ocpp:"max=8"`
	Language2           string          `json:"language2,omitempty" ocpp:"max=8"`
	EVSEID              []int           `json:"evseId,omitempty" ocpp:"minItems=1"`
	GroupIDToken        *IDToken        `json:"groupIdToken,omitempty"`
	PersonalMessage     json.RawMessage `json:"personalMessage,omitempty"`
}

type InstallCertificate16

type InstallCertificate16 struct {
	CertificateType string `json:"certificateType" ocpp:"req,enum=CentralSystemRootCertificate|ManufacturerRootCertificate"`
	Certificate     string `json:"certificate" ocpp:"req,max=5500"`
}

type InstallCertificate16Conf

type InstallCertificate16Conf struct {
	Status string `json:"status" ocpp:"req,enum=Accepted|Failed|Rejected"`
}

type InstallCertificate201

type InstallCertificate201 struct {
	CertificateType string `json:"certificateType" ocpp:"req,enum=V2GRootCertificate|MORootCertificate|CSMSRootCertificate|ManufacturerRootCertificate"`
	Certificate     string `json:"certificate" ocpp:"req,max=5500"`
}

type InstallCertificate201Conf

type InstallCertificate201Conf struct {
	Status     string      `json:"status" ocpp:"req,enum=Accepted|Rejected|Failed"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
}

type KeyValue16

type KeyValue16 struct {
	Key      string  `json:"key" ocpp:"req,max=50"`
	Readonly bool    `json:"readonly" ocpp:"req"`
	Value    *string `json:"value,omitempty" ocpp:"max=500"`
}

type LogParameters

type LogParameters struct {
	RemoteLocation  string `json:"remoteLocation" ocpp:"req,max=512"`
	OldestTimestamp string `json:"oldestTimestamp,omitempty" ocpp:"dt"`
	LatestTimestamp string `json:"latestTimestamp,omitempty" ocpp:"dt"`
}

type LogStatusNotification201

type LogStatusNotification201 struct {
	Status    string `` /* 134-byte string literal not displayed */
	RequestID *int   `json:"requestId,omitempty"`
}

type MeterValue16

type MeterValue16 struct {
	Timestamp    string           `json:"timestamp" ocpp:"req,dt"`
	SampledValue []SampledValue16 `json:"sampledValue" ocpp:"req,minItems=1"`
}

type MeterValue201

type MeterValue201 struct {
	Timestamp    string            `json:"timestamp" ocpp:"req,dt"`
	SampledValue []SampledValue201 `json:"sampledValue" ocpp:"req,minItems=1"`
}

type MeterValues16

type MeterValues16 struct {
	ConnectorID   int            `json:"connectorId" ocpp:"req,min=0"`
	TransactionID *int32         `json:"transactionId,omitempty"`
	MeterValue    []MeterValue16 `json:"meterValue" ocpp:"req,minItems=1"`
}

type MeterValues201

type MeterValues201 struct {
	EVSEID     int             `json:"evseId" ocpp:"req,min=0"`
	MeterValue []MeterValue201 `json:"meterValue" ocpp:"req,minItems=1"`
}

type Modem

type Modem struct {
	ICCID string `json:"iccid,omitempty" ocpp:"max=20"`
	IMSI  string `json:"imsi,omitempty" ocpp:"max=20"`
}

type MonitoringData

type MonitoringData struct {
	Component          Component            `json:"component" ocpp:"req"`
	Variable           Variable             `json:"variable" ocpp:"req"`
	VariableMonitoring []VariableMonitoring `json:"variableMonitoring" ocpp:"req,minItems=1"`
}

type MsgDef

type MsgDef struct {
	Req, Conf reflect.Type
	OK        []string
}

MsgDef is one action: its request and confirmation types, and for CSMS-initiated actions the statuses that count as success (none: any valid answer succeeds).

func Def

func Def[Req, Conf any](ok ...string) MsgDef

Def is the MsgDef of an action with request type Req and confirmation type Conf.

type MsgSigner

type MsgSigner struct {

	// Leaf is our signing certificate, when one is configured.
	Leaf *x509.Certificate
	// Trusted are the certificates whose signatures are verified, with
	// the index of the PEM text they came from.
	Trusted []TrustedCert
	// contains filtered or unexported fields
}

MsgSigner signs and verifies signed messages. A nil *MsgSigner verifies nothing (Open passes payloads through unverified) and cannot sign.

func NewMsgSigner

func NewMsgSigner(certPEM, keyPEM []byte, trusted [][]byte, require bool) (*MsgSigner, error)

NewMsgSigner makes a signer from our signing certificate and key (PEM, both empty for a verify-only signer) and PEM texts of certificates whose signatures are verified; require refuses signed messages from unknown keys. An EC signing key must be P-256 (ES256); an RSA key signs RS256.

func (*MsgSigner) Open

func (m *MsgSigner) Open(action string, p json.RawMessage) (json.RawMessage, *RPCError)

Open verifies a signed payload and returns the plain one; action is the expected OCPPAction ("" to skip the check).

func (*MsgSigner) Sign

func (m *MsgSigner) Sign(action string, typ int, payload []byte) (json.RawMessage, error)

Sign wraps a payload for action (message type typ).

type NotifyEvent201

type NotifyEvent201 struct {
	GeneratedAt string      `json:"generatedAt" ocpp:"req,dt"`
	Tbc         bool        `json:"tbc,omitempty"`
	SeqNo       int         `json:"seqNo" ocpp:"req,min=0"`
	EventData   []EventData `json:"eventData" ocpp:"req,minItems=1"`
}

type NotifyMonitoringReport201

type NotifyMonitoringReport201 struct {
	Monitor     []MonitoringData `json:"monitor,omitempty" ocpp:"minItems=1"`
	RequestID   int              `json:"requestId" ocpp:"req"`
	Tbc         bool             `json:"tbc,omitempty"`
	SeqNo       int              `json:"seqNo" ocpp:"req,min=0"`
	GeneratedAt string           `json:"generatedAt" ocpp:"req,dt"`
}

type NotifyReport201

type NotifyReport201 struct {
	RequestID   int          `json:"requestId" ocpp:"req"`
	GeneratedAt string       `json:"generatedAt" ocpp:"req,dt"`
	ReportData  []ReportData `json:"reportData,omitempty" ocpp:"minItems=1"`
	Tbc         bool         `json:"tbc,omitempty"`
	SeqNo       int          `json:"seqNo" ocpp:"req,min=0"`
}

type OCSPRequestData

type OCSPRequestData struct {
	HashAlgorithm  string `json:"hashAlgorithm" ocpp:"req,enum=SHA256|SHA384|SHA512"`
	IssuerNameHash string `json:"issuerNameHash" ocpp:"req,max=128"`
	IssuerKeyHash  string `json:"issuerKeyHash" ocpp:"req,max=128"`
	SerialNumber   string `json:"serialNumber" ocpp:"req,max=40"`
	ResponderURL   string `json:"responderURL" ocpp:"req,max=512"`
}

type PnC16Def added in v0.2.0

type PnC16Def struct {
	MsgDef
	FromCP bool
}

PnC16Def is one application note message.

type PnCAuthorize16 added in v0.2.0

type PnCAuthorize16 struct {
	Certificate                 string                 `json:"certificate,omitempty" ocpp:"max=5500"`
	IDToken                     PnCIDToken16           `json:"idToken" ocpp:"req"`
	ISO15118CertificateHashData []PnCOCSPRequestData16 `json:"iso15118CertificateHashData,omitempty" ocpp:"maxItems=4"`
}

type PnCAuthorize16Conf added in v0.2.0

type PnCAuthorize16Conf struct {
	CertificateStatus string           `` /* 164-byte string literal not displayed */
	IDTokenInfo       PnCIDTokenInfo16 `json:"idTokenInfo" ocpp:"req"`
}

type PnCCertificateHashData16 added in v0.2.0

type PnCCertificateHashData16 struct {
	HashAlgorithm  string `json:"hashAlgorithm" ocpp:"req,enum=SHA256|SHA384|SHA512"`
	IssuerNameHash string `json:"issuerNameHash" ocpp:"req,max=128"`
	IssuerKeyHash  string `json:"issuerKeyHash" ocpp:"req,max=128"`
	SerialNumber   string `json:"serialNumber" ocpp:"req,max=40"`
}

type PnCCertificateHashDataChain16 added in v0.2.0

type PnCCertificateHashDataChain16 struct {
	CertificateType          string                     `json:"certificateType" ocpp:"req,enum=V2GRootCertificate|MORootCertificate|V2GCertificateChain"`
	CertificateHashData      PnCCertificateHashData16   `json:"certificateHashData" ocpp:"req"`
	ChildCertificateHashData []PnCCertificateHashData16 `json:"childCertificateHashData,omitempty" ocpp:"maxItems=4"`
}

type PnCCertificateSigned16 added in v0.2.0

type PnCCertificateSigned16 struct {
	CertificateChain string `json:"certificateChain" ocpp:"req,max=10000"`
}

type PnCDeleteCertificate16 added in v0.2.0

type PnCDeleteCertificate16 struct {
	CertificateHashData PnCCertificateHashData16 `json:"certificateHashData" ocpp:"req"`
}

type PnCGet15118EVCertificate16 added in v0.2.0

type PnCGet15118EVCertificate16 struct {
	ISO15118SchemaVersion string `json:"iso15118SchemaVersion" ocpp:"req,max=50"`
	Action                string `json:"action" ocpp:"req,enum=Install|Update"`
	EXIRequest            string `json:"exiRequest" ocpp:"req,max=5600"`
}

type PnCGet15118EVCertificate16Conf added in v0.2.0

type PnCGet15118EVCertificate16Conf struct {
	Status      string `json:"status" ocpp:"req,enum=Accepted|Failed"`
	EXIResponse string `json:"exiResponse" ocpp:"req,max=5600"`
}

type PnCGetCertificateStatus16 added in v0.2.0

type PnCGetCertificateStatus16 struct {
	OCSPRequestData PnCOCSPRequestData16 `json:"ocspRequestData" ocpp:"req"`
}

type PnCGetCertificateStatus16Conf added in v0.2.0

type PnCGetCertificateStatus16Conf struct {
	Status     string `json:"status" ocpp:"req,enum=Accepted|Failed"`
	OCSPResult string `json:"ocspResult,omitempty" ocpp:"max=5500"`
}

type PnCGetInstalledCertificateIDs16 added in v0.2.0

type PnCGetInstalledCertificateIDs16 struct {
	CertificateType []string `json:"certificateType,omitempty"`
}

type PnCGetInstalledCertificateIDs16Conf added in v0.2.0

type PnCGetInstalledCertificateIDs16Conf struct {
	Status                   string                          `json:"status" ocpp:"req,enum=Accepted|NotFound"`
	CertificateHashDataChain []PnCCertificateHashDataChain16 `json:"certificateHashDataChain,omitempty"`
}

type PnCIDToken16 added in v0.2.0

type PnCIDToken16 struct {
	IDToken string `json:"idToken" ocpp:"req,max=20"`
}

type PnCIDTokenInfo16 added in v0.2.0

type PnCIDTokenInfo16 struct {
	Status              string `json:"status" ocpp:"req,enum=Accepted|Blocked|ConcurrentTx|Expired|Invalid"`
	CacheExpiryDateTime string `json:"cacheExpiryDateTime,omitempty" ocpp:"dt"`
}

type PnCInstallCertificate16 added in v0.2.0

type PnCInstallCertificate16 struct {
	CertificateType string `json:"certificateType" ocpp:"req,enum=V2GRootCertificate|MORootCertificate"`
	Certificate     string `json:"certificate" ocpp:"req,max=5500"`
}

type PnCOCSPRequestData16 added in v0.2.0

type PnCOCSPRequestData16 struct {
	HashAlgorithm  string `json:"hashAlgorithm" ocpp:"req,enum=SHA256|SHA384|SHA512"`
	IssuerNameHash string `json:"issuerNameHash" ocpp:"req,max=128"`
	IssuerKeyHash  string `json:"issuerKeyHash" ocpp:"req,max=128"`
	SerialNumber   string `json:"serialNumber" ocpp:"req,max=40"`
	ResponderURL   string `json:"responderURL" ocpp:"req,max=512"`
}

type PnCSignCertificate16 added in v0.2.0

type PnCSignCertificate16 struct {
	CSR string `json:"csr" ocpp:"req,max=5500"`
}

type PnCStatusConf16 added in v0.2.0

type PnCStatusConf16 struct {
	Status string `json:"status" ocpp:"req"`
}

PnCStatusConf16 is a confirmation with a status only; PnC16Check checks the status against the message's values.

type RPCError

type RPCError struct {
	Kind ErrKind
	Desc string
	// Enum marks a value outside an enumeration (our Go types' check).
	Enum bool
}

RPCError is a problem to answer with a CALLERROR.

func DecodeIn

func DecodeIn(version, action string, md MsgDef, payload json.RawMessage) (any, *RPCError)

DecodeIn validates a received request (1.6: our Go types; 2.x: the OCA JSON schema) and decodes it into its Go type.

Example

A 1.6 request is checked against its schema and decoded into its Go type.

package main

import (
	"encoding/json"
	"fmt"

	"github.com/cB-Sigma/ocpp"
)

func main() {
	md := ocpp.V16In["BootNotification"]
	v, verr := ocpp.DecodeIn(ocpp.V16, "BootNotification", md, json.RawMessage(`{"chargePointVendor":"Acme","chargePointModel":"AC22"}`))
	if verr != nil {
		fmt.Println(verr.Kind.Code(ocpp.V16), verr.Desc)
		return
	}
	fmt.Println(v.(*ocpp.BootNotification16).ChargePointVendor)
	_, verr = ocpp.DecodeIn(ocpp.V16, "BootNotification", md, json.RawMessage(`{"chargePointVendor":"Acme"}`))
	fmt.Println(verr.Kind.Code(ocpp.V16))
}
Output:
Acme
OccurenceConstraintViolation

func DecodeLoose

func DecodeLoose(t reflect.Type, payload json.RawMessage) (any, *RPCError)

DecodeLoose decodes a payload into a new t without the schema facts.

func PnC16Check added in v0.2.0

func PnC16Check(name string, response bool, payload json.RawMessage) (any, *RPCError)

PnC16Check validates the payload of application note message name (a confirmation when response is set) and decodes it into its Go type.

func PnC16ReadAnswer added in v0.2.0

func PnC16ReadAnswer(name string, conf json.RawMessage) (answer json.RawMessage, status string, ok bool, verr *RPCError)

PnC16ReadAnswer reads the DataTransfer confirmation to message name: the checked answer, or ok false when the peer did not take the message (status other than Accepted: UnknownVendorId and the like, which the note reads as no Plug & Charge support).

func PnC16Unwrap added in v0.2.0

func PnC16Unwrap(dt json.RawMessage) (name string, payload json.RawMessage, ok bool, verr *RPCError)

PnC16Unwrap reads a DataTransfer request: ok is false when it is not the application note's (another vendorId); otherwise the message name and its checked payload, or the error to answer with.

func RPCErrorf

func RPCErrorf(k ErrKind, f string, a ...any) *RPCError

RPCErrorf is an RPCError of kind k with a formatted description.

func Validate

func Validate(t reflect.Type, raw json.RawMessage, version string) (any, *RPCError)

Validate checks a raw payload against t (a struct type of this package, by its `ocpp` tags) and decodes it into a new value of t.

func ValidateJSON

func ValidateJSON(version, action string, response bool, raw json.RawMessage) (map[string]any, *RPCError)

ValidateJSON checks raw against the OCA schema of action's request or response in version and returns it decoded (numbers as json.Number).

func ValidateRequest added in v0.2.0

func ValidateRequest(version, action string, payload json.RawMessage) *RPCError

ValidateRequest checks the request of action in version, whichever side sends it, and returns the problem as an *RPCError carrying the kind of CALLERROR to answer (nil when the payload is valid).

2.0.1 and 2.1 requests are checked against the OCA schema. 1.6 requests are checked against the OCA 1.6 schema when the action has one and then against this package's Go type when it has one (the 1.6 security extension messages have only the Go type). An action that neither knows is reported with KindNotImplemented. The payload of a signed action (an action name ending in SignedSuffix) is a JWS and is not checked here.

func ValidateResponse added in v0.2.0

func ValidateResponse(version, action string, payload json.RawMessage) *RPCError

ValidateResponse is ValidateRequest for the CALLRESULT payload of action.

func (*RPCError) Error

func (e *RPCError) Error() string

type RemoteStartTransaction16

type RemoteStartTransaction16 struct {
	ConnectorID     *int               `json:"connectorId,omitempty" ocpp:"min=1"`
	IDTag           string             `json:"idTag" ocpp:"req,max=20"`
	ChargingProfile *ChargingProfile16 `json:"chargingProfile,omitempty"`
}

type RemoteStopTransaction16

type RemoteStopTransaction16 struct {
	TransactionID int32 `json:"transactionId" ocpp:"req"`
}

type ReportChargingProfiles201

type ReportChargingProfiles201 struct {
	RequestID           int                  `json:"requestId" ocpp:"req"`
	ChargingLimitSource string               `json:"chargingLimitSource" ocpp:"req,enum=EMS|Other|SO|CSO"`
	ChargingProfile     []ChargingProfile201 `json:"chargingProfile" ocpp:"req,minItems=1"`
	Tbc                 bool                 `json:"tbc,omitempty"`
	EVSEID              int                  `json:"evseId" ocpp:"req"`
}

type ReportData

type ReportData struct {
	Component               Component                `json:"component" ocpp:"req"`
	Variable                Variable                 `json:"variable" ocpp:"req"`
	VariableAttribute       []VariableAttribute      `json:"variableAttribute" ocpp:"req,minItems=1,maxItems=4"`
	VariableCharacteristics *VariableCharacteristics `json:"variableCharacteristics,omitempty"`
}

type ReportStatusConf201

type ReportStatusConf201 struct {
	Status     string      `json:"status" ocpp:"req,enum=Accepted|Rejected|NotSupported|EmptyResultSet"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
}

type RequestStartTransaction201

type RequestStartTransaction201 struct {
	EVSEID          *int                `json:"evseId,omitempty" ocpp:"min=1"`
	RemoteStartID   int                 `json:"remoteStartId" ocpp:"req"`
	IDToken         IDToken             `json:"idToken" ocpp:"req"`
	ChargingProfile *ChargingProfile201 `json:"chargingProfile,omitempty"`
	GroupIDToken    *IDToken            `json:"groupIdToken,omitempty"`
}

type RequestStartTransaction201Conf

type RequestStartTransaction201Conf struct {
	Status        string      `json:"status" ocpp:"req,enum=Accepted|Rejected"`
	StatusInfo    *StatusInfo `json:"statusInfo,omitempty"`
	TransactionID string      `json:"transactionId,omitempty" ocpp:"max=36"`
}

type RequestStopTransaction201

type RequestStopTransaction201 struct {
	TransactionID string `json:"transactionId" ocpp:"req,max=36"`
}

type ReservationStatusUpdate201

type ReservationStatusUpdate201 struct {
	ReservationID           int    `json:"reservationId" ocpp:"req"`
	ReservationUpdateStatus string `json:"reservationUpdateStatus" ocpp:"req,enum=Expired|Removed"`
}

type ReserveNow16

type ReserveNow16 struct {
	ConnectorID   int    `json:"connectorId" ocpp:"req,min=0"`
	ExpiryDate    string `json:"expiryDate" ocpp:"req,dt"`
	IDTag         string `json:"idTag" ocpp:"req,max=20"`
	ParentIDTag   string `json:"parentIdTag,omitempty" ocpp:"max=20"`
	ReservationID int    `json:"reservationId" ocpp:"req"`
}

type ReserveNow201

type ReserveNow201 struct {
	ID             int      `json:"id" ocpp:"req"`
	ExpiryDateTime string   `json:"expiryDateTime" ocpp:"req,dt"`
	ConnectorType  string   `` /* 246-byte string literal not displayed */
	IDToken        IDToken  `json:"idToken" ocpp:"req"`
	EVSEID         *int     `json:"evseId,omitempty"`
	GroupIDToken   *IDToken `json:"groupIdToken,omitempty"`
}

type ReserveNow201Conf

type ReserveNow201Conf struct {
	Status     string      `json:"status" ocpp:"req,enum=Accepted|Faulted|Occupied|Rejected|Unavailable"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
}

type Reset16

type Reset16 struct {
	Type string `json:"type" ocpp:"req,enum=Hard|Soft"`
}

type Reset201

type Reset201 struct {
	Type   string `json:"type" ocpp:"req,enum=Immediate|OnIdle"`
	EVSEID *int   `json:"evseId,omitempty"`
}

type ResultError

type ResultError struct {
	Code        string
	Description string
}

ResultError is a CALLRESULT that failed validation and was answered with a CALLRESULTERROR.

func (*ResultError) Error

func (e *ResultError) Error() string

type SOAPFault

type SOAPFault struct {
	RelatesTo, Sender, Sub, Reason string
}

SOAPFault is a SOAP Fault to answer with an OCPP sub-code (OCPP-S Table 1): Sender is "Sender" or "Receiver".

func (*SOAPFault) Write

func (f *SOAPFault) Write(w http.ResponseWriter)

Write answers the fault.

type SOAPRequest

type SOAPRequest struct {
	MessageID string // WS-Addressing MessageID
	From      string // WS-Addressing From: where the charger takes calls
	Identity  string // chargeBoxIdentity
	// contains filtered or unexported fields
}

SOAPRequest is an OCPP-S request to the Central System service.

func (*SOAPRequest) Action

func (q *SOAPRequest) Action() (string, *SOAPFault)

Action is the request's action: the Action header without its slash, else the body element's name; the body must hold one element that matches it.

func (*SOAPRequest) CheckWSDL

func (q *SOAPRequest) CheckWSDL() error

CheckWSDL checks the request's body element as CheckSOAPEnvelope does.

func (*SOAPRequest) Payload

func (q *SOAPRequest) Payload(action string) (json.RawMessage, *SOAPFault)

Payload is the request's body element as the OCPP-J 1.6 payload of action, typed by the action's 1.6 JSON schema.

type SampledValue16

type SampledValue16 struct {
	Value     string `json:"value" ocpp:"req"`
	Context   string `` /* 149-byte string literal not displayed */
	Format    string `json:"format,omitempty" ocpp:"enum=Raw|SignedData"`
	Measurand string `` /* 481-byte string literal not displayed */
	Phase     string `json:"phase,omitempty" ocpp:"enum=L1|L2|L3|N|L1-N|L2-N|L3-N|L1-L2|L2-L3|L3-L1"`
	Location  string `json:"location,omitempty" ocpp:"enum=Cable|EV|Inlet|Outlet|Body"`
	Unit      string `json:"unit,omitempty" ocpp:"enum=Wh|kWh|varh|kvarh|W|kW|VA|kVA|var|kvar|A|V|K|Celcius|Celsius|Fahrenheit|Percent"`
}

type SampledValue201

type SampledValue201 struct {
	Value            float64         `json:"value" ocpp:"req"`
	Context          string          `` /* 149-byte string literal not displayed */
	Measurand        string          `` /* 569-byte string literal not displayed */
	Phase            string          `json:"phase,omitempty" ocpp:"enum=L1|L2|L3|N|L1-N|L2-N|L3-N|L1-L2|L2-L3|L3-L1"`
	Location         string          `json:"location,omitempty" ocpp:"enum=Body|Cable|EV|Inlet|Outlet"`
	SignedMeterValue json.RawMessage `json:"signedMeterValue,omitempty"`
	UnitOfMeasure    *UnitOfMeasure  `json:"unitOfMeasure,omitempty"`
}

type SchemaError

type SchemaError struct {
	Code, Description, Schema string
}

SchemaError is a payload that does not match its OCA schema, with the RPC error code it maps to.

func (*SchemaError) Error

func (e *SchemaError) Error() string

type SecurityEventNotification201

type SecurityEventNotification201 struct {
	Type      string `json:"type" ocpp:"req,max=50"`
	Timestamp string `json:"timestamp" ocpp:"req,dt"`
	TechInfo  string `json:"techInfo,omitempty" ocpp:"max=255"`
}

type SendLocalList16

type SendLocalList16 struct {
	ListVersion            int                   `json:"listVersion" ocpp:"req"`
	LocalAuthorizationList []AuthorizationData16 `json:"localAuthorizationList,omitempty"`
	UpdateType             string                `json:"updateType" ocpp:"req,enum=Differential|Full"`
}

type SendLocalList201

type SendLocalList201 struct {
	VersionNumber          int                    `json:"versionNumber" ocpp:"req"`
	UpdateType             string                 `json:"updateType" ocpp:"req,enum=Differential|Full"`
	LocalAuthorizationList []AuthorizationData201 `json:"localAuthorizationList,omitempty" ocpp:"minItems=1"`
}

type SendLocalList201Conf

type SendLocalList201Conf struct {
	Status     string      `json:"status" ocpp:"req,enum=Accepted|Failed|VersionMismatch"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
}

type SetChargingProfile16

type SetChargingProfile16 struct {
	ConnectorID        int               `json:"connectorId" ocpp:"req,min=0"`
	CSChargingProfiles ChargingProfile16 `json:"csChargingProfiles" ocpp:"req"`
}

type SetChargingProfile201

type SetChargingProfile201 struct {
	EVSEID          int                `json:"evseId" ocpp:"req,min=0"`
	ChargingProfile ChargingProfile201 `json:"chargingProfile" ocpp:"req"`
}

type SetMonitoringBase201

type SetMonitoringBase201 struct {
	MonitoringBase string `json:"monitoringBase" ocpp:"req,enum=All|FactoryDefault|HardWiredOnly"`
}

type SetMonitoringData

type SetMonitoringData struct {
	ID          *int      `json:"id,omitempty"`
	Transaction *bool     `json:"transaction,omitempty"`
	Value       float64   `json:"value" ocpp:"req"`
	Type        string    `json:"type" ocpp:"req,enum=UpperThreshold|LowerThreshold|Delta|Periodic|PeriodicClockAligned"`
	Severity    int       `json:"severity" ocpp:"req,min=0"`
	Component   Component `json:"component" ocpp:"req"`
	Variable    Variable  `json:"variable" ocpp:"req"`
}

type SetMonitoringLevel201

type SetMonitoringLevel201 struct {
	Severity int `json:"severity" ocpp:"req,min=0"`
}

type SetMonitoringResult

type SetMonitoringResult struct {
	ID         *int        `json:"id,omitempty"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
	Status     string      `json:"status" ocpp:"req,enum=Accepted|UnknownComponent|UnknownVariable|UnsupportedMonitorType|Rejected|Duplicate"`
	Type       string      `json:"type" ocpp:"req,enum=UpperThreshold|LowerThreshold|Delta|Periodic|PeriodicClockAligned"`
	Component  Component   `json:"component" ocpp:"req"`
	Variable   Variable    `json:"variable" ocpp:"req"`
	Severity   int         `json:"severity" ocpp:"req"`
}

type SetVariableData

type SetVariableData struct {
	AttributeType  string    `json:"attributeType,omitempty" ocpp:"enum=Actual|Target|MinSet|MaxSet"`
	AttributeValue string    `json:"attributeValue" ocpp:"req,max=1000"`
	Component      Component `json:"component" ocpp:"req"`
	Variable       Variable  `json:"variable" ocpp:"req"`
}

type SetVariableMonitoring201

type SetVariableMonitoring201 struct {
	SetMonitoringData []SetMonitoringData `json:"setMonitoringData" ocpp:"req,minItems=1"`
}

type SetVariableMonitoring201Conf

type SetVariableMonitoring201Conf struct {
	SetMonitoringResult []SetMonitoringResult `json:"setMonitoringResult" ocpp:"req,minItems=1"`
}

type SetVariableResult

type SetVariableResult struct {
	AttributeType       string      `json:"attributeType,omitempty" ocpp:"enum=Actual|Target|MinSet|MaxSet"`
	AttributeStatus     string      `` /* 130-byte string literal not displayed */
	AttributeStatusInfo *StatusInfo `json:"attributeStatusInfo,omitempty"`
	Component           Component   `json:"component" ocpp:"req"`
	Variable            Variable    `json:"variable" ocpp:"req"`
}

type SetVariables201

type SetVariables201 struct {
	SetVariableData []SetVariableData `json:"setVariableData" ocpp:"req,minItems=1"`
}

type SetVariables201Conf

type SetVariables201Conf struct {
	SetVariableResult []SetVariableResult `json:"setVariableResult" ocpp:"req,minItems=1"`
}

type SignCertificate16

type SignCertificate16 struct {
	CSR string `json:"csr" ocpp:"req,max=5500"`
}

type SignCertificate16Conf

type SignCertificate16Conf struct {
	Status string `json:"status" ocpp:"req,enum=Accepted|Rejected"`
}

type SignCertificate201

type SignCertificate201 struct {
	CSR             string `json:"csr" ocpp:"req,max=5500"`
	CertificateType string `json:"certificateType,omitempty" ocpp:"enum=ChargingStationCertificate|V2GCertificate"`
}

type SignCertificate201Conf

type SignCertificate201Conf struct {
	Status     string      `json:"status" ocpp:"req,enum=Accepted|Rejected"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
}

type SignedFirmwareStatusNotification16

type SignedFirmwareStatusNotification16 struct {
	Status    string `` /* 240-byte string literal not displayed */
	RequestID *int   `json:"requestId,omitempty"`
}

type SignedUpdateFirmware16

type SignedUpdateFirmware16 struct {
	Retries       *int     `json:"retries,omitempty"`
	RetryInterval *int     `json:"retryInterval,omitempty"`
	RequestID     int      `json:"requestId" ocpp:"req"`
	Firmware      Firmware `json:"firmware" ocpp:"req"`
}

type SignedUpdateFirmware16Conf

type SignedUpdateFirmware16Conf struct {
	Status string `json:"status" ocpp:"req,enum=Accepted|Rejected|AcceptedCanceled|InvalidCertificate|RevokedCertificate"`
}

type StartTransaction16

type StartTransaction16 struct {
	ConnectorID   int    `json:"connectorId" ocpp:"req,min=1"`
	IDTag         string `json:"idTag" ocpp:"req,max=20"`
	MeterStart    int    `json:"meterStart" ocpp:"req"`
	ReservationID *int   `json:"reservationId,omitempty"`
	Timestamp     string `json:"timestamp" ocpp:"req,dt"`
}

type StartTransaction16Conf

type StartTransaction16Conf struct {
	IDTagInfo     IDTagInfo16 `json:"idTagInfo" ocpp:"req"`
	TransactionID int32       `json:"transactionId" ocpp:"req"`
}

type StatusConf16

type StatusConf16 struct {
	Status string `json:"status" ocpp:"req"`
}

type StatusConf201

type StatusConf201 struct {
	Status     string      `json:"status" ocpp:"req"`
	StatusInfo *StatusInfo `json:"statusInfo,omitempty"`
}

type StatusInfo

type StatusInfo struct {
	ReasonCode     string `json:"reasonCode" ocpp:"req,max=20"`
	AdditionalInfo string `json:"additionalInfo,omitempty" ocpp:"max=512"`
}

type StatusNotification16

type StatusNotification16 struct {
	ConnectorID     int    `json:"connectorId" ocpp:"req,min=0"`
	ErrorCode       string `` /* 274-byte string literal not displayed */
	Info            string `json:"info,omitempty" ocpp:"max=50"`
	Status          string `json:"status" ocpp:"req,enum=Available|Preparing|Charging|SuspendedEVSE|SuspendedEV|Finishing|Reserved|Unavailable|Faulted"`
	Timestamp       string `json:"timestamp,omitempty" ocpp:"dt"`
	VendorID        string `json:"vendorId,omitempty" ocpp:"max=255"`
	VendorErrorCode string `json:"vendorErrorCode,omitempty" ocpp:"max=50"`
}

type StatusNotification201

type StatusNotification201 struct {
	Timestamp       string `json:"timestamp" ocpp:"req,dt"`
	ConnectorStatus string `json:"connectorStatus" ocpp:"req,enum=Available|Occupied|Reserved|Unavailable|Faulted"`
	EVSEID          int    `json:"evseId" ocpp:"req,min=0"`
	ConnectorID     int    `json:"connectorId" ocpp:"req,min=0"`
}

type StopTransaction16

type StopTransaction16 struct {
	IDTag           string         `json:"idTag,omitempty" ocpp:"max=20"`
	MeterStop       int            `json:"meterStop" ocpp:"req"`
	Timestamp       string         `json:"timestamp" ocpp:"req,dt"`
	TransactionID   int32          `json:"transactionId" ocpp:"req"`
	Reason          string         `` /* 147-byte string literal not displayed */
	TransactionData []MeterValue16 `json:"transactionData,omitempty"`
}

type StopTransaction16Conf

type StopTransaction16Conf struct {
	IDTagInfo *IDTagInfo16 `json:"idTagInfo,omitempty"`
}

type TransactionEvent201

type TransactionEvent201 struct {
	EventType          string          `json:"eventType" ocpp:"req,enum=Ended|Started|Updated"`
	Timestamp          string          `json:"timestamp" ocpp:"req,dt"`
	TriggerReason      string          `` /* 356-byte string literal not displayed */
	SeqNo              int             `json:"seqNo" ocpp:"req,min=0"`
	Offline            bool            `json:"offline,omitempty"`
	NumberOfPhasesUsed *int            `json:"numberOfPhasesUsed,omitempty"`
	CableMaxCurrent    *int            `json:"cableMaxCurrent,omitempty"`
	ReservationID      *int            `json:"reservationId,omitempty"`
	TransactionInfo    TransactionInfo `json:"transactionInfo" ocpp:"req"`
	IDToken            *IDToken        `json:"idToken,omitempty"`
	EVSE               *EVSE           `json:"evse,omitempty"`
	MeterValue         []MeterValue201 `json:"meterValue,omitempty" ocpp:"minItems=1"`
}

type TransactionEvent201Conf

type TransactionEvent201Conf struct {
	TotalCost              *float64        `json:"totalCost,omitempty"`
	ChargingPriority       *int            `json:"chargingPriority,omitempty"`
	IDTokenInfo            *IDTokenInfo    `json:"idTokenInfo,omitempty"`
	UpdatedPersonalMessage json.RawMessage `json:"updatedPersonalMessage,omitempty"`
}

type TransactionInfo

type TransactionInfo struct {
	TransactionID     string `json:"transactionId" ocpp:"req,max=36"`
	ChargingState     string `json:"chargingState,omitempty" ocpp:"enum=Charging|EVConnected|SuspendedEV|SuspendedEVSE|Idle"`
	TimeSpentCharging *int   `json:"timeSpentCharging,omitempty"`
	StoppedReason     string `` /* 277-byte string literal not displayed */
	RemoteStartID     *int   `json:"remoteStartId,omitempty"`
}

type TriggerMessage16

type TriggerMessage16 struct {
	RequestedMessage string `` /* 154-byte string literal not displayed */
	ConnectorID      *int   `json:"connectorId,omitempty" ocpp:"min=0"`
}

type TriggerMessage201

type TriggerMessage201 struct {
	RequestedMessage string `` /* 271-byte string literal not displayed */
	EVSE             *EVSE  `json:"evse,omitempty"`
}

type TrustedCert

type TrustedCert struct {
	Index int // of the PEM text in NewMsgSigner's trusted
	Cert  *x509.Certificate
}

TrustedCert is a certificate whose signatures a MsgSigner verifies.

type UnitOfMeasure

type UnitOfMeasure struct {
	Unit       string `json:"unit,omitempty" ocpp:"max=20"`
	Multiplier *int   `json:"multiplier,omitempty"`
}

type UnlockConnector16

type UnlockConnector16 struct {
	ConnectorID int `json:"connectorId" ocpp:"req,min=1"`
}

type UnlockConnector201

type UnlockConnector201 struct {
	EVSEID      int `json:"evseId" ocpp:"req"`
	ConnectorID int `json:"connectorId" ocpp:"req"`
}

type UnreachableError

type UnreachableError struct{ Err error }

UnreachableError is a SOAP call that did not reach the charger.

func (*UnreachableError) Error

func (e *UnreachableError) Error() string

func (*UnreachableError) Unwrap

func (e *UnreachableError) Unwrap() error

type UpdateFirmware16

type UpdateFirmware16 struct {
	Location      string `json:"location" ocpp:"req"`
	Retries       *int   `json:"retries,omitempty"`
	RetrieveDate  string `json:"retrieveDate" ocpp:"req,dt"`
	RetryInterval *int   `json:"retryInterval,omitempty"`
}

type UpdateFirmware201

type UpdateFirmware201 struct {
	Retries       *int     `json:"retries,omitempty"`
	RetryInterval *int     `json:"retryInterval,omitempty"`
	RequestID     int      `json:"requestId" ocpp:"req"`
	Firmware      Firmware `json:"firmware" ocpp:"req"`
}

type Variable

type Variable struct {
	Name     string `json:"name" ocpp:"req,max=50"`
	Instance string `json:"instance,omitempty" ocpp:"max=50"`
}

type VariableAttribute

type VariableAttribute struct {
	Type       string  `json:"type,omitempty" ocpp:"enum=Actual|Target|MinSet|MaxSet"`
	Value      *string `json:"value,omitempty" ocpp:"max=2500"`
	Mutability string  `json:"mutability,omitempty" ocpp:"enum=ReadOnly|WriteOnly|ReadWrite"`
	Persistent *bool   `json:"persistent,omitempty"`
	Constant   *bool   `json:"constant,omitempty"`
}

type VariableCharacteristics

type VariableCharacteristics struct {
	Unit               string   `json:"unit,omitempty" ocpp:"max=16"`
	DataType           string   `json:"dataType" ocpp:"req,enum=string|decimal|integer|dateTime|boolean|OptionList|SequenceList|MemberList"`
	MinLimit           *float64 `json:"minLimit,omitempty"`
	MaxLimit           *float64 `json:"maxLimit,omitempty"`
	ValuesList         string   `json:"valuesList,omitempty" ocpp:"max=1000"`
	SupportsMonitoring bool     `json:"supportsMonitoring" ocpp:"req"`
}

type VariableMonitoring

type VariableMonitoring struct {
	ID          int     `json:"id" ocpp:"req"`
	Transaction bool    `json:"transaction" ocpp:"req"`
	Value       float64 `json:"value" ocpp:"req"`
	Type        string  `json:"type" ocpp:"req,enum=UpperThreshold|LowerThreshold|Delta|Periodic|PeriodicClockAligned"`
	Severity    int     `json:"severity" ocpp:"req"`
}

Directories

Path Synopsis
Package chargepoint is the charging station side of OCPP-J as a library role: it dials a central system as <url>/<identity> with the versions it offers, authenticates (security profiles 1 to 3), routes the central system's CALLs to handlers by action, checks every request and answer against the OCA schemas and, run with Run, reconnects with the randomised, doubling back-off of the 2.x OCPPCommCtrlr variables.
Package chargepoint is the charging station side of OCPP-J as a library role: it dials a central system as <url>/<identity> with the versions it offers, authenticates (security profiles 1 to 3), routes the central system's CALLs to handlers by action, checks every request and answer against the OCA schemas and, run with Run, reconnects with the randomised, doubling back-off of the 2.x OCPPCommCtrlr variables.
Package csms is the central system side of OCPP-J as a library role: an http.Handler that accepts charging stations of 1.6, 2.0.1 and 2.1 at <path>/<identity>, authenticates them (security profiles 1 to 3 through a hook), routes their CALLs and 2.1 SENDs to handlers by action, checks every request and every answer against the OCA schemas, keeps a registry of connected stations and calls them.
Package csms is the central system side of OCPP-J as a library role: an http.Handler that accepts charging stations of 1.6, 2.0.1 and 2.1 at <path>/<identity>, authenticates them (security profiles 1 to 3 through a hook), routes their CALLs and 2.1 SENDs to handlers by action, checks every request and every answer against the OCA schemas, keeps a registry of connected stations and calls them.
internal
cmd/gen21 command
Command gen21 writes v21/messages.go from the embedded OCPP 2.1 schemas.
Command gen21 writes v21/messages.go from the embedded OCPP 2.1 schemas.
gen21
Package gen21 writes the Go types of package v21 from the OCA's OCPP 2.1 JSON schemas, which the ocpp module embeds unmodified.
Package gen21 writes the Go types of package v21 from the OCA's OCPP 2.1 JSON schemas, which the ocpp module embeds unmodified.
Package v21 holds Go types for every OCPP 2.1 message, generated from the OCA's 2.1 JSON schemas that the ocpp module embeds: one struct per request and response (<Action>Request, <Action>Response; the SEND message NotifyPeriodicEventStream as NotifyPeriodicEventStreamRequest), a named string type with constants per enumeration, and one struct per shared object.
Package v21 holds Go types for every OCPP 2.1 message, generated from the OCA's 2.1 JSON schemas that the ocpp module embeds: one struct per request and response (<Action>Request, <Action>Response; the SEND message NotifyPeriodicEventStream as NotifyPeriodicEventStreamRequest), a named string type with constants per enumeration, and one struct per shared object.

Jump to

Keyboard shortcuts

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