Skip to main content

EVBox protocol documentation

Project | Article by Maarten Tromp | Published , updated | 4148 words.

This document describes the Max communications protocol, which is used internally between EVBox modules in G2, G3, and G4 HomeLine, BusinessLine, and PublicLine chargers.

In this article:

Charger

All information in this documentation has been gathered from tests on my own chargers, combined with any material I could find online. Background information on the project can be found on the project page.

The charger used for most of this documentation is an EVBox HomeLine G3, single-phase, 32 A, 7.4 kW unit. ChargeBox model: 471011.3, serial number 1917911. ChargePoint model: EU 471046.2, serial number 1919129. Other markings on the unit include: modem number EVB-P1919129, connector 1917911, serial number B19239404, article H1320-50082-EN, registration number EVB-P1919129, and production date 13/06/2019. I have since obtained a few more chargers.

Terminology

There are a few terms used by EVBox that might not be immediately clear.

ChargeBox, or CB. This is a single wall-mounted charger or charger pole, not including the communications module (if any). A charger with two outputs contains two CBs.

ChargePoint, or CP. Communications or management module.

ChargeStation, or CS. This is an entire site, including the CP and CB(s).

ChargeStation Tool. A software and USB adapter bundle for configuring ChargeStations. I have reverse engineered the EVBox ChargeStation Tool to work with a generic adapter.

Models and modules

Generation 2 through 4 hardware and software are developed and produced by Small Processor Systems. Industrial design by Rob Wolkers. Later generations are developed from scratch in-house and fall outside the scope of this documentation.

G2 (Generation 2) CB modules can be identified by the blue 3-pin LED connector.

G3 modules look similar but use a 4-pin connector. G2 and G3 hardware is identical across the HomeLine, BusinessLine, and PublicLine product ranges. A stand-alone CB module also exists. It does not include a CP module, or the connectors for one, and runs different firmware. Converting from stand-alone to managed is not possible.

G4 (Elvi) combines CB and CP modules onto a single circuit board. There is a version with integrated metering and a cellular modem, as well as a version without. I assume the same protocol is used.

Physical layer

The physical layer deals with byte-by-byte delivery over a physical medium.

Mechanical

Connectors are pluggable terminal blocks, 4 pins, by Phoenix Contact.

CBs have a male MSTBVA 2,5/4-G-5,08 1×4 PCB header.

CPs have a female ICV 2,5/4-G-5,08 1×4 PCB header.

Electrical

pinfunction
1GND
2RS-485 B (inverting)
3RS-485 A (non-inverting)
4+12 V

CP and CB communicate over an RS-485 bus. The bus is terminated on the CP (120 Ω), but not biassed. There is no termination on the CB, but on short distances this should not be a problem, and on a longer bus termination can be added at the last CB. There is no bias. The bus operates in multi-master mode, so each module can transmit messages on the bus.

The RS-485 bus is available on pin 28/29, the black 2-pin connector, and pin 34/35, the big green 4-pin connector. Note that A and B are swapped in most EVBox documentation. Pin 28 = pin 34 = A, pin 29 = pin 35 = B.

Serial baud rate is 38400 bps, 8N1, half-duplex.

    Notes:
  • EVBox supports a maximum of 20 CBs plus 1 CP module per bus.
  • Maximum bus length is 1200 m, using shielded twisted-pair cabling.

Network layer

The network layer deals with addressing packets across the data link layer.

A packet (ASCII-decoded frame payload) consists of a destination address, source address, and application data.

Packet encoding

The entire packet is a string, containing only numbers and capital letters.

Addresses are hex encoded. Example: string "3A" → address 0x3A (hex) = 58 (decimal).

Destination address

The first 2 characters (1 data byte) of a packet are the packet destination address.

Value: hex pair, resulting in a 1-byte destination address.

Source address

The next 2 characters (1 data byte) are the packet source address.

Value: hex pair, resulting in a 1-byte source address.

Application data

The remaining characters are application data.

Value: ASCII characters. This is described in more detail in the application layer.

Addressing

Every module on the bus has a unique address.

address (hex)namedetails
00new CB(s)charger module(s) before address assignment
01-14CB(s)charger module(s) with address, maximum 20 (dec)
70unknownunknown, observed during firmware update
80CPChargePoint module (modem)
A0SmartGrid moduleexplained in Max protocol specification
BCbroadcast
FDChargeStationChargeStation Tool for configuration and management

Packet example

packet (hex)800121
functiondestinationsourceapplication data
    Notes:
  • Packets with an invalid or unused address are ignored.
  • Observed value 0x00 at the end of command 34 data on a specific CP.
  • Broadcast is only used for commands that do not require a response.
  • There are no checksum, parity, sequence numbering, or data length fields at the network layer.

Application layer

The application layer is an abstraction layer that deals with process-to-process communication and depends on the network layer for transport.

Application data consists of a command and parameters.

Command

The first 2 characters (1 data byte) of application data are the command. Some documentation refers to these as "action".

Value: hex pair, resulting in a 1-byte command.

Similar commands are grouped; indexes are 1-based. Commands (hex) 11–1F are initialization, 21–2F are initiated by the CB, 31–3F are initiated by the CP, 41–4F are hardware configuration, 61–6F are power management, and E1–FF mostly deal with ChargeStation communication.

Parameters

The remaining zero or more characters are parameters. Protocol Max documentation refers to these as "data".

Value: variable length and encoding, depending on the command. Most parameters are encoded as hex pairs, but a few are strings. Each command has a fixed number of parameters, with fixed position, length, and encoding. The only way to know the correct parameter type and length is to know the protocol. Some string parameters are preceded by a used length.

The first 2 or 4 bytes are usually state. Some universal states are: AA00 → ack, 0055 → nack, 01 → success. Other states might exist, depending on the command.

All commands require all parameters to be present; unused or short parameters are padded with zeroes.

Application data procedures

Most communication follows the form: request → response, but there are a few exceptions.

Response messages have the same command byte as the request message, but (usually) different parameters. There is no way of knowing if an individual message is a request or response without knowing the protocol. If multiple messages with the same command byte are sent, only the last one can be responded to.

When a response is required but not received, the request is repeated every 2 seconds.

The first thing a CB does after boot is request an address from the CP. All CBs start at address 0x00 and send command 11 requests to the CP, containing their serial number and firmware version. The CP then broadcasts a response containing the CB serial number and assigned bus address. From that point, normal communication can start.

All decision-making is done in the CP.

Application data example

This is an example of command 23 (start metering) request parameters, sent from CB to CP. The parameters are already ASCII-decoded.

parameters0E0123456789ABCDEF00000000FF30F2
functionstring lengthcharge card numbermeter value * 1000
typehexstringhex
value140123456789ABCD16724.21

The first 2 characters are the hex-encoded length of the charge card number: 0E, resulting in a length of 14 (dec) characters.

The next 22 characters are a string, containing the charge card number value, padded with zeroes: 0123456789ABCD00000000, resulting in the card number 0123456789ABCD.

Last 8 characters are hex-encoded meter value * 1000: 00FF30F2, resulting in a raw value of 1672421 (dec), and a meter value of 16724.21 kWh.

    Notes:
  • Longest observed parameter length is 126 bytes.
  • All data is big-endian.
  • Parameter length is not included in the message. Nor is this validated on reception against frame length. If a command requires nn bytes of data, it will read nn bytes, even if it falls outside the payload area of the frame.
  • There are some redundant parameters between commands. e.g. Several distinct commands all expect mains voltage to be returned.
  • Message length can change between firmware versions. I assume CP and CB must run the same version in order to understand each other properly.
  • Responses are usually sent to predetermined addresses, regardless of request source.
  • If 3 consecutive heartbeats are missed, the CB reboots.

Commands

This is a list of all commands that were observed or found by fuzzing.

Command 11: CB register

Request: sent by CB (from address 00) to CP, 15 bytes.

byteparameterlengthencodingdetails
0-6CB serial number7 bytesstring
7-10firmware version4 bytesstring
11-12unknown2 bytesunknown
13-14unknown, could be hardware generation2 bytesunknown

Response: broadcast by CP, 11 bytes.

byteparameterlengthencodingdetails
0-6CB serial number7 bytesstring
7-8new address2 byteshex
9-10unknown, could be protocol version2 byteshex

Example:

src: 00 (new)
dst: 80 (CP)
cmd: 11 request (register), length: 15
dat: 1917911 0125 00 03 (serial number: 1917911, firmware version: 0125, hardware generation: 03)
src: 80 (CP) dst: BC (broadcast) cmd: 11 response (register), length: 11 dat: 1917911 01 03 (serial number: 1917911, address: 01, gen: 03)
    Notes:
  • Requesting to register an address is the first thing a CB does after boot.
  • No other messages are accepted by the CB until an address is assigned. Exception to ths is command 42 (set address), whch is always accepted.
  • I assume all CBs initialize at address 00.
  • Request without parameters results in CP sending a response with invalid checksum and parity, followed by command 13 (get meter info) request.
  • Response does not need to be broadcast. Direct addressing can be used as well.
  • No Response parameters can be left out, but setting last 2 bytes to 00 is accepted by CB.
  • The only observed firmware version is 0125, the only observed hardware generation is 03

Command 13: Get meter info

Request: sent by CP to CB, 0 bytes.

Response: 64 bytes on success, 4 bytes on failure.

byteparameterlengthencodingdetails
0-3meter present4 byteshex
4-5version number length2 byteshex
6-21version number value16 bytesstring
22-23model name length2 byteshex
24-39model name value16 bytesstring
40-55serial number16 bytesstring
56-59mains frequency * 1004 byteshex
60-63unknown

Example:

dst: 01 (charger)
src: 80 (CP)
cmd: 13 request (get meter info), length: 0
dst: 80 (CP) src: 01 (charger) cmd: 13 response (get meter info), length: 64 dat: AA00 0221 0000 0000 0000 000B ALE3 D5FS 10C0 0000 0000 4142 4546 5436 1388 0001 (version number: 21, model name: ALE3D5FS10C, serial number: 0000414245465436, mains frequency: 50.0Hz)
dst: 80 (CP) src: 01 (charger) cmd: 13 response (get meter info), length: 64 dat: AA00 0000 0000 0000 0000 0004 PULS 0000 0000 0000 0000 0000 0000 0000 0000 1400 (version number: , model name: PULS, serial number: 0000000000000000, mains frequency: 0.0Hz)
    Notes:
  • When a RS-485 power meter is configured but not present, CB returns nack only.
  • Value 0055 (nack) is treated as not received, so command 13 request is repeated.
  • Not sure if version number is for hardware or firmware.
  • When a pulse power meter is present, CB returns model number "PULS" (Dutch for pulse).

Command 18: Request message

Request: sent by CP to CB, 2 bytes.

byteparameterlengthencodingdetails
0-1type2 byteshex
typerequest
01command 21 heartbeat
02command 26 state update
03command 26 state update
04nothing

Response: none.

Example:

dst: 01 (charger)
src: 80 (CP)
cmd: 18 request (request message), length: 2
dat: 02 ()
dst: 80 (CP) src: 01 (charger) cmd: 26 request (charger update), length: 132 dat: 0215 0000 0000 0012 AD00 FF30 F200 000A 2EB8 2F03 F078 0008 0008 00DC 6400 0000 0000 00E2 0000 0000 0000 0000 0000 0000 03E8 0000 0000 0000 0000 0000 0000 0384 1388 (charger: idle, meter value: 16724.21kWh, temperature: 22.0°C, session: 0, voltage: 226/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz)
    Notes:
  • When no CB is registered at the CP, request is sent as broadcast. Otherwise direct addressing is used.
  • The only observed value is 02. Other values are found by fuzzing.

Command 1B: Connection state changed

Request: sent by CP as broadcast, 10 bytes.

Response: none.

Example:

dst: BC (broadcast)
src: 80 (CP)
cmd: 1B request (connection state changed), length: 10
dat: 0000 0384 00 ()
dst: 80 (CP) src: 01 (charger) cmd: 26 request (charger state update), length: 132 dat: 0215 0000 0000 0012 B000 FF30 F200 000A 2EB0 2F04 F078 0008 0008 0104 6400 0000 0000 00E2 0000 0000 0000 0000 0000 0000 03E8 0000 0000 0000 0000 0000 0000 0384 1388 (charger: idle, meter value: 16724.21kWh, temperature: 26.0°C, session: 0, voltage: 226/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz)
    Notes:
  • Request is sent once CP has established backend connection.
  • Request without parameters is accepted by CB.
  • Request is followed by CB sending command 26 CB state update request.

Command 1C: LED ring enable

Request: sent by CP as broadcast, 2 bytes.

byteparameterlengthencoding
0-1state2 byteshex
statedescription
00disable
01enable

Response: none

Example:

CP -> broadcast: led ring enable: state: enable
src: 80, dst: BC, cmd: 1C, data: 01, length: 2
(led trurns green)

CP -> broadcast: led ring enable: state: disable src: 80, dst: BC, cmd: 1C, data: 00, length: 2 (led trurns off)
    Notes:
  • LED ring dimming is possible using command 34 set configuration.

Command 1E: Restart registration

Request: sent by CP as broadcast, 0 bytes.

Response: none.

Example:

dst: BC (broadcast)
src: 80 (CP)
cmd: 1E request (restart registration), length: 0
dst: 80 (CP) src: 00 (new) cmd: 11 request (register), length: 15 dat: 1917911 0125 00 03 (serial number: 1917911, firmware version: 0125, hardware generation: 03)
    Notes:
  • Request results in CB setting it's address to 00 and sending an command 11 register request. All settings are preserved.
  • Request is the first message CP sends after boot.
  • Request does not need to be broadcast. Direct addressing can be used as well.

Command 21: Heartbeat

Request: sent by CB, 0 bytes.

Response: 0 bytes.

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: 21 request (heartbeat), length: 0
dst: 01 (charger) src: 80 (CP) cmd: 21 response (heartbeat), length: 0
    Notes:
  • Request is sent at 16 minute interval.

Command 22: Authorize card

Request: sent by CB, 26 bytes.

byteparameterlengthencodingdetails
0-1state2 byteshex
2-3card number length2 byteshex
4-25card number value22 bytesstring

Response: 30 bytes.

byteparameterlengthencodingdetails
0-1state2 byteshex
2-3card number length2 byteshex
4-25card number value22 bytesstring
26-29unknown, could be current limit
statedescription
00request
01access granted
03not connected to backend
12access denied
1Dinvalid card number

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: 22 request (card authentication request), length: 26
dat: 000E xxxx xxxx xxxx xx00 0000 00 (authentication request, card number: xxxxxxxxxxxxxx)
dat: 0008 0000 00AS 0000 0000 0000 00 (authentication request, auto start)
dst: 01 (charger) src: 80 (CP) cmd: 22 response (card authentication request), length: 30 dat: 010E xxxx xxxx xxxx xx00 0000 00FF FF (access granted, card number: xxxxxxxxxxxxxx) dat: 120E xxxx xxxx xxxx xx00 0000 00FF FF (access denied, card number: xxxxxxxxxxxxxx) dat: 0300 0000 0000 0000 0000 0000 00FF FF (not connected to backend)
    Notes:
  • Request is sent after scanning RFID charge card or, when auto start is enabled, after plugging in EV.
  • Auto start uses "card number" 000000AS.
  • Response is followed by CB sending command 6A charging state.

Command 23: Metering start

Request: sent by CB, 32 bytes.

byteparameterlengthencodingdetails
0-1card number length2 byteshex
2-23card number value22 bytesstring
24-31meter value * 10008 bytesstring

Response: 18 bytes.

byteparameterlengthencodingdetails
0-1state2 byteshex
2-9session id8 byteshex
10-17timestamp8 byteshex

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: 23 request (metering start), length: 32
dat: 0Exx xxxx xxxx xxxx 0000 0000 00FF 30F2 (card number: xxxxxxxxxxxxx, meter value: 16724.21kWh)
dst: 01 (charger) src: 80 (CP) cmd: 23 response (metering start), length: 18 dat: 0100 0000 002E 7C41 F5 (session: 0, timestamp: 2024-09-17 13:34:45)
# a few seconds later
dst: 01 (charger) src: 80 (CP) cmd: 23 response (metering start), length: 18 dat: 0100 C079 EA2E 7C41 F9 (session: 12614122, timestamp: 2024-09-17 13:34:49)
    Notes:
  • Request follows on CP sending command 6B start charging.
  • Request without parameters is accepted by CP.
  • Request gets two responses. The first response has Session id 0, in the second response it has a value.
  • Omitting the second response is accepted by CB.
  • Response is followed by CB sending a command 26 state update request.

Command 24: Metering end

Request: sent by CB, 50 bytes.

byteparameterlengthencodingdetails
0-1card number length2 byteshex
2-23card number value22 bytesstring
24-31meter value * 10008 byteshex
32-39session id8 byteshex
40-41state2 byteshex
42-49timestamp8 byteshex

Response: 2 bytes.

byteparameterlengthencodingdetails
0-1state2 byteshex

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: 24 request (metering end), length: 50
dat: 0Exx xxxx xxxx xxxx 0000 0000 00FF 3156 00C0 79EA 392E 7C44 49 (card number: xxxxxxxxxxxxxx, meter value: 16724.31kWh, session: 12614122, timestamp: 2024-09-17 13:44:41)
dst: 01 (charger) src: 80 (CP) cmd: 24 response (metering end), length: 2 dat: 01 ()
    Notes:
  • Request is sent after unplugging EV.
  • Request is sent after stopping session from CB (Harm Otten)
  • Request without parameters is accepted by CP.
  • Response without parameters is accepted by CB.
  • Response results in CB sending command 6A charging state.

Command 26: CB state update

Request: sent by CB, 132 bytes.

byteparameterlengthencodingdetails
0-1state2 byteshex
2-5unknown
6-7is charging2 byteshex
8-9led colour2 byteshex
10-11is locked4 byteshex
12-13cable max current2 bytesstring
14-17unknown
18-25meter value * 10008 byteshex
26-51unknown
52-55chassis temperature * 104 byteshex
56-57unknown
58-65session id8 byteshex
66-67unknown
68-71voltage phase 14 byteshex
72-75voltage phase 24 byteshex
76-79voltage phase 34 byteshex
80-83current phase 1 * 1004 byteshex
84-87current phase 2 * 1004 byteshex
88-91current phase 3 * 1004 byteshex
92-95socket temperature * 104 byteshex
96-99power factor phase 1 * 10004 byteshex
100-103power factor phase 2 * 10004 byteshex
104-107power factor phase 3 * 10004 byteshex
108-123unknown
124-127current limit * 104 byteshex
128-131mains frequency * 1004 byteshex
statedescription
02available
0Aerror
47charging cable connected
48charging
4Aready
4Bfinished (EV still plugged in)

State order: 02 (available) → 47 (charging cable connected) → 4A (ready) → 48 (charging) → 4A (ready) → 4B (finished) → 02 (available)

led colourdescription
0off
1green
2red (guess)
3yellow
4blue
5value observed, colour unknown

Response: 16 bytes.

byteparameterlengthencodingdetails
0-7session id8 byteshex
8-15timestamp8 byteshex

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: 26 request (charger state update), length: 132
dat: 4A15 0000 0301 141F 7200 A417 B200 000B 2E70 217C 2F16 0000 0CD8 00DC 0A00 0000 0000 00EF 0000 0000 0000 0000 0000 0014 03E8 03E8 03E8 0000 0000 0000 0000 003C 1388 (state: ready, is charging: 0, led colour: yellow, is locked: 1, cable current: 20A, meter value: 10753.97kWh, temperature: 22.0/20°C, session: 0, voltage: 239/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/1.0/1.0, current limit: 6.0A, frequency: 50.0Hz)
dst: 01 (charger) src: 80 (CP) cmd: 26 response (charger state update), length: 16 dat: 0000 0479 2F92 7302 (session: 1145, timestamp: 2025-04-16 13:54:10)
    Notes:
  • Response timestamp is set to 0 when CP is not connected to backend.
  • Response with session set to 0 is accepted by CB.
  • There does not seem to be a difference between the command 26 message sent after EV plugged in, but not authenticated yet, and authenticated, but not plugged in yet.
  • During charging session (from metering start to metering end) command 26 update is sent at a configurable interval.
  • Led status could be RGB.

Command 2A: Unknown

Request: sent by CB.

Response:

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: 2A request (unknown), length: 0
dst: 02 (unknown) src: 80 (CP) cmd: 2A response (unknown), length: 0
    Notes:

Command 31: Session remote start

Request: sent by CP, from back office, 24 bytes.

byteparameterlengthencodingdetails
0-1card number length2 byteshex
2-23card number value22 bytesstring

Response: 2 bytes.

byteparameterlengthencodingdetails
0-1state2 bytehex
statedescription
01success
23failed

Example:

dst: 01 (charger)
src: 80 (CP)
cmd: 31 request (remote start), length: 24
dat: 0Exx xxxx xxxx xxxx 0000 0000 (card number: xxxxxxxxxxxxxx)
 
dst: 80 (CP)
src: 01 (charger)
cmd: 31 response (remote start), length: 2
dat: 23 ()
    Notes:
  • Mentioned by Harm Otten

Command 32: Session remote stop

Request: sent by CP, from back office, 8 bytes.

byteparameterlengthencodingdetails
0-7session id8 byteshex

Response: 2 bytes.

byteparameterlengthencodingdetails
0-1state2 byteshex
statedescription
01success
23failed (already stopped)
    Notes:
  • Mentioned by Harm Otten

Command 33: Get CB configuration

Request: sent by CP, 0 bytes.

Response: 74 bytes (firmware 0125), 78 bytes (firmware 0125), 84 bytes (firmware 0140)

byteparameterlengthencodingdetails
0-19unknown
20-23meter update interval (seconds)8 byteshex
24-29unknown
30-31meter type2 byteshex
32-35unknown
36-37led brightness (percent)2 byteshex
38-53unknown
54-55enable auto start2 byteshex
56-65unknown
66-67allow remote start2 byteshex
68-endunknown
meter typedescription
00pulse
01serial

Example:

dst: 01 (charger)
src: 80 (CP)
cmd: 33 request (get configuration), length: 0
dst: 80 (CP) src: 01 (charger) cmd: 33 response (get configuration), length: 74 dat: 0000 003C 0000 0384 0000 0384 0300 0001 0100 1E01 0000 0000 0000 0000 0000 0000 0000 03E8 01 (led brightness: 30%, command 26 interval: 900s, auto start: 0, remote start: 0)
src: 01 (charger) dst: 80 (CP) cmd: 33 response (get configuration) dat: 0000 003C 0000 0384 0000 0384 0000 0501 0101 64FF 0000 0000 0000 0000 0001 0000 0000 03E8 0100 00 (led brightness: 100%, meter update interval: 900s, meter type: serial, auto start: 0, remote start: 0), length: 78
CP <- CB3: get configuration: led brightness: 30%, meter update interval: 900s, meter type: serial, auto start: 0, remote start: 0 src: 03, dst: 80, cmd: 33, data: 0000 003C 0000 0384 0000 0384 0300 0001 0100 1EFF 0000 0000 0000 0000 0001 0000 0000 03E8 0100 0000 0000, length: 84
    Notes:

Command 34: Set CB configuration

Request: sent by CP, 86 (firmware 125), 88 bytes, 94 bytes (firmware 140)

byteparameterlengthencodingdetails
0-7mask8 byteshex
8-9led brightness (percent)2 byteshex
10-15unknown
16-17meter type8 byteshex
18-37unknown
38-39enable auto start2 byteshex
40-57unknown
58-65meter update interval (seconds)8 byteshex
66-73unknown
74-75allow remote start2 byteshex
76-endunknown
meter typedescription
00pulse
01serial

Response: 4 bytes.

byteparameterlengthencodingdetails
0-3ack4 byteshex

Example:

dst: 01 (charger)
src: 80 (CP)
cmd: 34 request (set configuration), length: 86
dat: 03A3 F781 1E03 0000 0101 0001 0000 0000 0000 0000 0000 0000 3C00 0003 8400 0003 8400 0000 0000 03E8 0100 00 (led brightness: 30%, command 26 interval: 900s, auto start: 0, remote start: 0)
dst: 80 (CP) src: 01 (charger) cmd: 34 response (set configuration), length: 4 dat: AA00 (ack)
    Notes:
  • I assume the mask is to indicate which of the many values have been changed, and which have not.
  • When auto start is enabled, the RFID reader is disabled.
  • Values that would probably be in there are: default charging delay, amount of connectors, led idle state, led idle time on, led idle time off, external current loss, smart charge pause, auto stop when offline, EV reconnect charge, and some others.
  • Response without parameters results in CP sending a command 33 request.
  • Observed null characters at end of data.
  • Switching between seral meter and pulse meter requires a reboot to take effect.

Command 35: Reboot CB

Request: sent by ChargeStation as broadcast, 2 bytes.

byteparameterlengthencodingdetails
0-1unknown2 byteshex

Observed data values are 0C, 52 and 3F.

Response: none.

Example:

src: FD (ChargeStation)
dst: BC (broadcast)
cmd: 35 (reboot)
typ: request
dat: 0C (), length: 2
    Notes:
  • Ignored by CP.

Command 36: Unknown

Request: sent by CP, 0 bytes.

Response: 2 bytes.

Example:

dst: 01 (charger)
src: 80 (CP)
cmd: 36 request (unknown 36), length: 0
dst: 80 (CP) src: 01 (charger) cmd: 36 response (unknown 36), length: 2 dat: 23 ()
dst: 80 (CP) src: 01 (charger) cmd: 26 request (charger state update), length: 132 dat: 0215 0000 0100 0012 A000 FF75 4400 000A 2EB8 2F02 F078 0008 0008 00DC 6400 0000 0000 00E4 0000 0000 0000 0000 0000 0000 03E8 0000 0000 0000 0000 0000 0000 0384 1388 (charger: idle, meter value: 16741.7kWh, temperature: 22.0°C, session: 0, voltage: 228/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz)
    Notes:
  • Response is followed by CB sending a command 26 state update.

Command 37: Unknown

Request: sent by CP, 0 bytes.

Response: 2 bytes.

Example:

dst: 01 (charger)
src: 80 (CP)
cmd: 37 request (unknown 37), length: 0
dst: 80 (CP) src: 01 (charger) cmd: 37 response (unknown 37), length: 2 dat: 16 (unknown)
    Notes:

Command 38: Unknown

Request: sent by CP, 0 bytes.

Response: 2 bytes.

Example:

dst: 01 (charger)
src: 80 (CP)
cmd: 38 unknown (unknown), length: 0
dst: 80 (CP) src: 01 (charger) cmd: 38 unknown (unknown), length: 2 dat: 02 (unknown)
    Notes:

Command 41: Unknown

Request: sent by both CP and CB, 0 bytes.

Response: either 54 or 2 bytes.

Example sent to CB:

dst: 01 (charger)
src: 80 (CP)
cmd: 41 unknown (unknown 41), length: 0
dst: 80 (CP) src: 01 (charger) cmd: 41 unknown (unknown 41), length: 54 dat: 0100 0008 0008 2EBA 129A 08FC F87F 00BE 0375 4430 4203 3030 3032 45 () dat: 0100 0008 0008 2EB8 12A0 2F03 F078 00DC 0375 4430 4203 3237 4503 30 ()

Example sent to CP:

dst: 80 (CP)
src: 01 (charger)
cmd: 41 unknown (unknown), length: 0
dst: FD (ChargeStation) src: 80 (CP) cmd: 41 unknown (unknown), length: 2 dat: 37 ()
    Notes:
  • This is probably another system info / hardware info command.
  • If request is sent by CB, CP sends request to ChargeStation.

Command 42: Set CB serial number

Request: sent by CP, 7 bytes.

byteparameterlengthencodingdetails
0-6CB serial number7 bytesstring

Response: 7 bytes, copy of request.

Example:

dst: BC (broadcast)
src: 80 (CP)
cmd: 42 request (set serial number), length: 7
dat: 1917 911 (serial number: 1917911)
dst: 80 (CP) src: 00 (new) cmd: 42 response (set serial number), length: 7 dat: 1917 911 (serial number: 1917911)
    Notes:
  • Request without parameters is accepted by CB. This results in setting serial number 2F0F\x0300 (which is request checksum, parity, EoF, padded with 0).
  • Request can be sent during address negotiation.
  • Response is sent from address 00, but CB keeps its address.
  • The new serial number is written to permanent storage.

Command 43: Get CB info

Request: sent by ChargeStation, 0 bytes.

Response: 18 bytes (firmware 125), 20 (firmware 140).

byteparameterlengthencodingdetails
0-1hardware generation2 byteshex
2-5firmware version4 byteshex
6-endunknown

Example:

dst: 01 (charger)
src: 80 (CP)
cmd: 43 request (hardware info), length: 0
dst: FD (ChargeStation) src: 01 (charger) cmd: 43 response (hardware info), length: 18 dat: 03 0125 01 004C 0D04 2C (hardware generation: 03, firmware version: 0125)
    Notes:
  • Remaining values might include number of phases, type of relay, type of cable, etc.

Command 65: Set meter update interval

Request: sent by CB, 4 bytes.

byteparameterlengthencodingdetails
0-3interval4 byteshex

Response: none

Example:

dst: 01 (charger)
src: 80 (CP)
cmd: 65 request (set meter update interval), length: 4
dat: 003C (interval: 60s)
dst: 80 (CP) src: 01 (charger) cmd: 66 request (meter value), length: 44 dat: 00E6 0000 0000 0000 0000 0000 03E8 0000 0000 00FF 7544 (voltage: 230/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, meter value: 16741.7kWh)
    Notes:
  • Value 0 disables update interval.

Command 66: Push meter value

Request: sent by CB, 44 bytes.

byteparameterlengthencodingdetails
0-3voltage phase 14 byteshex
4-7voltage phase 24 byteshex
8-11voltage phase 34 byteshex
12-15current phase 1 * 1004 byteshex
16-19current phase 2 * 1004 byteshex
20-23current phase 3 * 1004 byteshex
24-27power factor phase 1 * 10004 byteshex
28-31power factor phase 2 * 10004 byteshex
32-35power factor phase 3 * 10004 byteshex
36-43meter value * 10008 byteshex

Response: 0 bytes.

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: 66 request (meter value), length: 44
dat: 00E6 0000 0000 0000 0000 0000 03E8 0000 0000 00FF 7544 (voltage: 230/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, meter value: 16741.7kWh)
dst: 01 (charger) src: 80 (CP) cmd: 66 response (meter value), length: 0
    Notes:

Command 68: Charging state

Request: sent by SmartGrid.

    Notes:
  • Explained in Max protocol specification.

Command 69: Charging state

Request: sent by SmartGrid.

    Notes:
  • Explained in Max protocol specification.

Command 6A: Charging state

Request: sent by CB, 4 bytes.

byteparameterlengthencodingdetails
0-1state2 byteshex
2-3always same2 byteshex
statedescription
07unknown, mentioned by Harm Otten
20unknown, observed
28unknown, observed
2Funknown, observed
80unplugged
81charging
A0available
A7ready
C1finished
E7failed

State order: A0 (available) → A7 (ready) → 81 (charging) → C1 (finished) → 80 (unplugged) → A0 (available)

Response: 4 bytes.

byteparameterlengthencodingdetails
0-3ack4 byteshex

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: 6A request (charging mode), length: 4
dat: A03C (state: charger idle)
dst: 01 (charger) src: 80 (CP) cmd: 6A response (charging mode), length: 4 dat: AA00 (ack)
    Notes:
  • Request without parameters is accepted by CP.

Command 6B: Set current limit

Request: sent by CP, 18 bytes.

byteparameterlengthencodingdetails
0-1always same2 byteshex
2-5minimum current * 104 byteshex
6-9current limit phase 1 * 104 byteshex
10-13current limit phase 2 * 104 byteshex
14-17current limit phase 3 * 104 byteshex

Response: 0 bytes.

Example:

dst: 01 (charger)
src: 80 (CP)
cmd: 6B request (set current limit), length: 18
dat: 0100 3C00 A000 A000 A0 (current min: 6.0A, current limit: 16.0/16.0/16.0A)
dst: 80 (CP) src: 01 (charger) cmd: 6B response (set current limit), length: 0
    Notes:
  • Request is sent when charging has started or ended.
  • Request follows on command 6A charging state.
  • Response is followed by CB sending a command 23 metering start request.
  • This command also acts as "start charging".
  • There might be 3 current limits for 3 phases, but command 23 only returns a single one.
  • Request without parameters is accepted by CB.

Command 6C: Unknown

Request: sent by CP.

Response: 2 bytes.

Example:

dst: 01 (charger)
src: 80 (CP)
cmd: 6C request (unknown 6C), length: 0
dst: 80 (CP) src: 01 (charger) cmd: 6C response (unknown 6C), length: 2 dat: 23 ()
    Notes:

Command E0: Unknown

Request: broadcast by ChargeStation, 2 bytes.

byteparameterlengthencodingdetails
0-1data2 byteshex

Observed data values are 80.

Response: none

Example:

CP -> broadcast: unknown E0: 
src: 80, dst: BC, cmd: E0, data: 80, length: 2
    Notes:

Command E1: Unknown

Request: sent by CP to address 70, 4 bytes.

Response: none.

Example:

CP -> unknown 70: unknown E1: ack
src: 80, dst: 70, cmd: E1, data: AA00, length: 4

Command E2: Verify firmware

Request: sent by address 70 to CP, 4 bytes.

byteparameterlengthencodingdetails
0-3block4 byteshex0x0001 - 0x15B5

Response: variable length.

byteparameterlengthencodingdetails
0-3block4 byteshexcopy of request
4-5data length2 byteshexthis is probably not correct
6-enddata4 * data length byteshex

Example:

unknown 70 -> CP: verify firmware: block: 0001
src: 70, dst: 80, cmd: E2, data: 0001, length: 4
unknown 70 <- CP: verify firmware: block: 0001, length: 4 src: 80, dst: 70, cmd: E2, data: 0001 040F 8000 03EF B4F0 D7, length: 4
unknown 70 -> CP: verify firmware: block: 0002 src: 70, dst: 80, cmd: E2, data: 0002, length: 4
unknown 70 <- CP: verify firmware: block: 0002, length: 8 src: 80, dst: 70, cmd: E2, data: 0002 080F 8800 056E D8CF 06F0 E0CF A2, length: 8
unknown 70 -> CP: verify firmware: block: 0003 src: 70, dst: 80, cmd: E2, data: 0003, length: 4
unknown 70 <- CP: verify firmware: block: 0003, length: 16 src: 80, dst: 70, cmd: E2, data: 0003 100F 9000 07F0 0001 E9CF 0DF0 EACF 08F0 E1CF 09F0 4A, length: 16
    Notes:

Command E3: Reboot

Request: sent by CB.

Response: none.

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: E3 request (reboot), length: 0
dst: BC (broadcast) src: 80 (CP) cmd: 1E request (restart registration), length: 0
    Notes:
  • Request results in CP rebooting.

Command E4: Unknown

Request: sent by address 70 to CP, 4 bytes.

Response: 4 bytes, copy of request.

Example:

unknown 70 -> CP: unknown E4: ack
src: 70, dst: 80, cmd: E4, data: AA00, length: 4
 
unknown 70 <- CP: unknown E4: ack
src: 80, dst: 70, cmd: E4, data: AA00, length: 4
    Notes:

Command E6: Unknown

Request: sent by CP, 0 bytes.

Response: 0 bytes.

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: E1 response (unknown), length: 0
dst: 70 (unknown) src: 80 (CP) cmd: E6 request (unknown), length: 0
    Notes:
  • Request follows on E1 response.

Command EB: Get CP version

Request: sent by ChargeStation to CP, 0 bytes.

Response: 8 bytes.

byteparameterlengthencodingdetails
0-3firmware version4 bytesstring
4-7unknown4 bytesstring

Example:

src: FD (ChargeStation)
dst: 80 (CP)
cmd: EB (get CP version)
typ: request
src: 80 (CP) dst: FD (ChargeStation) cmd: EB (get CP version) typ: response dat: 0134 0125 (version: 0134), length: 8
    Notes:

Command EC: Unknown

Request: sent by ChargeStation to CP, 10 bytes.

Response: 0 bytes

Example:

ChargeStation -> CP: unknown EC: 
src: FD, dst: 80, cmd: EC, data: 0300 2000 00, length: 10
ChargeStation <- CP: unknown EC: src: 80, dst: FD, cmd: EC, data: , length: 0
    Notes:
  • Response is followed by CP sending command ED request to ChargeStation.

Command ED: Unknown

Request: sent by CP to ChargeStation, 2 bytes.

byteparameterlengthencodingdetails
0-1data2 byteshex

Observed data values are 50.

Response: none.

Example:

CP -> ChargeStation: unknown ED: 
src: 80, dst: FD, cmd: ED, data: 50, length: 2
    Notes:
  • Request follows on command EC response.

Command F0: Read block

Request: sent by ChargeStation, 6 bytes.

byteparameterlengthencodingdetails
0-3offset4 byteshex
4-5length2 byteshex

Response: request+ 2 * length bytes.

byteparameterlengthencodingdetails
0-3offset4 byteshexcopy of request
4-5length2 byteshexcopy of request
6-enddata2 * length byteshex
src: FD (ChargeStation)
dst: 80 (CP)
cmd: F0 (read block)
typ: request
dat: 0080 16 (offset: 0080, length: 22), length: 6
src: 80 (CP) dst: FD (ChargeStation) cmd: F0 (read block) typ: response dat: 0080 1645 5642 2D50 3139 3139 3132 3900 0000 0000 0000 0000 00 (offset: 0080, length: 22, data: EVB-P1919129__________), length: 50
    Notes:
  • This request can be sent to both CP and CB.
  • Data sometimes is hex-encoded ASCII, such as serial number, identity, model, and URLs.
  • I have not yet analyzed the data. There might be interesting stuff in there!

Command F1: Write block

Request: sent by ChargeStation, variable length.

byteparameterlengthencodingdetails
0-3offset4 byteshex
4-5length2 byteshex
6-enddata2 * length byteshex

Data sometimes is hex-encoded ASCII, such as serial number, identity, model, and URLs.

Response: 6 bytes.

byteparameterlengthencodingdetails
0-3offset4 byteshexcopy of request
4-5length2 byteshexcopy of request
cmd: F1 (write block)
typ: request
dat: 02F0 0400 0000 00, length: 14
str: offset: 02F0, length: 4, data: ____
src: FD (ChargeStation) dst: 80 (CP) cmd: F1 (write block) typ: request dat: 02F0 0400 0000 00, length: 14 str: offset: 02F0, length: 4, data: ____
    Notes:
  • This command can be sent to both CP and CB.
  • Data sometimes is hex-encoded ASCII, such as serial number, identity, model, and URLs.

Command F2: Unknown

Request: sent by ChargeStation, 0 bytes.

Response: 0 bytes.

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: F2 request (unknown), length: 0
dst: FD (ChargeStation) src: 80 (CP) cmd: F2 response (unknown), length: 0
    Notes:

Command F3: Read diagnostic

Request: sent by ChargeStation, 10 bytes.

byteparameterlengthencodingdetails
0-3unknowntd>4 byteshex
4-7offset4 byteshex
8-9length2 byteshex

Response: request + 2 * length bytes.

byteparameterlengthencodingdetails
0-3unknowntd>4 byteshexcopy of request
4-7offset4 byteshexcopy of request
8-9length2 byteshexcopy of request
10-enddata2 * length byteshex

Example:

src: FD (ChargeStation)
dst: 80 (CP)
cmd: F3 (read diagnostic)
typ: request
dat: 0004 0000 14 (offset: 0000, length: 20), length: 10
src: 80 (CP) dst: FD (ChargeStation) cmd: F3 (read diagnostic) typ: response dat: 0004 0000 1400 0101 0000 0000 0002 ED00 0000 8000 0000 0000 00 (offset: 0000, length: 20), length: 50
    Notes:
  • Data seems to be log in CSV format.

Command F4: Unknown

Request: sent by ChargeStation, 0 bytes.

Response: 10 bytes.

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: F4 request (unknown), length: 0
dst: FD (ChargeStation) src: 80 (CP) cmd: F4 response (unknown), length: 10 dat: 4478 3000 00 (unknown)
    Notes:

Command F5: Preparing ChargeStation for firmware update

Request: sent by ChargeStation to CP, 10 bytes.

byteparameterlengthencodingdetails
0-3block4 byteshex0x0020 - 0x003f
4-endunknown

Response: 10 bytes, copy of request.

Example:

ChargeStation -> CP: preparing chargestation for firmware update: block: 0020
src: FD, dst: 80, cmd: F5, data: 0020 0000 03, length: 10
ChargeStation <- CP: preparing chargestation for firmware update: block: 0020 src: 80, dst: FD, cmd: F5, data: 0020 0000 03, length: 10
(...)
ChargeStation -> CP: preparing chargestation for firmware update: block: 003F src: FD, dst: 80, cmd: F5, data: 003F 0000 03, length: 10
ChargeStation <- CP: preparing chargestation for firmware update: block: 003F src: 80, dst: FD, cmd: F5, data: 003F 0000 03, length: 10
    Notes:

Command F6: Reboot CP

Request: sent by ChargeStation.

Response: none.

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: F6 request (reboot), length: 0
dst: BC (broadcast) src: 80 (CP) cmd: 1E request (restart registration), length: 0
    Notes:
  • Request follows on command F5 response.
  • Request results in CP rebooting.

Command F7: Transfer firmware

Request: sent by ChargeStation to CP, 50 bytes.

byteparameterlengthencodingdetails
0-3block4 byteshex0x2000 - 0x33D1
4-enddatahex

Response: 0 bytes.

Example:

ChargeStation -> CP: transfer firmware: block: 2000
src: FD, dst: 80, cmd: F7, data: 2000 00EF 0F03 0BC8 C200 13D2 3301 4001 40
9E50 0010 01BA 01, length: 50
ChargeStation <- CP: transfer firmware: block: src: 80, dst: FD, cmd: F7, data: , length: 0
    Notes:
  • Every request (and response) is repeated 6 times. I assume this is for additional security against corrution during transfer.
  • I have not yet analyzed the data. I assume this is a firmware image. It might be worth dumping and disassembling.

Command F8: Unknown

Request: sent by ChargeStation, 0 bytes.

Response: 122 bytes.

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: F8 request (unknown), length: 0
dst: FD (ChargeStation) src: 80 (CP) cmd: F8 response (unknown), length: 122 dat: 4874 330D 38FF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FF (unknown)
    Notes:

Command F9: Unknown

Request: sent by ChargeStation, 0 bytes.

Response: 10 bytes.

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: F9 request (unknown), length: 0
dst: FD (ChargeStation) src: 80 (CP) cmd: F9 response (unknown), length: 10 dat: 4975 330D 38 (unknown)
    Notes:

Command FA: Unknown

Request: sent by ChargeStation, 0 bytes.

Response: 0 bytes.

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: FA request (unknown), length: 0
dst: FD (ChargeStation) src: 80 (CP) cmd: FA response (unknown), length: 0
    Notes:

Command FB: Reboot CP

Request: sent by ChargeStation to CP, 2 bytes.

byteparameterlengthencodingdetails
0-1data2 byteshex

Observed data values are 0C.

Response: none.

Example:

src: FD (ChargeStation)
dst: 80 (CP)
cmd: FB (Restart)
typ: request
dat: 0C (), length: 2

Command FD: Reboot

Request: sent by ChargeStation.

Response: none.

Example:

dst: 80 (CP)
src: 01 (charger)
cmd: FD request (unknown), length: 0
dst: BC (broadcast) src: 80 (CP) cmd: 1E request (restart registration), length: 0
    Notes:
  • Request results in CP rebooting.

Captures

Boot

CP -> broadcast: restart registration:
new -> CP: CB register: serial number: 1917911, firmware version: 0125, hardware generation: 03
CP -> broadcast: CB register: serial number: 1917911, address: 01, gen: 03
CP -> CB1: connection state changed:
CB1 -> CP: charging state: state: available
CB1 <- CP: charging state: ack
CB1 -> CP: CB state update: state: available, is charging: 0, led colour: off, is locked: 0, cable current: 0A, meter value: 16724.21kWh, temperature: 26.0/0°C, session: 0, voltage: 226/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: not connected to backend
CP -> CB1: get meter info:
CP <- CB1: get meter info: version number: 16, model name: ALD1D5FS00A, serial number: 364D334100000000, mains frequency: 50.0Hz
CP -> CB1: get CB configuration:
CP <- CB1: get CB configuration: led brightness: 30%, meter update interval: 900s, meter type: serial, auto start: 0, remote start: 0
CP -> CB1: set CB configuration: led brightness: 30%, meter update interval: 900s, meter type: serial, auto start: 0, remote start: 0
CP <- CB1: set CB configuration: ack
# once CP connected to backend
CP -> broadcast: connection state changed:
CB1 -> CP: CB state update: state: available, is charging: 0, led colour: off, is locked: 0, cable current: 0A, meter value: 16724.21kWh, temperature: 26.0/0°C, session: 0, voltage: 225/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: session: 0, timestamp: 2024-06-06 13:46:20
CP -> CB1: request update: update type: 2
CB1 -> CP: CB state update: state: available, is charging: 0, led colour: off, is locked: 0, cable current: 0A, meter value: 16724.21kWh, temperature: 26.0/0°C, session: 0, voltage: 222/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: session: 0, timestamp: 2024-06-06 13:46:31

Charging session

# plugin EV
CB1 -> CP: CB state update: state: charging cable connected, is charging: 0, led colour: off, is locked: 0, cable current: 32A, meter value: 16734.28kWh, temperature: 31.0/0°C, session: 0, voltage: 227/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: session: 0, timestamp: 2024-09-23 13:52:32
# scan fob
CB1 -> CP: authentication request: state: authentication request, card number: xxxx
CB1 <- CP: authentication request: state: access granted, card number: xxxx
CB1 -> CP: CB state update: state: charging cable connected, is charging: 0, led colour: off, is locked: 0, cable current: 32A, meter value: 16734.28kWh, temperature: 31.0/0°C, session: 0, voltage: 232/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: session: 0, timestamp: 2024-09-23 13:54:30
CB1 -> CP: charging state: state: ready
CB1 <- CP: charging state: ack
CP <- CB1: set current limit:
CB1 -> CP: metering start: card number: xxxx, meter value: 16734.28kWh
CB1 <- CP: metering start: session: 0, timestamp: 2024-09-23 13:54:33
CB1 -> CP: CB state update: state: ready, is charging: 0, led colour: yellow, is locked: 1, cable current: 32A, meter value: 16734.28kWh, temperature: 31.0/0°C, session: 0, voltage: 227/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 6.0A, frequency: 50.0Hz
CB1 <- CP: metering start: session: 12729945, timestamp: 2024-09-23 13:54:35
CB1 -> CP: CB state update: state: charging, is charging: 1, led colour: blue, is locked: 1, cable current: 32A, meter value: 16734.28kWh, temperature: 31.0/0°C, session: 12729945, voltage: 231/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 6.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: session: 12729945, timestamp: 2024-09-23 13:56:28
CB1 -> CP: charging state: state: ready
CB1 <- CP: charging state: ack
CP -> CB1: set current limit: current min: 6.0A, current limit: 6.0/6.0/6.0A
CP <- CB1: set current limit:
CB1 -> CP: charging state: state: charging
CB1 <- CP: charging state: ack
CP -> CB1: set current limit: current min: 6.0A, current limit: 20.0/20.0/20.0A
CP <- CB1: set current limit:
CB1 -> CP: CB state update: state: charging, is charging: 1, led colour: blue, is locked: 1, cable current: 32A, meter value: 16735.0kWh, temperature: 31.0/0°C, session: 12729945, voltage: 222/0/0V, current: 13.3/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 20.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: session: 12729945, timestamp: 2024-09-23 14:11:29
# (...)
CB1 -> CP: CB state update: state: charging, is charging: 1, led colour: blue, is locked: 1, cable current: 32A, meter value: 1 6741.45kWh, temperature: 31.0/0°C, session: 12729945, voltage: 223/0/0V, current: 4.8/0.0/0.0A, power factor: 0.98/0.0/0.0, cur
rent limit: 20.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: session: 12729945, timestamp: 2024-09-23 16:41:37
# charging finished
CB1 -> CP: CB state update: state: ready, is charging: 0, led colour: yellow, is locked: 1, cable current: 32A, meter value: 16 741.54kWh, temperature: 31.0/0°C, session: 12729945, voltage: 227/0/0V, current: 4.6/0.0/0.0A, power factor: 1.0/0.0/0.0, curre
nt limit: 20.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: session: 12729945, timestamp: 2024-09-23 16:46:56
CB1 -> CP: charging state: state: finished
CB1 <- CP: charging state: ack
CP <- CB1: set current limit: 
CB1 -> CP: CB state update: state: ready, is charging: 0, led colour: yellow, is locked: 1, cable current: 32A, meter value: 16741.54kWh, temperature: 30.0/0°C, session: 12729945, voltage: 227/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 20.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: session: 12729945, timestamp: 2024-09-23 17:01:55
# unplug EV
CB1 -> CP: charging state: state: unplugged
CB1 <- CP: charging state: ack
CB1 -> CP: CB state update: state: finished, is charging: 0, led colour: off, is locked: 1, cable current: 32A, meter value: 16741.54kWh, temperature: 30.0/0°C, session: 12729945, voltage: 223/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: session: 12729945, timestamp: 2024-09-23 17:09:05
CB1 -> CP: CB state update: state: finished, is charging: 0, led colour: off, is locked: 1, cable current: 32A, meter value: 16741.54kWh, temperature: 30.0/0°C, session: 12729945, voltage: 223/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: session: 12729945, timestamp: 2024-09-23 17:09:14
CB1 -> CP: metering end: card number: xxxx, meter value: 16741.54kWh, session: 12729945, timestamp: 2024-09-23 17:09:15
CB1 <- CP: metering end: 
CB1 -> CP: charging state: state: available
CB1 <- CP: charging state: ack
CB1 -> CP: CB state update: state: available, is charging: 0, led colour: off, is locked: 0, cable current: 0A, meter value: 16741.54kWh, temperature: 30.0/0°C, session: 0, voltage: 223/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz
CB1 -> CP: CB state update: state: available, is charging: 0, led colour: off, is locked: 0, cable current: 0A, meter value: 16741.54kWh, temperature: 30.0/0°C, session: 0, voltage: 223/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz
CB1 -> CP: CB state update: state: available, is charging: 0, led colour: off, is locked: 0, cable current: 0A, meter value: 16741.54kWh, temperature: 30.0/0°C, session: 0, voltage: 223/0/0V, current: 0.0/0.0/0.0A, power factor: 1.0/0.0/0.0, current limit: 90.0A, frequency: 50.0Hz
CB1 <- CP: CB state update: session: 0, timestamp: 2024-09-23 17:09:18

Firmware update

I do not fully understand all steps and commands yet. Some of the firmware update stages in the ChargeStation Tool map directly to commands, but others are less clear. Firmware is transferred to the CP, but the CB is also updated. Where address 0x70 comes from is also unclear.

    firmware update steps in ChargeStation Tool:
  • checking file (= read block)
  • preparing chargestaton (= preparing chargestation for firmware update)
  • transfering to chargestation (= transfer firmware)
  • checking transfered file in chargtestation (= verify firmware)
  • programming chargebox
  • programming chargepoint
ChargeStation -> CP: get CP version: 
ChargeStation <- CP: get CP version: version: 0134
ChargeStation -> CP: read block: offset: 0400, length: 10
ChargeStation <- CP: read block: offset: 0400, length: 10
(...)
ChargeStation <- CP: read block: offset: 07C0, length: 10
ChargeStation <- CP: read block: offset: 07C0, length: 10
ChargeStation -> CP: preparing chargestation for firmware update: block: 0020
ChargeStation <- CP: preparing chargestation for firmware update: block: 0020
(...)
ChargeStation -> CP: preparing chargestation for firmware update: block: 003F
ChargeStation <- CP: preparing chargestation for firmware update: block: 003F
ChargeStation -> CP: get CP version: 
ChargeStation <- CP: get CP version: version: 0134
ChargeStation -> CP: transfer firmware: block: 2000
ChargeStation <- CP: transfer firmware:
(...)
ChargeStation -> CP: transfer firmware: block: 33D1
ChargeStation <- CP: transfer firmware:
ChargeStation -> CP: unknown EC: 
ChargeStation <- CP: unknown EC: 
CP -> ChargeStation: unknown ED: 
CP -> broadcast: unknown E0: 
CP -> unknown 70: unknown E1: ack
unknown 70 -> CP: verify firmware: block: 0001
unknown 70 <- CP: verify firmware: block: 0001, length: 4
(...)
unknown 70 -> CP: verify firmware: block: 15B5
unknown 70 <- CP: verify firmware: block: 15B5, length: 0
unknown 70 -> CP: reboot: 
unknown 70 <- CP: reboot: 
unknown 70 -> CP: unknown E4: ack
unknown 70 <- CP: unknown E4: ack
new -> CP: register: serial number: 1951714, firmware version: 0140, hardware generation: 03
CP -> broadcast: register: serial number: 1951714, address: 03, gen: 03
CP -> CB3: connection state changed: 
CP -> broadcast: unknown E0: 
CP -> broadcast: unknown E5:
CP -> broadcast: restart registration: 
CP -> broadcast: register: serial number: 1951714, address: 03, gen: 03

My implementation

You can find my partial CP implementation in the downloads directory of the background article.

Resources

In addition to my own testing, I have used these publicly available sources: