Modbus TCP API
This document provides a complete overview of the Modbus Slave features of the Charge Controller.
Based on revision v0.14.
1. Config UI parameters reference for Operators
2. Modbus Unit ID
The Modbus TCP Server on the charge controller will reply to messages with any Unit ID from 1 to 255.
3. OCPP multiple connector scenarios
On an OCPP setup with 2 connectors, both controllers are accessible by connecting through the one acting as a master controller. In this case it is necessary to establish a separate connection to each charge controller.
The second connector's controller is accessible on the port
corresponding to Modbus TCP Server Base Port
+ 1.
Assuming that the Modbus TCP Server Base Port
is configured on the
default port 502, the first connector can be accessed by
connecting a Modbus Client
to port 502, and the second connector
can be accessed by connecting a separate Modbus Client to the first
connector charge controller's port 503.
4. Word and byte ordering
With the notable exception of the values in the register destined to error codes (those with names prefixed with ERROR_CODES_ ) which are explained separately in their corresponding section, all other registers are to be read and written with the high byte first and the low byte after. For double registers (32-bit) the order of the words is the high word first and the low word after.
As an example, if registers 200-201 are read and contain a value of 0x0001 for register 200 and a value of 0x1F40 for register 201, these values are to be read as 0x00011F40, that is a decimal value of 73536.
5. Lowering charging current
To lower the charging currant the HEMS shall write to the Register HEMS_CURRENT_LIMIT as described in the HEMS configuration options section.
Please note the actual signaled current as indicated by the register named SIGNALED_CURRENT can be lower than the HEMS_CURRENT_LIMIT since other limitations (such as charging cable, or dynamic load management limits) could apply.
6. Supported function codes
All registers described in this document are HOLDING registers. Therefore, the only supported function codes are:
- 0x03 -- Read single register
- 0x06 -- Write single register
- 0x10 -- Write multiple registers.
7. Bulk read of registers
It is possible to read a range of registers at a time (bulk read) starting at a specified register and within the boundaries of the register section.
If there are gaps with undefined register numbers in this range, value '0' will be returned.
8. General system information
The register in the first table that follows contain general information about the system, about its status, error states, FW and protocol versions and other system and configuration information.
The Charge Point Status as defined in OCPP 1.5 and 1.6 is available in the OCPP_CP_STATUS
register.
Note that there's some difference between the two versions, so for example the value 1, which is used for "Occupied", is only valid for OCPP 1.5 and instead in 1.6 a more detailed value is available.
For the descriptions of each of the charge point status values, please refer to the OCPP specification that corresponds to the version in use.
For details on how to read and interpret the registers designated for error handling please refer to the section Error states mask mappings.
9. Meter values from OCPP primary meter
Meter values are unsigned and sent in 32-bit words.
When not available, registers contain a 0xffffffff value to indicate that no meter value for the requested register is present.
For maintaining backwards compatibility with previous systems, where the METER_TOTAL_ENERG and METER_TOTAL_POW registers were not present, the Total Power and Total Energy values can also be read from the Power and Energy registers corresponding to L1. In that case, the Power and Energy registers for L2 and L3 will return 0xffffffff.
10. Dynamic Load Management (DLM)
This is information mostly concerning the DLM Master. Everything except for register 600 will be available only for devices with a DLM Master role set (meaning a value of 1 or 2 is returned on this register). | -->
11. Charge process information
Charge process information is information collected during, or inferred from, the charging process.
Registers
- 705
- 709
are deprecated and only to be used for clients that implement until version 10 of this protocol.
The older registers can still be read in newer versions for backwards compatibility, but it is discouraged to do so in newer implementations.
Once the values in those registers reach their maximum, they will stay at the maximum value until the next session is started or until the charging process is finished according to each case.
12. HEMS configuration options
13. Authorization with IDTag
Please note that for these registers to be enabled, the corresponding
option must be set in the controller HEMS/Modbus setting named Modbus Slave Allow Start/Stop Transaction
.
When writing to these registers, the effect will be exactly the same as if one physically presented an RFID card in fron of the card reader. That means it will start/stop the transaction accordingly based on each scenario's workflow.
Note that the registers in this table are WRITE only. To READ the IDTAG
currently in use please refer to the registers prefixed with
READ_ID_TAG_
on their name.
14. Error states mask mappings
In order to represent any simultaneous error states, the value read from the ERROR_CODES registers can be AND'ed with different mask mappings to identify which individual errors may be present at any given time in the system.
Since only bits 0 to 21 are used in the current specification, it is possibly to read only from registers 111-112 in order to optimize the fetching of values.
For completion however, it is clarified here how to read and interpret the values when reading all 8 registers.
To test for each error individually, the resulting value of reading all registers has to be masked against the corresponding error mask. An example is given below on how to achieve this.
Supposing the following value (presented here in HEX) is read from the
ERROR_CODES
registers:
Register: 105-106 107-108 109-110 111-112
Value: 0000 0000 0000 0000 0000 0000 4100 0000
Please focus first in the value of registers 111-112.
The bits of a double word are numbered from 0 through 31 with bit 0 being the least significant bit. The word containing bit 0 is the low word and the word containing bit 31 is the high word. Each 32-bit register has the low word first, and each word has the low byte first.
So in the case of registers 111-112 the words must first be inverted, to get a value of 0000 4100, and then the bytes of each word must be inverted too, in order to get a value of 0000 0041.
That is to be done for each register pair (105-106, 107-108, 109-110, 111-112), and once it is done, then the whole resulting value can be simply assembled from all registers by starting from a value of 0, and going through each word (register) in order, first shifting to the left then adding.
The result from the case above would be:
0000 0000 0000 0000 0000 0000 0000 0041
Finally, to identify which individual errors are present this value must be AND'ed to each error mask. So by doing the following operation:
0000 0000 0000 0000 0000 0000 0000 0041
AND
0000 0000 0000 0000 0000 0000 0000 0001
Ii is possible to identify that an error "ERR_RCMB_TRIGGERED" is present.
And by continuing doing for example:
0000 0000 0000 0000 0000 0000 0000 0041
AND
0000 0000 0000 0000 0000 0000 0000 0040
It can be observed that also there is an error "ERR_CONTACTOR_WELD" present.
Mask values for bits 0 to 21 (LSB 0) are specified in the following table. Bits 22 to 127 are reserved.
15. Error events mask mappings
The same as described in chapter above applies here, except:
Supposing the following value (presented here in HEX) is read from the ERR_EVT_CODES registers:
Register: 158-159 160-161 162-163 164-165
Value: 0000 0000 0000 0000 0000 0000 4100 0000
Please focus first in the value of registers 164-165.
16. Appendix
16.1. Exhaustive list of Modbus registers
Here's an exhaustive list of Modbus registers for convinience:
All data is transferred in network byte order/big endian.