Skip to content

DL/T645 Driver ​

dc3-driver-dlt645 reads electricity meters speaking the Chinese DL/T645-2007 protocol over RS485. It builds the meter request frame (68H ... 16H), verifies the response checksum, and parses the data identifier (DI0-DI3) value; writes use the DL/T645 operator codes for meter programming.

Protocol background ​

DL/T645-2007 is the Chinese national standard for multi-function electricity meters. Frames are delimited by 68H, carry a 6-byte BCD meter address, and end with a cumulative checksum. Each measured quantity (voltage, current, power, energy) is addressed by a 4-byte data identifier DI0-DI3.

  • Driver name / code: DL/T645 Driver / Dlt645Driver
  • Type: DRIVER_CLIENT (opens the serial port and polls the meter)
  • Underlying library: jSerialComm (self-built DL/T645-2007 frame encode/decode)

Attribute configuration ​

Driver attributes (device-level driver-attribute) ​

AttributecodeTypeDefaultDescription
Serial PortportSTRING/dev/ttyUSB0Serial port device path
Baud RatebaudRateINT2400Baud rate (DL/T645 default 2400)
Data BitsdataBitsINT8Data bits
Stop BitsstopBitsINT1Stop bits
ParityparityINT2Parity (2=Even, DL/T645 default)
TimeouttimeoutINT1000Read timeout in milliseconds
Meter AddressmeterAddressSTRING00000000000012-digit BCD meter address
Write PasswordpasswordSTRING00000000Meter password for writes
Operator CodeoperatorCodeSTRING00000000Operator code for writes

Point attributes (point-attribute) ​

AttributecodeTypeDefaultDescription
Data IdentifierdiSTRING000100004-byte data identifier as 8 hex chars (DI0-DI3; default = total active energy)
Data FormatdataFormatSTRINGHEXHEX, BCD, INT, FLOAT, ASCII

Command attributes (command-attribute) ​

AttributecodeTypeDefaultDescription
Data IdentifierdiSTRING00010000Data identifier for writes (DI0-DI3, 8 hex chars)
Data FormatdataFormatSTRINGHEXEncoding for the written value: HEX, BCD, INT, FLOAT, ASCII

The write path does not read this table

write() takes di and dataFormat from the point attributes and meterAddress / password / operatorCode from the device attributes; the two command attributes above are only registered in the driver's application.yml and are not consumed by write(). To change write behavior, edit the point attributes.

Collection and health ​

  • Collection cycle: default cron 0/30 * * * * ? (one polling round over all points every 30 seconds).
  • Health/online: device health defaults to cron 0/15 * * * * ?, lease timeout 45 seconds.

Capability matrix ​

CapabilitySupportedNotes
Read✓
Write✓
Subscribe—

Implementation status: complete

The frame encoder/decoder (Dlt645Frame) and serial connection (Dlt645SerialPortConnection) are fully implemented, including address BCD encoding, checksum verification, and read/write frame building.

Troubleshooting ​

Serial devices fail at the physical layer first — match the symptom before touching anything else.

Failed to open serial port only means the port did not open

A wrong path, missing permissions for the driver process, or another program holding the port (a serial terminal, another driver instance) all make openPort() return false and raise a ConnectorException. In container deployments, also verify the serial device is actually mounted into the container.

  • Symptom: Invalid DL/T 645 meter address or Invalid hexadecimal value → cause: meterAddress must be 12 decimal digits; di, password and operatorCode must each be 8 hexadecimal characters. Wrong length or characters are rejected before any frame is built. Check: pad with leading zeros against the meter nameplate; never use A-F in meterAddress.
  • Symptom: Empty DL/T 645 response keeps recurring and the connection keeps being rebuilt → cause: the meter is not answering — wrong meter address, baud rate or parity mismatching the meter's settings, or swapped A/B lines on the RS485 bus. An empty response raises a ReadPointException and invalidates the connection; the next cycle reopens the port and fails the same way. Check: send a read request by hand with a serial tool at the same settings, then verify meterAddress, baudRate and parity.
  • Symptom: reads throw Unexpected DL/T 645 response control code, or writes return failure → cause: the meter answered with a non-normal frame. Reads only accept the read-response control codes 0x91 / 0xB1 (with follow-up); anything else throws. A write only counts as success when the response control code is 0x94 — a wrong password or operator code, or a data identifier that is not writable, makes the meter return an error frame and the write return false without an exception. Check: confirm di exists in the meter's data identifier table; verify password / operatorCode against the meter's communication parameters.
  • Symptom: checksum mismatch / response too short / invalid frame delimiters → cause: a truncated or corrupted response frame — typically mismatched serial parameters, bus interference, or a timeout too short to receive the full frame. Check: recheck the serial parameters; raise the device attribute timeout if needed.
  • Symptom: values arrive but the magnitude is obviously wrong → cause: dataFormat does not match the actual encoding of that data identifier. The driver decodes purely by the point's dataFormat; display-style identifiers (XXX.X) on meters are usually BCD, and configuring FLOAT yields garbage. Check: look up the DI's encoding and fix the point attribute.
  • Symptom: the device shows online but no values ever arrive → cause: the health check only tests whether the serial handle is still open, not whether the meter answers; read failures only surface in the driver log. Check: search the driver log for ReadPointException and match it against the list above.

How it lands in IoT DC3 ​

One DL/T645 meter is one Device in the platform: the serial parameters (port / baudRate / dataBits / stopBits / parity / timeout) and the meter address (meterAddress) all live on device attributes, and the driver keeps one serial connection per deviceId, opened lazily on the first read, write or health check. The protocol itself is a one-master, many-slaves polling model on an RS485 bus, addressed by the 6-byte BCD meter address; one device carries exactly one meter address, so a bus with several meters means several devices, each with its own meterAddress.

The read path: the scheduler calls read() per point every 30 seconds by default. The driver builds a control-code 0x11 read-data request from the point attribute di, sends it on the serial port, verifies the checksum, reverses the +0x33 offset on each data byte, then formats the bytes into a string using the point attribute dataFormat (BCD / INT / FLOAT / ASCII / HEX) and hands it back as a PointValue. The write path reuses the same point attributes: write() locates the data identifier by the point's di, encodes the value per dataFormat, takes meterAddress / password / operatorCode from device attributes to build a control-code 0x14 write-data frame, and succeeds when the response control code is 0x94 (the command attributes are not consumed by write(), see the warning above); execute() is not implemented in this driver, so custom commands return the interface default — an empty map.

The connection is self-healing: any exception on the read path closes and removes that device's serial connection, and the next cycle reopens it; deleting or updating the device closes the old connection through a metadata event. Online state rides the health check plus the lease: the health check runs every 15 seconds by default and only confirms the serial handle is open, with a 45-second lease timeout — see Device. Alarms and automation trigger on the platform side from point values; the driver registers no event attributes, matching the "Subscribe —" row in the capability matrix.

Minimal onboarding example ​

  1. Create a Device using DL/T645 Driver, set port=/dev/ttyUSB0, baudRate=2400, parity=2, meterAddress=<your 12-digit address>.
  2. Add a Point (READ_ONLY) with di=02010100 (phase A voltage) and dataFormat=FLOAT.
  3. Start the driver; within 30 seconds the value appears in PointValue.

Further reading ​

Released under the AGPL-3.0 License