西门子 S7 驱动
概述
西门子 SIMATIC S7 系列(S7-300 / S7-400 / S7-1200 / S7-1500)的 ISO-on-TCP 通信。
| 项目 | 值 |
|---|---|
opc_type | S7 |
| 实现类 | plantpulse.driver.protocol.s7.S7_34_Driver |
| 库 | iot-communication (plantpulse.plc.protocol.s7) |
| read | ✅(批量模式) |
| write | ✅ (Boolean/Integer/Long/Float/Double/String) |
| 安全 | 无(TCP 直连,不支持 S7 安全通信) |
OPC 注册表单
| 字段 | 含义 | 示例 |
|---|---|---|
opc_agent_ip | PLC IP | 192.168.0.70 |
opc_agent_port | ISO-on-TCP 端口 | 102 |
timecycle | 轮询周期(ms) | 1000 |
options.controller-type | 系列 | S7_400 (default) / S7_300 / S7_200 / S7_200_SMART / S7_1200 / S7_1500 / SINUMERIK_828D |
options.local-rack | rack 号(兼容旧拼写错误的 local-lack) | 0 (default) |
options.local-slot | slot 号 | 3(S7-400 默认)/ 0 (S7-1200/1500) / 2 (S7-300) |
options.multi-read | 按分块单次往返批量 read(opt-in) | false (default) |
options.multi-read-max-items | 每个分块的条目数上限 | 18(default,PDU 240 预算) |
rack/slot
- S7-300 : rack=0, slot=2
- S7-400 : rack=0, slot=3(取决于 CPU 插槽)
- S7-1200 / 1500 : rack=0, slot=0(或 1)
标签 plc_address 格式
西门子标准内存地址表示法(DB / I / Q / M / T / C)。
| 表示 | 含义 |
|---|---|
%DB1.DBX0.0 | DB1 的 X0.0 位 (Bool) |
%DB1.DBB0 | DB1 的 byte 0 (8-bit) |
%DB1.DBW0 | DB1 的 word 0 (16-bit) |
%DB1.DBD0 | DB1 的 double word 0 (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 |
iot-communication 库也接受形如 DB1.DBW0 这种不带 % 的写法,但为保持一致性建议使用 % 前缀。
data_type / format 映射
data_type | format | 映射 / 备注 |
|---|---|---|
| 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 | DB 中的 8 字节区域 |
| String | STR[N] | S7 STRING(2 字节头 + N 字节) |
批量模式 (IS_BATCH_MODE=true) + REQUEST_LIMIT=4 —— 一次 read 最多合并 4 个地址。
常见错误与解决
| 消息 / 现象 | 原因 | 解决 |
|---|---|---|
| Connection refused | ISO-on-TCP(端口 102)被阻断 | 在 TIA Portal 中启用 “Permit access with PUT/GET” |
Connection rejected by remote | rack/slot 不匹配 | 参照上表更正 |
Address out of range | DB 未处于绝对地址模式(Optimized) | 在 TIA Portal 中 DB 属性 → 关闭 "Optimized block access" |
| 所有值为 0 | DB 号 / 偏移量错误 | 用 TIA Portal Watch table 对同一地址 read 验证 |
| 仅 Bool 读不到 | %DB1.DBX0.0 中缺少 .bit | 准确书写 DBX{byte}.{bit} 表示 |
curl 注册示例
读取 S7-1500 / DB1 的 Real 值与 Bool 值的示例:
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"
}
]
}'
值 read:
curl -s http://<edge-host>/api/v1/tag/OPC_S7_LINE2_TAG_00001/value | jq
示例集(按数据类型)
西门子标准内存区域为 DB / I / Q / M / T / C。iot-communication 库接受形如 %DB1.DBW0 的 % 前缀(不写也可工作,但为一致性建议使用)。
位 / 布尔 (Boolean)
data_type | format | plc_address 示例 | 含义 |
|---|---|---|---|
Boolean | (empty) | %DB1.DBX0.0 | DB1 byte0 的 bit 0 |
Boolean | (empty) | %DB1.DBX10.7 | DB1 byte10 的 bit 7 |
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 位整数
data_type | format | plc_address 示例 | 含义 |
|---|---|---|---|
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 位整数
data_type | format | plc_address 示例 | 含义 |
|---|---|---|---|
Integer | DW | %DB1.DBD0 | DB double (signed 32) |
Integer | DWORD | %MD100 | Memory double 100 |
Integer | UDW | %DB1.DBD8 | unsigned 32 |
实数 (Float / Double)
data_type | format | plc_address 示例 | 含义 |
|---|---|---|---|
Float | REAL | %DB1.DBD0 | IEEE 754 32-bit (DBD = 4 byte) |
Float | REAL | %MD200 | Memory float 200 |
Double | LREAL | %DB1.DBD8 | IEEE 754 64-bit (8 byte) |
字符串
data_type | format | plc_address 示例 | 含义 |
|---|---|---|---|
String | STR[16] | %DB1.DBB100 | S7 STRING(max 16 chars),含 2 字节头 |
String | STR[32] | %DB2.DBB0 | S7 STRING,max 32 |
Formula 应用
| 用途 | data_type | fomula | 备注 |
|---|---|---|---|
| 整数 raw → 实数换算 | Float | ${VALUE}*0.1 | DBW raw → 实测值 |
| 温度校正 | Float | ${VALUE}+${TAG_OFFSET} | 校准 |
| 压力单位换算 (Pa → kPa) | Float | ${VALUE}/1000 | 单位换算 |
curl 综合示例
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"}
]
}'