# Data Collector Gateway HTTP API ## 文档用途 本文档用于说明 Data Collector Gateway 的 HTTP 接口,目标是让 AI 或自动化程序能够根据本文档直接构造请求、理解每个接口的用途、理解每个字段的含义,并正确解析返回结果。 当前接口支持通过 HTTP 调用 Modbus TCP 和 Siemens S7 TCP 设备。S7 详细请求和响应约定见 [s7-http-api.md](s7-http-api.md)。 ## 服务器请求地址 稳定环境服务器请求地址统一配置为: ```text http://127.0.0.1:8000 ``` 接口完整请求地址拼接规则: ```text 完整请求地址 = 服务器请求地址 + 接口路径 ``` 示例: ```text http://127.0.0.1:8000/api/dc-gateway/modbus/read ``` 如果部署到其他服务器,只需要替换服务器请求地址,例如: ```text http://<服务器IP或域名>:8000 ``` ## 通用约定 ### 请求格式 所有 `POST` 接口都使用 JSON 请求体,并且请求头必须包含: ```http Content-Type: application/json ``` ### 返回格式 除健康检查外,业务接口统一返回以下 JSON 结构: ```json { "code": 0, "msg": "success", "data": {} } ``` 字段说明: | 字段 | 类型 | 必定返回 | 含义 | |---|---|---:|---| | `code` | integer | 是 | 业务状态码。`0` 表示成功,`1` 表示失败。调用方应优先用该字段判断业务是否成功。 | | `msg` | string | 是 | 业务消息。成功时通常为 `success`,失败时为错误原因。 | | `data` | object | 是 | 业务数据对象。不同接口的字段不同。 | ### HTTP 状态码说明 接口校验失败、设备连接失败、Modbus 通信失败时,通常仍返回 HTTP `200`,业务是否成功由响应体中的 `code` 判断。 AI 调用接口时应按以下规则判断结果: 1. HTTP 请求失败或超时:认为网关服务不可达。 2. HTTP 返回成功但 JSON 中 `code = 0`:认为业务调用成功。 3. HTTP 返回成功但 JSON 中 `code != 0`:认为业务调用失败,失败原因读取 `msg`。 ## 接口列表 | 接口 | 方法 | 路径 | 用途 | |---|---|---|---| | 健康检查 | `GET` | `/api/dc-gateway/health` | 检查网关服务是否存活。 | | 原始 Modbus 读取 | `POST` | `/api/dc-gateway/modbus/read` | 读取 Modbus 数据,但不解析为业务值,只返回 Tx/Rx 通信报文。 | | 点位读取并转换 | `POST` | `/api/dc-gateway/modbus/read_points` | 按点位定义读取 Modbus 数据,并按数据类型转换为业务值。 | | 点位读取并转换别名 | `POST` | `/api/dc-gateway/modbus/read-points` | 与 `/api/dc-gateway/modbus/read_points` 等价,建议优先使用下划线版本。 | | 原始 S7 读取 | `POST` | `/api/dc-gateway/s7/read` | 读取 S7 原始字节,只返回语义化 `communication`。 | | S7 点位读取并转换 | `POST` | `/api/dc-gateway/s7/read_points` | 按点位定义读取 S7 数据,并按数据类型转换为业务值。 | | S7 连接扫描 | `POST` | `/api/dc-gateway/s7/connect_scan` | 只传 IP,扫描可用的 `rock`、`slot`、`tsap_conn_type` 组合。 | ## S7 接口快速说明 S7 `/s7/read` 接口的 `communication` 是基于 `python-snap7` 调用过程生成的语义化记录,不是底层真实 `TPKT + COTP + S7Comm` 原始网络帧。`/s7/read_points` 不返回 `communication`。 S7 通用设备字段: | 字段 | 类型 | 必填 | 默认值 | 允许值或范围 | 含义 | |---|---|---:|---|---|---| | `device_type` | string | 否 | `S7TCP` | 只能是 `S7TCP` | 设备协议类型。 | | `ip` | string | 是 | 无 | 合法 IPv4 或 IPv6 地址 | S7 设备 IP 地址。 | | `port` | integer | 否 | `102` | `1..65535` | S7 TCP 端口,通常固定为 `102`。 | | `rock` | integer | 是 | 无 | `0..31` | PLC rock。 | | `slot` | integer | 是 | 无 | `0..31` | PLC slot。 | | `tsap_conn_type` | string | 否 | `PG` | `PG`、`OP`、`BASIC` | Snap7 连接类型。 | S7 地址字段: | 字段 | 类型 | 必填 | 默认值 | 允许值或范围 | 含义 | |---|---|---:|---|---|---| | `area` | string | 是 | 无 | `DB`、`M`、`I`、`Q` | 读取区域。 | | `db` | integer | `area=DB` 时必填 | `0` | `>=0` | DB 块号,`area=DB` 时必须大于 `0`。 | | `start` | integer | 是 | 无 | `>=0` | 起始字节偏移。 | | `size` | integer | `/s7/read` 必填 | 无 | `1..65535` | 读取字节数。 | S7 连接扫描接口: ```http POST /api/dc-gateway/s7/connect_scan ``` 请求体: ```json { "ip": "192.168.1.10" } ``` 返回只包含可用连接组合: ```json { "code": 0, "msg": "success", "data": { "device": { "device_type": "S7TCP", "ip": "192.168.1.10", "port": 102 }, "available": [ { "rock": 0, "slot": 1, "tsap_conn_type": "PG" } ] } } ``` ## 通用设备字段 以下字段用于描述要连接的 Modbus TCP 设备,出现在 `/modbus/read` 和 `/modbus/read_points` 请求体的顶层。 | 字段 | 类型 | 必填 | 默认值 | 允许值或范围 | 含义 | |---|---|---:|---|---|---| | `device_type` | string | 否 | `ModbusTCP` | 只能是 `ModbusTCP` | 设备协议类型。当前仅支持 Modbus TCP。 | | `ip` | string | 是 | 无 | 合法 IPv4 或 IPv6 地址 | Modbus TCP 设备的 IP 地址,不是网关服务器地址。 | | `port` | integer | 是 | 无 | `1..65535` | Modbus TCP 设备监听端口。常见端口为 `502`,示例使用 `505`。 | | `word_byte_order` | string | 否 | `ABCD` | `ABCD`、`BADC`、`CDAB`、`DCBA` | 多寄存器数据的字节序和字序,用于 `int32`、`float32`、`int64`、`float64` 等寄存器值转换。 | | `address_base` | integer | 否 | `0` | `>= 0` | 地址偏移量。网关实际发送给 Modbus 协议的地址为 `address + address_base`。通常传 `0`。 | | `slave_id` | integer | 是 | 无 | `0..247` | Modbus 从站 ID,也称 Unit ID、Device ID 或 Slave Address。 | ### 地址规则 请求体中的 `address` 是调用方传入的逻辑地址。网关实际发送给 Modbus 协议的地址计算方式如下: ```text protocol_address = address + address_base ``` 如果设备文档给出的地址已经是从 `0` 开始的协议地址,则使用: ```json "address_base": 0 ``` 如果设备文档用 `40001` 表示第一个保持寄存器,调用方需要先换算为协议地址 `0`,再请求接口。不要直接把 `40001` 当作 `address` 传入,除非明确需要这种偏移行为。 ### word_byte_order 说明 `word_byte_order` 用于寄存器型多字节数据的转换。每个 Modbus 寄存器为 2 字节。 | 值 | 含义 | |---|---| | `ABCD` | 默认顺序。寄存器内字节不反转,寄存器顺序不反转。 | | `BADC` | 每个寄存器内的两个字节反转,寄存器顺序不反转。 | | `CDAB` | 寄存器顺序反转,寄存器内字节不反转。 | | `DCBA` | 每个寄存器内字节反转,同时寄存器顺序反转。 | ## Modbus 功能码 | `function_code` | Modbus 名称 | 读取对象 | 返回原始类型 | 点位类型限制 | |---:|---|---|---|---| | `1` | Read Coils | 线圈 | bit/boolean | `/read_points` 中只能使用 `bool`。 | | `2` | Read Discrete Inputs | 离散输入 | bit/boolean | `/read_points` 中只能使用 `bool`。 | | `3` | Read Holding Registers | 保持寄存器 | 16 位 register | 可使用寄存器型数据类型,也可使用 `bool` 读取寄存器整体或指定位。 | | `4` | Read Input Registers | 输入寄存器 | 16 位 register | 可使用寄存器型数据类型,也可使用 `bool` 读取寄存器整体或指定位。 | ## communication 字段格式 `communication` 只在 `/api/dc-gateway/modbus/read` 返回,用于记录本次 HTTP 请求期间网关与 Modbus 设备之间的原始通信报文。 示例: ```text Tx:001-00 00 33 00 00 00 06 01 03 00 00 00 04 Rx:002-00 00 33 00 00 00 0B 01 03 08 00 01 42 A8 00 00 40 F8 ``` 格式说明: | 片段 | 含义 | |---|---| | `Tx` | 网关发送给 Modbus 设备的 Modbus TCP ADU 报文。 | | `Rx` | Modbus 设备返回给网关的 Modbus TCP ADU 报文。 | | `001`、`002` | 当前 HTTP 请求内的报文序号,从 `001` 开始递增。 | | `-` 后内容 | 大写十六进制字节,字节之间使用空格分隔。 | 补充说明: | 规则 | 说明 | |---|---| | trace 隔离 | 每个 HTTP 请求都有独立的 trace,并发请求不会互相清空或串包。 | | 重试报文 | 如果底层 Modbus 客户端发生重试,`communication` 中可能出现多组 `Tx` 或 `Rx`。 | | 失败场景 | 如果设备无响应,可能只有 `Tx` 没有 `Rx`。 | ## 接口:健康检查 ### 基本信息 | 项 | 值 | |---|---| | 方法 | `GET` | | 路径 | `/api/dc-gateway/health` | | 完整地址 | `http://127.0.0.1:8000/api/dc-gateway/health` | | 请求体 | 无 | | 用途 | 判断 Data Collector Gateway HTTP 服务是否启动。 | ### 成功返回 ```json { "status": "ok" } ``` 返回字段说明: | 字段 | 类型 | 含义 | |---|---|---| | `status` | string | 服务状态。`ok` 表示 HTTP 服务存活。 | ### 调用示例 ```bash curl http://127.0.0.1:8000/api/dc-gateway/health ``` ## 接口:原始 Modbus 读取 ### 基本信息 | 项 | 值 | |---|---| | 方法 | `POST` | | 路径 | `/api/dc-gateway/modbus/read` | | 完整地址 | `http://127.0.0.1:8000/api/dc-gateway/modbus/read` | | Content-Type | `application/json` | | 用途 | 向 Modbus TCP 设备发起一次读取请求,只返回通信报文,不返回解析后的业务值。 | ### 请求体结构 ```json { "device_type": "ModbusTCP", "ip": "192.168.75.240", "port": 505, "word_byte_order": "ABCD", "address_base": 0, "slave_id": 1, "read": { "function_code": 3, "address": 0, "quantity": 4 } } ``` 顶层字段说明见“通用设备字段”。 `read` 字段说明: | 字段 | 类型 | 必填 | 默认值 | 允许值或范围 | 含义 | |---|---|---:|---|---|---| | `read` | object | 是 | 无 | 对象 | 本次读取的参数对象。 | | `read.function_code` | integer | 是 | 无 | `1`、`2`、`3`、`4` | Modbus 功能码,决定读取线圈、离散输入、保持寄存器或输入寄存器。 | | `read.address` | integer | 是 | 无 | `>= 0` | 起始地址。实际协议地址为 `read.address + address_base`。 | | `read.quantity` | integer | 是 | 无 | `1..125` | 读取数量。功能码 `1`、`2` 表示读取 bit 数量;功能码 `3`、`4` 表示读取 register 数量。 | ### 成功返回示例 ```json { "code": 0, "msg": "success", "data": { "device": { "device_type": "ModbusTCP", "ip": "192.168.75.240", "port": 505, "word_byte_order": "ABCD", "address_base": 0, "slave_id": 1 }, "communication": [ "Tx:001-00 00 33 00 00 00 06 01 03 00 00 00 04", "Rx:002-00 00 33 00 00 00 0B 01 03 08 00 01 42 A8 00 00 40 F8" ] } } ``` 成功返回字段说明: | 字段 | 类型 | 含义 | |---|---|---| | `code` | integer | `0` 表示读取成功。 | | `msg` | string | 成功时为 `success`。 | | `data.device` | object | 本次请求实际使用的设备连接参数。 | | `data.device.device_type` | string | 设备类型,当前固定为 `ModbusTCP`。 | | `data.device.ip` | string | 目标 Modbus 设备 IP。 | | `data.device.port` | integer | 目标 Modbus 设备端口。 | | `data.device.word_byte_order` | string | 本次请求使用的字节序设置。原始读取不解析值,但仍会回显该参数。 | | `data.device.address_base` | integer | 本次请求使用的地址偏移。 | | `data.device.slave_id` | integer | 本次请求使用的 Modbus 从站 ID。 | | `data.communication` | string[] | 本次 Modbus TCP 原始 Tx/Rx 报文列表。 | ### 失败返回示例 设备无响应或通信失败: ```json { "code": 1, "msg": "Modbus Error: [Input/Output] No response received after 3 retries, continue with next request", "data": { "device": { "device_type": "ModbusTCP", "ip": "192.168.75.240", "port": 505, "word_byte_order": "ABCD", "address_base": 0, "slave_id": 1 }, "communication": [ "Tx:001-00 00 33 00 00 00 06 01 03 00 00 00 04" ] } } ``` 请求字段校验失败: ```json { "code": 1, "msg": "read.quantity: Input should be less than or equal to 125", "data": { "communication": [] } } ``` 失败返回字段说明: | 字段 | 类型 | 含义 | |---|---|---| | `code` | integer | `1` 表示失败。 | | `msg` | string | 失败原因,可能是连接失败、Modbus 错误或请求字段校验错误。 | | `data.device` | object | 如果请求已经通过基础校验,通常会回显设备参数。 | | `data.communication` | string[] | 失败前已经捕获到的通信报文。字段校验失败时通常为空数组。 | ### 调用示例 ```bash curl -X POST http://127.0.0.1:8000/api/dc-gateway/modbus/read \ -H "Content-Type: application/json" \ -d '{ "device_type": "ModbusTCP", "ip": "192.168.75.240", "port": 505, "word_byte_order": "ABCD", "address_base": 0, "slave_id": 1, "read": { "function_code": 3, "address": 0, "quantity": 4 } }' ``` ## 接口:点位读取并转换 ### 基本信息 | 项 | 值 | |---|---| | 方法 | `POST` | | 推荐路径 | `/api/dc-gateway/modbus/read_points` | | 兼容路径 | `/api/dc-gateway/modbus/read-points` | | 完整地址 | `http://127.0.0.1:8000/api/dc-gateway/modbus/read_points` | | Content-Type | `application/json` | | 用途 | 按点位定义逐个读取 Modbus 数据,并把原始 bit/register 转换为 `bool`、`int16`、`float32` 等业务值。 | ### 请求体结构 ```json { "device_type": "ModbusTCP", "ip": "192.168.75.240", "port": 505, "word_byte_order": "ABCD", "address_base": 0, "slave_id": 1, "points": [ { "function_code": 3, "address": 7, "type": "int16" }, { "function_code": 3, "address": 1, "type": "float32" }, { "function_code": 3, "address": 10, "type": "bool", "bit": 2 }, { "function_code": 1, "address": 0, "type": "bool" } ] } ``` 顶层字段说明见“通用设备字段”。 `points` 字段说明: | 字段 | 类型 | 必填 | 默认值 | 允许值或范围 | 含义 | |---|---|---:|---|---|---| | `points` | object[] | 是 | 无 | 至少 1 个元素 | 点位读取定义列表。网关会按数组顺序逐个读取。 | | `points[].function_code` | integer | 是 | 无 | `1`、`2`、`3`、`4` | 当前点位使用的 Modbus 功能码。 | | `points[].address` | integer | 是 | 无 | `>= 0` | 当前点位起始地址。实际协议地址为 `points[].address + address_base`。 | | `points[].type` | string | 是 | 无 | `bool`、`int16`、`uint16`、`int32`、`uint32`、`int64`、`uint64`、`float32`、`float64` | 当前点位的数据类型。接口会按该类型决定读取寄存器数量和转换方式。输入会被转换为小写。 | | `points[].bit` | integer 或 null | 否 | `null` | `0..15` | 仅寄存器点位支持。用于从一个 16 位寄存器中取某一位并返回布尔值。功能码 `1`、`2` 不允许传 `bit`。 | ### 点位类型和读取长度 | `type` | 读取长度 | 可用功能码 | 返回 JSON 类型 | 含义 | |---|---:|---|---|---| | `bool` | 功能码 `1`、`2` 为 1 bit;功能码 `3`、`4` 为 1 register | `1`、`2`、`3`、`4` | boolean | 布尔值。寄存器点位未传 `bit` 时,寄存器值非 `0` 返回 `true`;传 `bit` 时读取指定位。 | | `int16` | 1 register | `3`、`4` | integer | 有符号 16 位整数。 | | `uint16` | 1 register | `3`、`4` | integer | 无符号 16 位整数。 | | `int32` | 2 registers | `3`、`4` | integer | 有符号 32 位整数。 | | `uint32` | 2 registers | `3`、`4` | integer | 无符号 32 位整数。 | | `float32` | 2 registers | `3`、`4` | number | IEEE 754 单精度浮点数。 | | `int64` | 4 registers | `3`、`4` | integer | 有符号 64 位整数。 | | `uint64` | 4 registers | `3`、`4` | integer | 无符号 64 位整数。 | | `float64` | 4 registers | `3`、`4` | number | IEEE 754 双精度浮点数。 | ### 点位校验规则 | 规则 | 说明 | |---|---| | `function_code` 必须合法 | 只能是 `1`、`2`、`3`、`4`。 | | 线圈和离散输入只能读布尔值 | 当 `function_code` 为 `1` 或 `2` 时,`type` 必须是 `bool`。 | | 线圈和离散输入不能使用 `bit` | 当 `function_code` 为 `1` 或 `2` 时,不能传 `bit`。 | | 寄存器点位可以使用 `bit` | 当 `function_code` 为 `3` 或 `4` 且 `type` 为 `bool` 时,可用 `bit` 读取寄存器指定位。 | | 不允许额外字段 | 请求对象中出现未定义字段会校验失败。 | ### 成功返回示例 ```json { "code": 0, "msg": "success", "data": { "device": { "device_type": "ModbusTCP", "ip": "192.168.75.240", "port": 505, "word_byte_order": "ABCD", "address_base": 0, "slave_id": 1 }, "points": [ { "function_code": 3, "address": 7, "type": "int16", "value": -321 }, { "function_code": 3, "address": 10, "type": "bool", "bit": 2, "value": true } ] } } ``` 成功返回字段说明: | 字段 | 类型 | 含义 | |---|---|---| | `code` | integer | `0` 表示所有点位读取和转换成功。 | | `msg` | string | 成功时为 `success`。 | | `data.device` | object | 本次请求实际使用的设备连接参数。 | | `data.points` | object[] | 点位读取结果数组,顺序与请求体 `points` 一致。 | | `data.points[].function_code` | integer | 该点位使用的 Modbus 功能码。 | | `data.points[].address` | integer | 该点位请求中的逻辑地址,不包含 `address_base` 偏移。 | | `data.points[].type` | string | 该点位的数据类型,返回为小写。 | | `data.points[].bit` | integer | 仅当请求点位传入 `bit` 时返回。 | | `data.points[].value` | boolean、integer 或 number | 转换后的点位值。具体 JSON 类型由 `type` 决定。 | ### 失败返回示例 设备连接失败: ```json { "code": 1, "msg": "failed to connect to 192.168.75.240:505", "data": { "device": { "device_type": "ModbusTCP", "ip": "192.168.75.240", "port": 505, "word_byte_order": "ABCD", "address_base": 0, "slave_id": 1 }, "points": [] } } ``` 读取部分点位后失败: ```json { "code": 1, "msg": "Modbus Error: [Input/Output] No response received after 3 retries, continue with next request", "data": { "device": { "device_type": "ModbusTCP", "ip": "192.168.75.240", "port": 505, "word_byte_order": "ABCD", "address_base": 0, "slave_id": 1 }, "points": [ { "function_code": 3, "address": 7, "type": "int16", "value": -321 } ] } } ``` 失败返回字段说明: | 字段 | 类型 | 含义 | |---|---|---| | `code` | integer | `1` 表示失败。 | | `msg` | string | 失败原因,可能是连接失败、Modbus 错误或请求字段校验错误。 | | `data.device` | object | 如果请求已经通过基础校验,通常会回显设备参数。 | | `data.points` | object[] | 失败前已成功读取的点位。字段校验失败或连接失败时通常为空数组。 | ### 调用示例 ```bash curl -X POST http://127.0.0.1:8000/api/dc-gateway/modbus/read_points \ -H "Content-Type: application/json" \ -d '{ "device_type": "ModbusTCP", "ip": "192.168.75.240", "port": 505, "word_byte_order": "ABCD", "address_base": 0, "slave_id": 1, "points": [ { "function_code": 3, "address": 7, "type": "int16" }, { "function_code": 3, "address": 1, "type": "float32" }, { "function_code": 1, "address": 0, "type": "bool" } ] }' ``` ## AI 调用决策指南 AI 或自动化程序选择接口时遵循以下规则: | 目标 | 应调用接口 | 原因 | |---|---|---| | 只想检查网关是否启动 | `GET /api/dc-gateway/health` | 不访问 Modbus 设备,只检查 HTTP 服务。 | | 需要查看原始 Modbus Tx/Rx 报文 | `POST /api/dc-gateway/modbus/read` | 返回 `communication`,适合调试通信、对比 Modbus Poll 报文。 | | 需要得到点位业务值 | `POST /api/dc-gateway/modbus/read_points` | 返回 `points[].value`,自动按类型转换。 | AI 构造请求时必须区分两个地址: | 地址 | 字段或配置 | 含义 | |---|---|---| | 网关服务器地址 | `http://127.0.0.1:8000` | HTTP API 服务地址,用于拼接请求 URL。 | | Modbus 设备地址 | 请求体 `ip` 和 `port` | 实际被读取的 Modbus TCP 设备地址。 | AI 构造 `/modbus/read_points` 点位时应按以下步骤: 1. 根据设备点表选择 `function_code`。 2. 将设备点表地址换算为从 `0` 开始的 Modbus 协议地址,填入 `address`。 3. 如果需要统一偏移,再设置 `address_base`,否则保持 `0`。 4. 根据点位数据类型设置 `type`。 5. 如果读取保持寄存器或输入寄存器中的某一位,设置 `type` 为 `bool` 并填写 `bit`。 6. 发送请求后检查响应体 `code`,不要只检查 HTTP 状态码。