2026年08月23日 23:23
本文档供 PLC、DCS、SCADA 等通过 Modbus-TCP 读取 DTS 设备温度与告警状态,并执行连接、启停、布防、消音、告警恢复等常用操作。
分区阈值、里程等详细配置仍建议通过 API.md HTTP 完成;Modbus 侧重轮询数据与现场常用控制。
状态:草案,尚未实现。寄存器地址与含义以正式发布版为准。
| 项目 | 说明 |
|---|---|
| 协议 | Modbus-TCP(从站 / Slave) |
| 地址 | <host>:502(<host> 与 HTTP 服务相同,默认端口 502) |
| Unit ID | 默认 1 |
| 读 | FC02 离散输入、FC04 输入寄存器 |
| 写 | FC05 写单线圈、FC06 写单寄存器、FC16 写多寄存器(可选) |
| 字节序 | 16 位寄存器大端;多字节数据高字节在前 |
| 温度格式 | UINT16,数值 = 摄氏度 × 10(例:623 → 62.3 ℃) |
| 用途 | 推荐接口 |
|---|---|
| 连接、启停采集、布防启停、消音、告警恢复 | Modbus(本文档)或 HTTP 均可 |
| 告警分区定义、阈值、起止里程 | HTTP GET/POST /api/v1/alarms |
| 采样点数、平均次数、完整配置、标定、光源 | HTTP(见 API.md) |
| 轮询各分区最高温、布防/告警状态 | Modbus |
1. (可选)HTTP 配置 samplePoints、avgCount
2. 写线圈 CMD_CONNECT,轮询 connected=1(首次可能需 60–90 s)
3. 写线圈 CMD_START,轮询 reading=1
4. 周期 FC04 读取温度与分区状态
5. 告警时:CMD_ALARM_MUTE 消音 / CMD_ALARM_ACK 确认恢复
6. 写线圈 CMD_STOP,必要时 CMD_DISCONNECT
亦可在步骤 1 前用 HTTP GET /api/v1/health 确认服务在线。
0xxxx、离散输入 1xxxx、输入寄存器 3xxxx、保持寄存器 4xxxx(均为 Modicon 1 基址)| 项目 | 上限 |
|---|---|
| 通道数 | 16(与配置中 channels[].channel 一致) |
| 每通道分区数 | 124(与 partitions[].partitionId 对应,建议 1–124) |
基址 PDU 0x0000(PLC 00001 起)。均为 上升沿触发:写 1(0xFF00)执行动作,设备完成后 自动清 0;正常空闲时读为 0。
| PDU | PLC | 名称 | HTTP 等价 | 说明 |
|---|---|---|---|---|
| 0 | 00001 | CMD_CONNECT |
POST /api/v1/connect |
连接采集卡及外设 |
| 1 | 00002 | CMD_DISCONNECT |
POST /api/v1/disconnect |
停止采集并断开 |
| 2 | 00003 | CMD_START |
POST /api/v1/acquisition/start |
开始采集;使用设备当前 samplePoints、avgCount |
| 3 | 00004 | CMD_STOP |
POST /api/v1/acquisition/stop |
停止采集 |
| 4 | 00005 | CMD_ALARM_ACK |
POST /api/v1/alarms/acknowledge |
告警恢复(确认) |
| 5 | 00006 | CMD_ALARM_MUTE |
POST /api/v1/alarms/mute |
消音 |
| 6 | 00007 | CMD_ARM_ENABLE |
POST /api/v1/alarms {"enabled":true} |
布防启用(全局) |
| 7 | 00008 | CMD_ARM_DISABLE |
POST /api/v1/alarms {"enabled":false} |
布防停止(全局撤防) |
说明:
CMD_START 使用设备当前 samplePoints、avgCount(IR 30005–30006 可读);修改请走 HTTP POST /api/v1/config 或 acquisition/start。CMD_CONNECT 已连接、CMD_START 已在采集时再次触发仍视为成功(幂等)。CMD_ALARM_ACK 与 alarmActive 位判断。除全局撤防外,可单独控制各通道是否参与布防(同 HTTP channels[].enabled):
| PDU | PLC | 名称 | 说明 |
|---|---|---|---|
| 0 | 40001 | channelArmedMask |
bit0–15 对应通道 1–16:1=启用布防,0=停止;写后持久生效 |
读回当前通道布防状态 → IR 30003(与写入值一致)。
基址 PDU 0x0000(PLC 40001)。Modbus 不提供 samplePoints、avgCount 写入。
| PDU | PLC | 名称 | 说明 |
|---|---|---|---|
| 0 | 40001 | channelArmedMask |
通道布防位掩码(§3.1) |
| 1–15 | 40002–40016 | 保留 | 读为 0,写入忽略 |
基址 PDU 0x0000(PLC 30001)。
| PDU | PLC | 类型 | 名称 | 说明 |
|---|---|---|---|---|
| 0 | 30001 | uint16 | systemStatus |
位域,见下表 |
| 1 | 30002 | uint16 | currentChannel |
最近更新温度数据的通道号;0=无 |
| 2 | 30003 | uint16 | channelArmedMask |
通道 1–16 布防状态(同 HR 40001) |
| 3 | 30004 | uint16 | channelAlarmMask |
通道 1–16 是否存在分区告警 |
| 4 | 30005 | uint16 | samplePoints |
当前采样点数 |
| 5 | 30006 | uint16 | avgCount |
当前平均次数 |
| 6–7 | 30007–30008 | — | 保留 | 读为 0 |
systemStatus 位定义:
| Bit | 名称 | 说明 |
|---|---|---|
| 0 | connected |
已连接 |
| 1 | reading |
正在采集 |
| 2 | alarmActive |
全局告警中 |
| 3 | alarmEnabled |
全局布防已启用 |
| 4 | muted |
蜂鸣器已消音 |
| 5–15 | — | 保留 |
| PDU | PLC | 名称 |
|---|---|---|
| 0 | 10001 | connected |
| 1 | 10002 | reading |
| 2 | 10003 | alarmActive |
| 3 | 10004 | alarmEnabled |
| 4 | 10005 | muted |
| 层级 | 条件(均为 true 时该分区视为布防) |
|---|---|
| 全局 | alarmEnabled = 1(CMD_ARM_ENABLE 或 HTTP enabled:true) |
| 通道 | channelArmedMask 对应 bit = 1 |
| 分区 | 已配置且 fixedTempEnabled 或 diffTempEnabled 为 true |
channel = 1 .. 16
partitionId = 1 .. 124
tempPDU = 0x0100 + (channel - 1) * 248 + (partitionId - 1)
tempPLC = 30129 + (channel - 1) * 248 + (partitionId - 1)
每通道 248 寄存器:124 温度 + 124 状态(§7)。
| 位置 | PDU | PLC |
|---|---|---|
| 通道 1,分区 1 温度 | 0x0100 | 30129 |
| 通道 1,分区 1 状态 | 0x017C | 30253 |
| 通道 2,分区 1 温度 | 0x01F8 | 30377 |
| 寄存器值 | 含义 |
|---|---|
0 – 65520 |
有效温度,℃ × 10 |
65534 (0xFFFE) |
分区未配置 |
65535 (0xFFFF) |
已配置暂无数据 |
statusPDU = 0x0100 + (channel - 1) * 248 + 124 + (partitionId - 1)
statusPLC = 30129 + (channel - 1) * 248 + 124 + (partitionId - 1)
| Bit | 名称 | 说明 |
|---|---|---|
| 0 | armed |
该分区已布防 |
| 1 | alarm |
告警中 |
| 2 | fixedTempAlarm |
定温告警 |
| 3 | diffTempAlarm |
差温告警 |
| 4–15 | — | 保留 |
| PLC 范围 | 读/写 | 内容 |
|---|---|---|
| 00001–00008 | 写(线圈) | 连接、启停、消音、恢复、布防启停 |
| 10001–10005 | 读 | 离散输入状态位 |
| 30001–30008 | 读 | 系统状态 |
| 40001 | 读写 | 通道布防掩码 |
| 30129 起 ×16 通道 | 读 | 每通道 124 温度 + 124 状态 |
from pymodbus.client import ModbusTcpClient
HOST, UNIT = "192.168.1.100", 1
client = ModbusTcpClient(HOST, port=502)
client.connect()
# 连接设备(线圈 00001)
client.write_coil(0, True, slave=UNIT)
# 启动采集(使用设备当前 samplePoints / avgCount)
client.write_coil(2, True, slave=UNIT) # 线圈 00003 CMD_START
# 读系统状态
rr = client.read_input_registers(0, 4, slave=UNIT)
status = rr.registers[0]
print("connected", bool(status & 1), "reading", bool(status & 2))
# 消音、告警恢复
client.write_coil(5, True, slave=UNIT) # CMD_ALARM_MUTE
client.write_coil(4, True, slave=UNIT) # CMD_ALARM_ACK
# 全局撤防 / 启用布防
client.write_coil(7, True, slave=UNIT) # CMD_ARM_DISABLE
client.write_coil(6, True, slave=UNIT) # CMD_ARM_ENABLE
# 仅启用通道 1、2 布防
client.write_register(0, 0x0003, slave=UNIT) # HR 40001
client.close()
Modbus-TCP = MBAP 头 7B + PDU。线圈写 ON 固定为 FF 00,OFF 为 00 00。
| 功能 | FC | 说明 |
|---|---|---|
| 读线圈 | 01 | 读命令位是否为 0 |
| 写单线圈 | 05 | 触发控制命令 |
| 读输入寄存器 | 04 | 读温度、状态 |
| 写单寄存器 | 06 | 写 HR |
请求:
00 01 00 00 00 06 01 05 00 00 FF 00
UID FC Addr ON
响应(回显请求表示受理):
00 01 00 00 00 06 01 05 00 00 FF 00
执行完成后线圈自动回到 0。读线圈:
请求: 00 02 00 00 00 06 01 01 00 00 00 01
响应: 00 02 00 00 00 04 01 01 01 00(00= 空闲)
使用设备当前 samplePoints、avgCount(可读 IR 30005–30006;修改请走 HTTP)。
请求:
00 03 00 00 00 06 01 05 00 02 FF 00
响应:
00 03 00 00 00 06 01 05 00 02 FF 00
停止(线圈 00004,PDU 3):
请求: 00 06 00 00 00 06 01 05 00 03 FF 00
响应: 00 06 00 00 00 06 01 05 00 03 FF 00
断开(线圈 00002,PDU 1):
请求: 00 07 00 00 00 06 01 05 00 01 FF 00
响应: 00 07 00 00 00 06 01 05 00 01 FF 00
请求:
00 08 00 00 00 06 01 05 00 05 FF 00
响应:
00 08 00 00 00 06 01 05 00 05 FF 00
消音后 systemStatus bit4 / 离散输入 10005 为 1。
请求:
00 09 00 00 00 06 01 05 00 04 FF 00
响应:
00 09 00 00 00 06 01 05 00 04 FF 00
确认后 alarmActive 在无新命中时清 0;若温度仍超阈可能再次告警。
布防启用(线圈 00007,PDU 6):
请求: 00 0A 00 00 00 06 01 05 00 06 FF 00
响应: 00 0A 00 00 00 06 01 05 00 06 FF 00
布防停止(线圈 00008,PDU 7):
请求: 00 0B 00 00 00 06 01 05 00 07 FF 00
响应: 00 0B 00 00 00 06 01 05 00 07 FF 00
读 systemStatus bit3:alarmEnabled 随之变为 1 或 0。
启用通道 1、2 布防,停用其余通道 → channelArmedMask = 0x0003:
请求:
00 0C 00 00 00 06 01 06 00 00 00 03
^PDU0=40001
响应:
00 0C 00 00 00 06 01 06 00 00 00 03
读回 IR 30003 应为 00 03。
请求:
00 0D 00 00 00 06 01 04 00 00 00 04
响应示例(已连接、采集中、布防启用、通道 1 布防):
00 0D 00 00 00 0B 01 04 08 00 0B 00 01 00 01 00 00
^^^^
bit0+1+3 → 0x000B
读通道 1 分区 1(PLC 30129,PDU 0x0100):
请求: 00 0E 00 00 00 06 01 04 01 00 00 01
响应(62.3 ℃):00 0E 00 00 00 05 01 04 02 02 6F
读通道 1 分区 1 状态(PLC 30253,PDU 0x017C):
请求: 00 0F 00 00 00 06 01 04 01 7C 00 01
响应(布防+告警):00 0F 00 00 00 05 01 04 02 00 03
请求: 00 10 00 00 00 06 01 04 01 00 00 7C
响应(节选):00 10 00 00 00 FB 01 04 F8 02 6F 02 58 FF FE ...
请求: 00 11 00 00 00 06 01 02 00 00 00 05
响应(connected+reading+alarmEnabled):00 11 00 00 00 04 01 02 01 13
| Modbus | HTTP |
|---|---|
CMD_CONNECT |
POST /api/v1/connect |
CMD_DISCONNECT |
POST /api/v1/disconnect |
CMD_START |
POST /api/v1/acquisition/start(body 可带 samplePoints/avgCount,Modbus 不带) |
CMD_STOP |
POST /api/v1/acquisition/stop |
CMD_ALARM_MUTE |
POST /api/v1/alarms/mute |
CMD_ALARM_ACK |
POST /api/v1/alarms/acknowledge |
CMD_ARM_ENABLE / CMD_ARM_DISABLE |
POST /api/v1/alarms {"enabled":true/false} |
HR / IR channelArmedMask |
POST /api/v1/alarms {"channels":[{"channel":1,"enabled":true}]} |
| 温度 / 分区状态 IR | WebSocket frame / alarm 汇总结果 |
| 现象 | 处理 |
|---|---|
| 写线圈无响应 | 检查 Unit ID、502 端口防火墙 |
CMD_CONNECT 后长期 connected=0 |
连接耗时较长,继续轮询 IR 30001 |
温度全为 0xFFFF |
确认已 CMD_START 且 reading=1 |
| 撤防后仍显示旧 alarm 位 | 执行 CMD_ALARM_ACK 并等待下一采集周期 |
| 需改采样点数、平均次数 | HTTP POST /api/v1/config 或 acquisition/start |
| 需改分区阈值、里程 | 使用 HTTP POST /api/v1/alarms |
| 需完整温度曲线 | HTTP WebSocket(见 API.md) |
文档版本:v1.2 草案 · 2026-08-24