This is the core of the driver. Below are typical mapping rules.
| IEC 104 Concept | OCPP 1.6 / 2.0.1 Mapping |
|----------------|---------------------------|
| M_ME_TF_1 (measured value, scaled, with timestamp) | MeterValues.req (active import energy) → convert to instantaneous power (kW) |
| C_CS_NA_1 (setpoint command, normalized) | SetChargingProfile.req – limit power (kW) or current (A) |
| C_CI_NA_1 (interrogation command) | GetCompositeSchedule.req (OCPP 2.0.1) or cache state |
| M_SP_NA_1 (single point status – e.g., circuit breaker) | StatusNotification.req (connector status) |
| C_SE_NB_1 (select-execute for protection) | Not directly in OCPP; implement as precondition for large limit changes |
| Spontaneous events (e.g., overload) | NotifyEvent.req (OCPP 2.0.1) or custom vendor extensions |
Not all drivers are created equal. When sourcing a driver for your 809-based hardware, look for these specifications: ocpp-809 driver
Two days before launch, we ran a load test. The driver crashed after 400 transactions.
The legacy chargers were sending MeterValues every second. OCPP 1.5 allowed this. OCPP 2.0.1 expects a structured TransactionEvent with specific data types. This is the core of the driver
The Series 4 units were sending power as a string. "value": "14.4kW".
The OCPP 2.0.1 schema demanded a float. "value": 14.4.
The driver’s strict unmarshalling was panicking. I spent a night writing a "Sanitizer" middleware. Companies like Siemens or Advantech sell "Protocol Gateways
// Pseudo-logic for the Sanitizer
func CleanLegacyPower(input string) float64
// Strip non-numeric characters
s := strings.ReplaceAll(input, "kW", "")
val, err := strconv.ParseFloat(s, 64)
if err != nil
return 0.0 // Fail safely, log error
return val
Companies like Siemens or Advantech sell "Protocol Gateways." Their "OCPP-809 Driver Package" allows a PLC (Programmable Logic Controller) to act as an OCPP server, converting industrial serial data into EV roaming protocols.
Website security powered by MilesWeb