Siemens S7 Driver
Overview
ISO-on-TCP communication for the Siemens SIMATIC S7 series (S7-300 / S7-400 / S7-1200 / S7-1500).
| Item | Value |
|---|---|
opc_type | S7 |
| Implementation class | plantpulse.driver.protocol.s7.S7_34_Driver |
| Library | iot-communication (plantpulse.plc.protocol.s7) |
| read | ✅ (batch mode) |
| write | ✅ (Boolean/Integer/Long/Float/Double/String) |
| Security | None (direct TCP; S7 safety communication is not supported) |
OPC Registration Form
| Field | Meaning | Example |
|---|---|---|
opc_agent_ip | PLC IP | 192.168.0.70 |
opc_agent_port | ISO-on-TCP port | 102 |
timecycle | Polling interval (ms) | 1000 |
options.controller-type | Series | S7_400 (default) / S7_300 / S7_200 / S7_200_SMART / S7_1200 / S7_1500 / SINUMERIK_828D |
options.local-rack | rack number (the legacy misspelling local-lack is also accepted) | 0 (default) |
options.local-slot | slot number | 3 (S7-400 default) / 0 (S7-1200/1500) / 2 (S7-300) |
options.multi-read | Bulk read of each chunk in a single round trip (opt-in) | false (default) |
options.multi-read-max-items | Maximum number of items per chunk | 18 (default, based on a 240-byte PDU budget) |
rack/slot
- S7-300 : rack=0, slot=2
- S7-400 : rack=0, slot=3 (varies with the CPU slot)
- S7-1200 / 1500 : rack=0, slot=0 (or 1)
Tag plc_address Format
Standard Siemens memory address notation (DB / I / Q / M / T / C).
| Notation | Meaning |
|---|---|
%DB1.DBX0.0 | Bit X0.0 of DB1 (Bool) |
%DB1.DBB0 | Byte 0 of DB1 (8-bit) |
%DB1.DBW0 | Word 0 of DB1 (16-bit) |
%DB1.DBD0 | Double word 0 of DB1 (32-bit / Real) |
%I0.0 | Input bit 0.0 |
%Q0.0 | Output bit 0.0 |
%M0.0 | Memory bit 0.0 |
%MW100 | Memory word 100 |
%MD100 | Memory double 100 |
The iot-communication library also accepts forms without %, such as DB1.DBW0, but the % prefix is recommended for consistency.
data_type / format Mapping
data_type | format | Mapping / Notes |
|---|---|---|
| Boolean / Bool | (empty) | DBX / Ix.y / Mx.y |
| Byte | B / BYTE | DBB / MB |
| Short / Int / Int16 | (empty) | DBW (signed 16-bit) |
| Int32 / DWord | DW / DWORD | DBD (signed 32-bit) |
| UInt32 | UDW | DBD (unsigned) |
| Float / REAL | REAL | DBD 32-bit IEEE float |
| Double / LREAL | LREAL | 8-byte area of a DB |
| String | STR[N] | S7 STRING (2-byte header + N bytes) |
Batch mode (IS_BATCH_MODE=true) + REQUEST_LIMIT=4 — a single read groups up to 4 addresses.
Common Errors and Fixes
| Message / Symptom | Cause | Fix |
|---|---|---|
| Connection refused | ISO-on-TCP (port 102) blocked | Enable "Permit access with PUT/GET" in TIA Portal |
Connection rejected by remote | rack/slot mismatch | Correct the values per the table above |
Address out of range | The DB is not in absolute addressing mode (Optimized) | In TIA Portal, DB properties → turn "Optimized block access" OFF |
| All values are 0 | Wrong DB number / offset | Verify by reading the same address in a TIA Portal watch table |
| Only Bool fails to read | .bit missing in %DB1.DBX0.0 | Write the DBX{byte}.{bit} notation exactly |
curl Registration Example
Example of reading a Real value and a Bool value from DB1 of an S7-1500:
curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_S7_LINE2",
"opc_type": "S7",
"opc_name": "Line2 S7-1500",
"opc_agent_ip": "192.168.0.70",
"opc_agent_port": "102",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"options": {
"controller-type": "S7_1500",
"local-rack": "0",
"local-slot": "0"
},
"tag_list": [
{
"tag_id": "OPC_S7_LINE2_TAG_00001",
"tag_name": "Pressure",
"plc_address": "%DB1.DBD0",
"data_type": "Float",
"format": "REAL"
},
{
"tag_id": "OPC_S7_LINE2_TAG_00002",
"tag_name": "RunFlag",
"plc_address": "%DB1.DBX10.0",
"data_type": "Boolean"
}
]
}'
Reading values:
curl -s http://<edge-host>/api/v1/tag/OPC_S7_LINE2_TAG_00001/value | jq
Example Collection (by Data Type)
The standard Siemens memory areas are DB / I / Q / M / T / C. The iot-communication library accepts the % prefix, as in %DB1.DBW0 (it works without it, but the prefix is recommended for consistency).
Bit / Bool (Boolean)
data_type | format | plc_address example | Meaning |
|---|---|---|---|
Boolean | (empty) | %DB1.DBX0.0 | Bit 0 of DB1 byte 0 |
Boolean | (empty) | %DB1.DBX10.7 | Bit 7 of DB1 byte 10 |
Boolean | (empty) | %I0.0 | Input bit 0.0 |
Boolean | (empty) | %Q0.0 | Output bit 0.0 |
Boolean | (empty) | %M0.0 | Memory bit 0.0 |
8 / 16-bit Integers
data_type | format | plc_address example | Meaning |
|---|---|---|---|
Integer | B | %DB1.DBB0 | byte (8-bit) |
Integer | BYTE | %MB10 | Memory byte 10 |
Integer | (empty) | %DB1.DBW0 | DB word (signed 16) |
Integer | (empty) | %MW100 | Memory word 100 |
32-bit Integers
data_type | format | plc_address example | Meaning |
|---|---|---|---|
Integer | DW | %DB1.DBD0 | DB double (signed 32) |
Integer | DWORD | %MD100 | Memory double 100 |
Integer | UDW | %DB1.DBD8 | unsigned 32 |
Floating Point (Float / Double)
data_type | format | plc_address example | Meaning |
|---|---|---|---|
Float | REAL | %DB1.DBD0 | IEEE 754 32-bit (DBD = 4 bytes) |
Float | REAL | %MD200 | Memory float 200 |
Double | LREAL | %DB1.DBD8 | IEEE 754 64-bit (8 bytes) |
Strings
data_type | format | plc_address example | Meaning |
|---|---|---|---|
String | STR[16] | %DB1.DBB100 | S7 STRING (max 16 chars), including the 2-byte header |
String | STR[32] | %DB2.DBB0 | S7 STRING, max 32 |
Using Formulas
| Purpose | data_type | fomula | Notes |
|---|---|---|---|
| Integer raw → scaled real value | Float | ${VALUE}*0.1 | DBW raw → measured value |
| Temperature correction | Float | ${VALUE}+${TAG_OFFSET} | Calibration |
| Pressure unit conversion (Pa → kPa) | Float | ${VALUE}/1000 | Unit conversion |
Comprehensive curl Example
curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_S7_FULL",
"opc_type": "S7",
"opc_name": "S7-1500 Full",
"opc_agent_ip": "192.168.0.70",
"opc_agent_port": "102",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"options": { "controller-type": "S7_1500", "local-rack": "0", "local-slot": "0" },
"tag_list": [
{"tag_id":"OPC_S7_FULL_T01", "tag_name":"DBBit", "plc_address":"%DB1.DBX0.0", "data_type":"Boolean"},
{"tag_id":"OPC_S7_FULL_T02", "tag_name":"InputBit", "plc_address":"%I0.0", "data_type":"Boolean"},
{"tag_id":"OPC_S7_FULL_T03", "tag_name":"DBByte", "plc_address":"%DB1.DBB1", "data_type":"Integer", "format":"B"},
{"tag_id":"OPC_S7_FULL_T04", "tag_name":"DBWord", "plc_address":"%DB1.DBW2", "data_type":"Integer"},
{"tag_id":"OPC_S7_FULL_T05", "tag_name":"DBDouble", "plc_address":"%DB1.DBD4", "data_type":"Integer", "format":"DW"},
{"tag_id":"OPC_S7_FULL_T06", "tag_name":"Pressure", "plc_address":"%DB1.DBD8", "data_type":"Float", "format":"REAL"},
{"tag_id":"OPC_S7_FULL_T07", "tag_name":"Power", "plc_address":"%DB1.DBD12", "data_type":"Double", "format":"LREAL"},
{"tag_id":"OPC_S7_FULL_T08", "tag_name":"BatchName", "plc_address":"%DB1.DBB100", "data_type":"String", "format":"STR[16]"},
{"tag_id":"OPC_S7_FULL_T09", "tag_name":"PressKpa", "plc_address":"%DB1.DBD8", "data_type":"Float", "format":"REAL", "fomula":"${VALUE}/1000"}
]
}'