Skip to content

IEC 104 Driver

dc3-driver-iec104 connects IEC 60870-5-104 telecontrol equipment to IoT DC3: it connects as a 104 client to substation/dispatch-automation devices, collects telemetry and status by Information Object Address (IOA), and supports sending telecontrol commands. By the end of this page you will understand how 104 addresses data, how to fill the protocol attributes on a device and its points correctly, and exactly where this driver's implementation currently stops.

You are here: the "power telecontrol / SCADA" onboarding side of field devices. To understand why industrial protocols are vendor-proprietary and where IEC 104 sits in the network layer, start with Industrial Buses & Protocols.

Protocol Background

IEC 60870-5-104 (IEC 104 for short) is the international standard telecontrol protocol for power-system dispatch automation, carrying the IEC 60870-5-101 application layer over standard TCP/IP. It is widely used for "four-remote" communication — telemetry, telesignaling, telecontrol, telesetpoint — between substation integrated-automation systems, distribution terminals (DTU/FTU), RTUs, and master stations. In power dispatch it belongs — alongside building-automation BACnet and utility-metering DLMS/COSEM — to the camp of protocols standardized to industry-specific needs.

IEC 104 differs from a protocol like Modbus in its addressing model; it locates and interprets a data point with two concepts:

  • Information Object Address (IOA) uniquely locates one data point in the telecontrol device (a telemetry value, a status point).
  • ASDU type describes the data semantics of the frame, e.g. M_ME_NC_1 (short-float telemetry), M_SP_NA_1 ( single-point status) — the same IOA with a different ASDU type yields data with a different meaning.

104 frames have no field delimiters; how many bytes the common address, cause of transmission, and information object address each occupy is agreed between the master and the telecontrol device during engineering configuration (typically 2/2/3). This model of "split by byte width, locate by IOA" means the byte-length configuration must match the peer exactly.

In the four-layer IoT architecture, IEC 104 belongs to the industrial wired side of the network layer: it solves " how a field telecontrol device sends a telemetry/status point out over TCP/IP and receives a telecontrol command," sitting above the sensing layer (transformers/transducers) and below the platform layer (IoT DC3 aggregation). The diagram below places the 104 client within a single collection:

Network layer (IEC 60870-5-104)read/write by IOA + asduTypecollected valueRTUIOA 16385 = 220.5TCP Socketport 2404ASDU messageM_ME_NC_1 short floatdc3-driver-iec104code=Iec104DriverIoT DC3PointValue

The driver acts as a client and actively connects to a 104 server, locating which point to read by the ioa configured on the point and interpreting the bytes by asduType, then unifies it as a PointValue sent upstream.

Attribute Configuration

IEC 104 onboarding parameters come in two layers: driver attributes (driver-attribute) describe "which telecontrol device, which port, how many bytes per field" and are filled on the device; point attributes (point-attribute) describe "which IOA, interpreted as which ASDU type" and are filled on each Point. Writable points add a command attribute (command-attribute). The defaults of all of these come from the driver's application.yml; for the three-layer origin see Attributes and Config.

Driver Attributes (device-level driver-attribute)

When onboarding an IEC 104 device, first state its network location and frame-field convention on the device. host / port decide where TCP connects; asduAddress (common address, a.k.a. station address) distinguishes multiple logical stations under the same connection; cotLength / caLength / ioaLength are the byte widths of the cause-of-transmission, common-address, and information-object-address fields in a 104 frame; connectTimeout bounds how long the connect waits.

AttributecodeTypeDefaultDescription
HosthostSTRINGlocalhost104 server IP (telecontrol device address)
PortportINT2404104 TCP port (standard 2404)
ASDU AddressasduAddressINT1Common address (station address), distinguishes logical stations
COT LengthcotLengthINT2Cause-of-transmission field byte count
CA LengthcaLengthINT2Common-address field byte count
IOA LengthioaLengthINT3Information-object-address field byte count
Connect TimeoutconnectTimeoutINT10000Connect timeout (milliseconds)

COT/CA/IOA lengths are a station-wide convention and must match the peer

cotLength / caLength / ioaLength are the byte widths of the respective fields in 104 frames, agreed between the master and the telecontrol device during engineering configuration (typically 2/2/3). These three must match the peer exactly, otherwise the frame is split on the wrong byte boundaries and addresses are read off misaligned bytes. asduAddress (common address) distinguishes multiple logical stations under the same host:port connection.

host / port / asduAddress are validated as required

validate() lists host, port, and asduAddress as required; missing any one reports an ERROR at validation and the device config does not pass. The remaining byte-length attributes have defaults and use the table values above when omitted.

Point Attributes (point-attribute)

Each collected point must state which information object to read and which ASDU type to interpret it with — the driver does not probe the device for the type; it interprets bytes strictly by the asduType you set.

AttributecodeTypeDefaultDescription
IOAioaINT0Information object address, uniquely locates one data point
ASDU TypeasduTypeSTRINGM_ME_NC_1ASDU type identifier, defines the data semantics

IOA locates "which point to read", ASDU type defines the data semantics

ioa is the information object address, uniquely identifying one data point in the telecontrol device. asduType indicates the point's data type, defaulting to M_ME_NC_1 (short-float telemetry); status points commonly use M_SP_NA_1 (single-point status). The Point's own data type (Point pointTypeFlag) should match the actual data carried by the ASDU type. validatePoint() lists ioa as required.

Command Attribute (command-attribute)

Writable points (issuing telecontrol) add a send template on the write command.

AttributecodeTypeDefaultDescription
Send CommandsendCommandSTRING${value}Send-command template, rendered from command arguments

sendCommand is a template with parameter placeholders

sendCommand uses ${paramName} placeholders; during execute() the driver substitutes the command arguments (e.g. ${value}) one by one, and the default ${value} simply uses the command value as the control value. Note: execute() currently only renders the template and returns it under the sendCommand key of the result map — it does not actually send the telecontrol frame to the 104 server (see implementation status below).

Collection and Health

  • Collection cycle: default read cron 0/30 * * * * ? (reads once every 30 seconds).
  • Custom schedule: schedule.custom is enabled in the yml (cron 0/5 * * * * ?), but the current schedule() method body is empty and performs no custom logic.
  • Health / online: device health check default cron 0/15 * * * * ?, lease timeout 45 seconds — see Device for the online-state mechanism.

Troubleshooting

IEC 104 onboarding failures mostly fall into two buckets: "cannot connect" and "frame parsing is misaligned." Work through them from the outside in. Note: this driver's protocol read/write is currently a skeleton (see the next section), so the checks below target onboarding parameters and network reachability, not a running state that already collects values.

Port or firewall: 2404 unreachable

104 runs over TCP 2404 by standard — different from Modbus 502, EtherNet/IP 44818, and DLMS 4059, so do not mix them up. First confirm host:2404 is reachable from the driver host (telnet <host> 2404 or nc -vz <host> 2404). Common causes: the 104 service not enabled on the telecontrol device, network not routed, firewall blocking 2404. The connect timeout is controlled by connectTimeout (default 10000 ms).

Mismatched COT/CA/IOA lengths = whole-frame parse misalignment

104 frames have no field delimiters and are split purely by the agreed byte widths. If cotLength / caLength / ioaLength differ from the peer, addresses get read off the wrong bytes, so you collect the wrong point or parsing fails outright. Before onboarding, confirm the peer's 2/2/3 (or other) configuration with operations and fill all three in exactly.

Wrong common address (asduAddress) connects to the wrong logical station

One RTU may host several logical stations distinguished by asduAddress (common address). When several devices share the same host:port, each one's asduAddress decides which station to connect to / read. If asduAddress is wrong, the expected points will not be found in the peer's interrogation response. Confirm each logical station's common address with operations before onboarding.

ASDU type does not match the point's real type

The driver interprets bytes strictly by the asduType set on the point. Configuring a short-float telemetry point ( M_ME_NC_1) as single-point status (M_SP_NA_1) makes the decoded value meaningless. Confirm the ASDU type of each IOA before onboarding, and make the point's pointTypeFlag match (telemetry is usually FLOAT, status is usually BOOLEAN).

Device online state does not mean a value has been collected

Device online/offline is maintained by the lease mechanism (default 45 seconds timeout) and reflects the heartbeat between the driver and the platform, not that data was actually read over the 104 link. To judge whether a value is being collected, rely on whether the PointValue updates. With the protocol read/write not yet implemented (see the next section), no PointValue will update.

How It Lands in IoT DC3

  • dc3.driver.code: Iec104Driver (a stable routing identifier — registration and message routing both rely on it, do not change it casually). Driver name IEC 104 Driver, type DRIVER_CLIENT (the driver actively connects to the telecontrol device).
  • Read: read() is not implemented — it throws ReadPointException to fail fast (so the SDK records the failure and applies backoff, rather than echoing a cached value or faking success).
  • Write: write() is not implemented — it throws WritePointException to fail fast.
  • Telecontrol command: execute() is partially implemented — it only renders the sendCommand template from arguments and returns the result; it does not yet send the telecontrol frame to the 104 server.
  • Subscribe / push: not applicable. This driver follows a client model and reads actively on the collection cycle; it does not listen for device-initiated pushes.

Aligned with the Driver Capability Matrix: in the matrix IEC 104 is marked for read/write/subscribe, with the note "Power SCADA, skeleton pending."

Work in progress (skeleton)

This driver is a protocol template skeleton: the attribute tables, collection cycle, and IOA/ASDU addressing semantics are in place and safe to fill in, but the 104 protocol-layer I/O is not yet implemented:

  • read() / write() throw a "not implemented" exception to fail fast, performing no IOA read or telecontrol send;
  • execute() only renders the sendCommand template and returns — it does not actually send a frame;
  • initial(), schedule(), and event() have empty bodies, with no custom init/schedule/metadata-event logic;
  • the only implemented logic is configuration validation (validate() / validatePoint()) and command-template rendering.

Treat it as a starting template for onboarding a 104 device, not a production-ready driver. For the final behavior, consult the read() / write() / initial() source in Iec104DriverCustomServiceImpl.

The minimal path to onboard a telecontrol device (to validate the config flow, not for production collection):

  1. Create a device with IEC 104 Driver, and set the driver attributes host=192.168.1.30, port=2404, asduAddress=1 (leave cotLength / caLength / ioaLength at the defaults 2/2/3, as long as they match the peer's convention).
  2. Add a telemetry Point (pointTypeFlag=FLOAT, READ_ONLY) to the Profile bound to the device, and set the point attributes ioa=16385, asduType=M_ME_NC_1.
  3. Start the driver and watch the connect and validation logs. Until the protocol layer is completed, the 30-second read round fails fast (with exception backoff); once completed, the collected value appears in PointValue.

For the complete onboarding procedure, see Device Onboarding.

Further Reading

Released under the AGPL-3.0 License