Skip to content

aasanchez/ocpp16messages

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

137 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OCPP 1.6 Messages for Go

Go Reference Go Report Card codecov

A type-safe Go implementation of the Open Charge Point Protocol (OCPP) 1.6 message set, with validated request/response structures for EV charge points (EVSE) and Central Systems (CSMS/backends).

Overview

This library implements OCPP (Open Charge Point Protocol) 1.6 message types with strict validation, following Go best practices and the official OCPP 1.6 specification. It is designed as a foundation for building OCPP-compliant charging station management systems and charge point implementations.

Status: Stable - v1.0.0 (28/28 OCPP 1.6 JSON messages implemented)

- API follows SemVer; see [CHANGELOG](CHANGELOG.md) for release notes.
- Public API is frozen for all v1.x releases; breaking changes will bump
    MAJOR.

Search terms: OCPP 1.6, Open Charge Point Protocol, EVSE, CSMS, charge station backend, Authorize.req, BootNotification, MeterValues, RemoteStart, Charge Point, Central System.

Key Features

  • Type Safety - Constructor pattern with validation (New*() for types, Req()/Conf() for messages)
  • OCPP 1.6 Compliance - Strict adherence to protocol specification
  • OCPP Naming - Uses Req()/Conf() to match OCPP terminology (Authorize.req, Authorize.conf)
  • Immutable Types - Thread-safe by design with value receivers
  • Comprehensive Testing - Unit tests and example tests with high coverage
  • Zero Panics - All errors returned, never panicked
  • Well Documented - Full godoc coverage and examples

Implemented OCPP 1.6 operations

The library covers the full OCPP 1.6 message surface, including:

  • Authorize.req / .conf, BootNotification.req / .conf, Heartbeat.req / .conf
  • StartTransaction.req / .conf, StopTransaction.req / .conf, StatusNotification
  • MeterValues, ClearChargingProfile, SetChargingProfile, TriggerMessage
  • RemoteStartTransaction, RemoteStopTransaction, ChangeAvailability, ChangeConfiguration, GetConfiguration, DataTransfer
  • ReserveNow, CancelReservation, UnlockConnector, Reset, UpdateFirmware, GetDiagnostics, DiagnosticsStatusNotification, FirmwareStatusNotification
  • SendLocalList, GetLocalListVersion, GetCompositeSchedule

Installation

go get github.com/aasanchez/ocpp16messages

Requirements: Go 1.24.6 or later (CI and go.mod aligned)

Project Structure

.
├── types/                      # Core OCPP data types (shared across messages)
│   ├── cistring.go             # CiString20/25/50/255/500 types
│   ├── datetime.go             # RFC3339 DateTime with UTC normalization
│   ├── integer.go              # Validated uint16 Integer type
│   ├── errors.go               # Shared error constants and sentinels
│   ├── authorizationstatus.go  # AuthorizationStatus enum
│   ├── idtoken.go              # IdToken type
│   ├── idtaginfo.go            # IdTagInfo type
│   ├── chargingprofilepurposetype.go  # ChargingProfilePurposeType enum
│   ├── chargingrateunit.go     # ChargingRateUnit enum
│   ├── chargingschedule.go     # ChargingSchedule type
│   ├── chargingscheduleperiod.go  # ChargingSchedulePeriod type
│   ├── metervalue.go           # MeterValue and MeterValueInput types
│   ├── sampledvalue.go         # SampledValue and SampledValueInput types
│   ├── measurand.go            # Measurand enum
│   ├── readingcontext.go       # ReadingContext enum
│   ├── valueformat.go          # ValueFormat enum
│   ├── phase.go                # Phase enum
│   ├── location.go             # Location enum
│   ├── unitofmeasure.go        # UnitOfMeasure enum
│   ├── doc.go                  # Package documentation
│   └── tests/                  # Public API tests (black-box)
├── authorize/                  # Authorize message
├── bootNotification/           # BootNotification message
├── cancelReservation/          # CancelReservation message
├── changeAvailability/         # ChangeAvailability message
├── changeConfiguration/        # ChangeConfiguration message
├── clearCache/                 # ClearCache message
├── clearChargingProfile/       # ClearChargingProfile message
├── dataTransfer/               # DataTransfer message
├── diagnosticsStatusNotification/  # DiagnosticsStatusNotification message
├── firmwareStatusNotification/ # FirmwareStatusNotification message
├── getCompositeSchedule/       # GetCompositeSchedule message
├── getConfiguration/           # GetConfiguration message
├── getDiagnostics/             # GetDiagnostics message
├── getLocalListVersion/        # GetLocalListVersion message
├── heartbeat/                  # Heartbeat message
├── meterValues/                # MeterValues message
├── remoteStartTransaction/     # RemoteStartTransaction message
├── remoteStopTransaction/      # RemoteStopTransaction message
├── reserveNow/                 # ReserveNow message
├── reset/                      # Reset message
├── sendLocalList/              # SendLocalList message
├── setChargingProfile/         # SetChargingProfile message
├── startTransaction/           # StartTransaction message
├── statusNotification/         # StatusNotification message
├── stopTransaction/            # StopTransaction message
├── triggerMessage/             # TriggerMessage message
├── unlockConnector/            # UnlockConnector message
├── updateFirmware/             # UpdateFirmware message
└── SECURITY.md                 # Security policy and vulnerability reporting

Versioning and support

  • Semantic Versioning: API surface follows SemVer starting with v1.0.0.
  • Supported Go versions: >= 1.24 (aligned with go.mod and CI).
  • Changelog: see CHANGELOG for releases and upgrade notes.

Usage

Core Types

The library provides validated OCPP 1.6 data types:

import "github.com/aasanchez/ocpp16messages/types"

// CiString types (case-insensitive, ASCII printable, length-validated)
idTag, err := types.NewCiString20Type("RFID-ABC123")
if err != nil {
    // Handle validation error (length > 20 or non-ASCII chars)
}

// DateTime (RFC3339, must be UTC)
timestamp, err := types.NewDateTime("2025-01-02T15:04:05Z")
if err != nil {
    // Handle parsing error
}

// Integer (validated uint16)
retryCount, err := types.NewInteger(3)
if err != nil {
    // Handle conversion/range error
}

Message Types

Messages use OCPP terminology with Req() for requests and Conf() for responses:

import "github.com/aasanchez/ocpp16messages/authorize"

// Create an Authorize.req message using the ReqInput struct
// Validation happens automatically in the constructor
req, err := authorize.Req(authorize.ReqInput{
    IdTag: "RFID-ABC123",
})
if err != nil {
    // Handle validation error (empty, too long, or invalid characters)
}

// Access the validated IdTag
fmt.Println(req.IdTag.String()) // "RFID-ABC123"

import "github.com/aasanchez/ocpp16messages/clearChargingProfile"

// ClearChargingProfile.req with optional fields
id := 123
req, err := clearChargingProfile.Req(clearChargingProfile.ReqInput{
    Id:                     &id,
    ConnectorId:            nil,
    ChargingProfilePurpose: nil,
    StackLevel:             nil,
})

The ReqMessage type returned by Req() contains validated, typed fields that are immutable and thread-safe.

Development

Prerequisites

  • Go 1.24+
  • golangci-lint
  • staticcheck
  • gci, gofumpt, golines (formatters)

Common Commands (including opt-in suites)

# Install dependencies
go mod tidy

# Run tests
make test                   # Unit tests with coverage
make test-coverage          # Generate HTML coverage report
make test-example           # Run example tests (documentation tests)
make test-all               # Run all test types
make test-race              # Run race detector with -race (opt-in)
make test-fuzz              # Run fuzzers in ./fuzz (short budget, opt-in)
make test-bench             # Run benchmarks in ./benchmark (opt-in)

# Code quality
make lint                   # Run all linters (golangci-lint, go vet, staticcheck)
make format                 # Format code (gci, gofumpt, golines, gofmt)

# Documentation
make pkgsite                # Start local documentation server at http://localhost:8080

Nightly CI (opt-in suites)

  • Nightly workflow runs make test-all, make test-race, make test-fuzz, and make test-bench to guard the opt-in suites.

Test Coverage

Reports are generated in the reports/ directory:

  • reports/coverage.out - Coverage data
  • reports/golangci-lint.txt - Lint results

OCPP 1.6 Compliance

Type System

Core Types (types/)

OCPP Type Go Type Validation
CiString20Type types.CiString20Type Length <= 20, ASCII printable (32-126)
CiString25Type types.CiString25Type Length <= 25, ASCII printable (32-126)
CiString50Type types.CiString50Type Length <= 50, ASCII printable (32-126)
CiString255Type types.CiString255Type Length <= 255, ASCII printable (32-126)
CiString500Type types.CiString500Type Length <= 500, ASCII printable (32-126)
dateTime types.DateTime RFC3339, UTC only
integer types.Integer uint16 (0-65535)

Authorization Types (types/)

OCPP Type Go Type Description
IdToken types.IdToken RFID tag identifier (CiString20)
IdTagInfo types.IdTagInfo Authorization info with status
AuthorizationStatus types.AuthorizationStatus Accepted, Blocked, Expired, etc

Charging Profile Types (types/)

OCPP Type Go Type Description
ChargingProfilePurposeType types.ChargingProfilePurposeType TxDefaultProfile, TxProfile
ChargingRateUnit types.ChargingRateUnit W or A
ChargingSchedule types.ChargingSchedule Schedule with periods
ChargingSchedulePeriod types.ChargingSchedulePeriod Start/limit/phases

Meter Value Types (types/)

OCPP Type Go Type Description
MeterValue types.MeterValue Timestamp + SampledValue array
SampledValue types.SampledValue Value + optional context/format/etc
Measurand types.Measurand Energy, Power, Current, Voltage, etc
ReadingContext types.ReadingContext Sample.Clock, Sample.Periodic, etc
ValueFormat types.ValueFormat Raw or SignedData
Phase types.Phase L1, L2, L3, N, L1-N, L2-N, L3-N
Location types.Location Body, Cable, EV, Inlet, Outlet
UnitOfMeasure types.UnitOfMeasure Wh, kWh, varh, kvarh, W, kW, VA, etc

Message-Specific Types

Package Type Description
bootNotification/types RegistrationStatus Accepted, Pending, Rejected
cancelReservation/types CancelReservationStatus Accepted, Rejected
changeAvailability/types AvailabilityType Inoperative, Operative
changeAvailability/types AvailabilityStatus Accepted, Rejected, Scheduled
changeConfiguration/types ConfigurationStatus Accepted, Rejected, etc
clearCache/types ClearCacheStatus Accepted, Rejected
clearChargingProfile/types ClearChargingProfileStatus Accepted, Unknown
dataTransfer/types DataTransferStatus Accepted, Rejected, etc
diagnosticsStatusNotification DiagnosticsStatus Idle, Uploaded, UploadFailed, etc
firmwareStatusNotification FirmwareStatus Downloaded, Installing, etc
getCompositeSchedule/types GetCompositeScheduleStatus Accepted, Rejected
getConfiguration/types KeyValue Configuration key-value pair
getLocalListVersion/types ListVersionNumber Local list version number
remoteStartTransaction/types RemoteStartTransactionStatus Accepted, Rejected
remoteStopTransaction/types RemoteStopTransactionStatus Accepted, Rejected
reserveNow/types ReservationStatus Accepted, Faulted, Occupied, etc
reset/types ResetType Hard, Soft
reset/types ResetStatus Accepted, Rejected
sendLocalList/types UpdateType Differential, Full
sendLocalList/types UpdateStatus Accepted, Failed, etc
sendLocalList/types AuthorizationData IdTag + IdTagInfo
setChargingProfile/types ChargingProfile Complete charging profile
setChargingProfile/types ChargingProfileKindType Absolute, Recurring, Relative
setChargingProfile/types ChargingProfileStatus Accepted, Rejected, etc
setChargingProfile/types RecurrencyKindType Daily, Weekly
statusNotification/types ChargePointErrorCode ConnectorLockFailure, etc
statusNotification/types ChargePointStatus Available, Charging, Faulted, etc
stopTransaction/types StopReason EmergencyStop, EVDisconnected, etc
triggerMessage/types MessageTrigger BootNotification, Heartbeat, etc
triggerMessage/types TriggerMessageStatus Accepted, Rejected, NotImplemented
unlockConnector/types UnlockStatus Unlocked, UnlockFailed, etc

Message Implementation Status

Message Request Confirmation Package
Authorize Done Done authorize
BootNotification Done Done bootNotification
CancelReservation Done Done cancelReservation
ChangeAvailability Done Done changeAvailability
ChangeConfiguration Done Done changeConfiguration
ClearCache Done Done clearCache
ClearChargingProfile Done Done clearChargingProfile
DataTransfer Done Done dataTransfer
DiagnosticsStatusNotification Done Done diagnosticsStatusNotification
FirmwareStatusNotification Done Done firmwareStatusNotification
GetCompositeSchedule Done Done getCompositeSchedule
GetConfiguration Done Done getConfiguration
GetDiagnostics Done Done getDiagnostics
GetLocalListVersion Done Done getLocalListVersion
Heartbeat Done Done heartbeat
MeterValues Done Done meterValues
RemoteStartTransaction Done Done remoteStartTransaction
RemoteStopTransaction Done Done remoteStopTransaction
ReserveNow Done Done reserveNow
Reset Done Done reset
SendLocalList Done Done sendLocalList
SetChargingProfile Done Done setChargingProfile
StartTransaction Done Done startTransaction
StatusNotification Done Done statusNotification
StopTransaction Done Done stopTransaction
TriggerMessage Done Done triggerMessage
UnlockConnector Done Done unlockConnector
UpdateFirmware Done Done updateFirmware

Design Principles

  1. OCPP Naming - Messages use Req()/Conf() to match OCPP terminology
  2. Constructor Validation - All types require constructors that validate input
  3. Input Struct Pattern - Raw values passed via ReqInput/ConfInput structs, validated automatically
  4. Immutability - Types use private fields and value receivers
  5. Error Accumulation - Constructors report all validation errors at once using errors.Join()
  6. Error Wrapping - Context preserved via fmt.Errorf with %w
  7. No Panics - Library never panics; all errors returned
  8. Thread Safety - Designed for safe concurrent use
  9. Go Conventions - Follows Effective Go guidelines

Security

Security is critical for EV charging infrastructure. This library:

  • Validates all input at construction time
  • Prevents injection attacks via strict type constraints
  • Provides clear error messages without exposing internals
  • Uses immutable types to prevent tampering
  • Is designed for safe concurrent use

Reporting vulnerabilities: See SECURITY.md for our security policy and responsible disclosure process.

Contributing

We welcome contributions! Please:

  1. Follow Go best practices and Effective Go
  2. Add tests for all new functionality
  3. Ensure make test-all passes
  4. Run make lint and make format before committing
  5. Document all exported types and functions
  6. Follow the existing code style

See CLAUDE.md for detailed development guidelines.

License

See LICENSE

Resources

Packages

No packages published

Contributors 2

  •  
  •