# Data Collector Gateway 基于 FastAPI 的数据采集 HTTP 网关,用于通过 HTTP 接口读取 Modbus TCP、Siemens S7 TCP 和 BACnet/IP 设备。 ## 环境要求 - Python 3.12+ ## 安装 ```bash uv sync ``` ## 功能 - 原始 Modbus 读取,返回 Modbus Poll 风格的 `Tx/Rx` 通信报文 - 点位读取,并支持常见寄存器类型的数据转换 - 支持 Modbus 功能码 `1=线圈输入`、`2=离散量输入`、`3=保持寄存器`、`4=输入寄存器` - S7 原始字节读取,返回连接、读取、断开的语义化 `communication` - S7 点位读取和连接组合扫描 - BACnet/IP 点位读取,固定读取 `present-value` - BACnet/IP 点位搜索,读取设备 `object-list` 并返回点位基础信息和值 ## 运行 ```bash uvicorn main:app --host 0.0.0.0 --port 8000 ``` ## 接口 基础路径:`/api/dc-gateway` | 方法 | 路径 | 说明 | |---|---|---| | `GET` | `/health` | 健康检查 | | `POST` | `/modbus/read` | 原始 Modbus 读取,返回 `communication` 报文 | | `POST` | `/modbus/read_points` | 读取点位并返回转换后的值 | | `POST` | `/s7/read` | 原始 S7 字节读取,返回语义化 `communication` | | `POST` | `/s7/read_points` | 读取 S7 点位并返回转换后的值 | | `POST` | `/s7/connect_scan` | 扫描 S7 可用连接组合 | | `POST` | `/bacnet/read_points` | 读取 BACnet 点位 `present-value` | | `POST` | `/bacnet/search_points` | 搜索 BACnet 设备点位 | 示例: ```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 } }' ``` 完整请求和响应约定见 [docs/modbus-http-api.md](docs/modbus-http-api.md)、[docs/s7-http-api.md](docs/s7-http-api.md) 和 [docs/bacnet-http-api.md](docs/bacnet-http-api.md)。 ## 测试 编译检查: ```bash python -m compileall app main.py ``` 集成测试: ```bash python -m unittest discover -s intergration/modbus -p "test_*.py" python -m unittest discover -s intergration/s7 -p "test_*.py" python -m unittest discover -s intergration/bacnet -p "test_*.py" ``` Modbus API 集成测试会自动启动本项目 HTTP 服务,默认使用 `D:\Projects\BACnet-Client\autotest\Integration\modbus` 中相同的真实设备参数和点位地址。 S7 测试会在本机启动 `python-snap7` 模拟 server,不依赖真实 PLC。 BACnet API 集成测试默认使用真实设备 `192.168.75.240:47808`,设备号 `12345`。 环境变量: | 名称 | 默认值 | |---|---| | `DATA_COLLECTOR_BASE_URL` | `http://127.0.0.1:8000` | | `MODBUS_DEVICE_IP` | `192.168.75.240` | | `MODBUS_TCP_PORT` | `505` | | `MODBUS_SLAVE_ID` | `1` | | `BACNET_DEVICE_IP` | `192.168.75.240` | | `BACNET_DEVICE_ID` | `12345` | | `BACNET_PORT` | `47808` | | `BACNET_LOCAL_IP` | 自动按到目标设备的路由推断 | | `BACNET_LOCAL_MASK` | `24` | | `BACNET_LOCAL_PORT` | 自动选择空闲 UDP 端口 | | `REQUEST_TIMEOUT` | `20` |