# NexIoT-Simulator **Repository Path**: thingscan/NexIoT-Simulator ## Basic Information - **Project Name**: NexIoT-Simulator - **Description**: A single-process device simulator covering 4 industrial protocols, for integration development and testing against host systems such as ThingsBoard Gateway. - **Primary Language**: Python - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-08-28 - **Last Updated**: 2026-08-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # NexIoT Simulator(物联网协议模拟器) > **中文** | [English](./README.md) **一个单进程模拟 4 种工业协议的设备模拟器,用于 ThingsBoard Gateway 等上位系统的对接开发与测试。** `python -m app` 一键启动后,同时运行 Modbus TCP、OPC UA、BACnet、Siemens S7 四个协议服务器与一个 FastAPI 管理接口,附带 Vue 3 前端点位配置界面。所有点位数据通过 REST API 即可配置与修改,**最多 1 秒内在协议线侧生效**。
[![Python](https://img.shields.io/badge/Python-3.11-blue.svg)](https://www.python.org/) [![FastAPI](https://img.shields.io/badge/FastAPI-0.104+-009688.svg)](https://fastapi.tiangolo.com/) [![Vue](https://img.shields.io/badge/Vue-3.4%2B-42b883.svg)](https://vuejs.org/) [![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](LICENSE)
> 想看技术细节与内部机制?请阅读 [`doc/`](doc/README.md) 下的技术文档。 --- ## 目录 - [功能特性](#功能特性) - [界面预览](#界面预览) - [支持的协议与端口](#支持的协议与端口) - [快速开始](#快速开始) - [Docker 一键安装(推荐)](#docker-一键安装推荐) - [Docker Compose(开发方式)](#docker-compose开发方式) - [本地运行(Python + 前端)](#本地运行python--前端) - [使用说明](#使用说明) - [API 概览](#api-概览) - [技术文档](#技术文档) - [项目结构](#项目结构) - [测试与验证](#测试与验证) - [环境变量覆盖初始值](#环境变量覆盖初始值) - [常见问题](#常见问题) - [贡献指南](#贡献指南) - [许可证](#许可证) --- ## 功能特性 - **四大工业协议**:同时模拟 Modbus TCP(2 个从站)、OPC UA(2 个设备)、BACnet(15 个对象)、Siemens S7(4 个内存区域)设备。 - **配置即生效**:通过 REST API / 前端界面新建、修改、删除点位后,同步循环在 **≤1 秒** 内将值写入协议线侧(详见 [`doc/03-data-flow.md`](doc/03-data-flow.md))。 - **RPC 写入**:所有协议均支持原生写入(FC06/FC16、UA Write、BACnet WriteProperty、S7 write_area)及统一的 REST API 写入。 - **Web 管理界面**:Vue 3 + Pinia 前端,支持点位列表(按协议筛选)、详情、新建/编辑/删除、JSON 导入/导出。 - **完整 REST API**:点位 CRUD、值读写、导入导出、统计,附 Swagger 交互式文档。 - **灵活配置**:通过环境变量即可覆盖各协议初始值,无需重新构建镜像。 - **配置持久化**:点位配置与当前值自动保存到磁盘(默认 `./data/points.json`),容器重启 / 重建后自动恢复,无需重新配置。 - **开箱即用**:内置 49 个种子点位,涵盖多协议、多数据类型(bit/uint16/int32/float32/double/string/boolean 等)。 ## 界面预览 **Web 管理界面** —— 点位列表、按协议筛选、统计与操作: ![Web 管理界面](img/web-ui.png) **Modbus TCP 客户端读取**(线圈 / 离散输入 / 保持寄存器): ![Modbus 客户端](img/modbus.png) **OPC UA 客户端读取**(MyDevice / MyDevice1 节点): ![OPC UA 客户端](img/opcua.png) **S7 客户端读取**(I / Q / M 区)与 **DB1 数据块读取**: ![S7 DB1 读取](img/s7-db.png) ## 支持的协议与端口 | 协议 | 端口 | 传输 | 说明 | |------|------|------|------| | Modbus TCP | `502` | TCP | 2 个从站设备(unit 1 / 2),含线圈、离散输入、输入/保持寄存器 | | OPC UA | `53530` | TCP | `opc.tcp://0.0.0.0:53530/OPCUA/SimulationServer`,2 个设备 | | BACnet | `47808` | UDP | 设备实例 1234(SimBACnetDevice),15 个对象 | | S7 | `102` | TCP | Siemens S7 模拟,I / Q / M / DB1 四个内存区域 | | HTTP | `8000` | TCP | FastAPI 管理接口 + 前端页面(可用 `API_PORT` 环境变量修改) | > 端口多为 0–1024 特权端口(502 / 102),Linux 下直接本地运行需 root 权限,建议使用 [Docker 方式](#docker-一键安装推荐)。 ## 快速开始 ### Docker 一键安装(推荐) 直接运行预构建镜像,无需任何构建: ```bash docker run -d --name nexiot-simulator --restart unless-stopped \ -p 502:502 \ -p 53530:53530 \ -p 47808:47808/udp \ -p 102:102 \ -p 8000:8000 \ -v nexiot-data:/app/data \ crpi-pormt4sdd35mkqt3.cn-hangzhou.personal.cr.aliyuncs.com/jettzhan/nexiot-simulator ``` - `--restart unless-stopped`:容器退出后自动重新拉起,开机自启。 - `-v nexiot-data:/app/data`:命名卷持久化。点位配置与当前值存于其中,容器重启 / 重建后自动恢复;首次启动无文件时自动写入 49 个种子点位。 - 如需覆盖初始值,追加 `-e 变量=值`(如 `-e "MB_FLOAT_0=42.5"`),详见[环境变量覆盖初始值](#环境变量覆盖初始值)。 启动后: | 服务 | 地址 | |------|------| | Web 管理界面 | | | Swagger API 文档 | | | Modbus TCP | `localhost:502` | | OPC UA | `opc.tcp://localhost:53530/OPCUA/SimulationServer` | | BACnet | `localhost:47808` (UDP) | | S7 | `localhost:102` | ### Docker Compose(开发方式) 适合开发调试:从本机构建镜像并以 Compose 编排运行,`docker-compose.yml` 已配置好端口映射与命名卷 `nexiot-data`。 ```bash docker compose up -d --build ``` ### 本地运行(Python + 前端) 依赖 Python 3.11+ 与 Node.js 18+。 ```bash # 1. 安装后端依赖 pip install -r requirements.txt # 2. 启动模拟器(默认 API 端口 8000) python -m app # 或自定义 API 端口:API_PORT=8001 python -m app ``` 前端为可选构建(否则无 Web 界面,API 不受影响): ```bash cd frontend npm install npx vite build # 构建产物输出到 ../app/static,重启 app 后由 FastAPI 托管 # 开发模式(热更新,代理 /api → localhost:8000): npm run dev ``` ## 使用说明 1. 打开 查看点位列表与统计,按协议筛选点位。 2. 在界面中新建 / 编辑 / 删除点位,或导入/导出 JSON 配置(所有变更自动保存)。 3. 修改点位值后,OPC UA / BACnet / S7 / Modbus 会在 **≤1 秒** 内同步到协议线侧,可直接被 ThingsBoard Gateway 等客户端读取。 4. 下次启动 / 重启容器后,之前配置的点位与当前值会自动恢复。 5. 详细点位表(每个寄存器/节点的地址与初始值)见 [`doc/02-data-model.md`](doc/02-data-model.md)。 ## API 概览 Base URL:`http://:8000`,交互式文档:`http://:8000/docs`。 | 方法 | 路径 | 说明 | |------|------|------| | `GET` | `/api/points` | 点位列表 + 统计 | | `POST` | `/api/points` | 新建点位 | | `GET` | `/api/points/{id}` | 点位详情 + 当前值 | | `PUT` | `/api/points/{id}` | 更新点位 | | `DELETE` | `/api/points/{id}` | 删除点位 | | `DELETE` | `/api/points` | 清空全部点位 | | `GET` | `/api/points/{id}/value` | 读取当前值 | | `PUT` | `/api/points/{id}/value` | 写入当前值(RPC) | | `GET` | `/api/points/export` | 导出全部点位配置 | | `POST` | `/api/points/import` | 全量导入点位配置 | | `GET` | `/api/stats` | 点位统计 | **快速上手:** ```bash # 列出点位 curl http://localhost:8000/api/points # 写入 OPC UA 点位值(1s 内同步到 UA 节点) curl -X PUT http://localhost:8000/api/points/16/value \ -H "Content-Type: application/json" -d '{"value":200.5}' # 新建 Modbus 点位 curl -X POST http://localhost:8000/api/points \ -H "Content-Type: application/json" \ -d '{"name":"MB_Test","protocol":"modbus","modbus":{"unitId":1,"functionCode":"03","address":30,"dataType":"uint16","byteOrder":"AB"},"initialValue":777,"changeMode":"fixed"}' ``` 完整接口参考与请求/响应示例见 [`doc/05-api.md`](doc/05-api.md)。 ## 技术文档 系统设计、数据模型、生效机制、协议实现等详细说明记录在 [`doc/`](doc/README.md) 目录: | 文档 | 内容 | |------|------| | [doc/README.md](doc/README.md) | 技术文档索引与 30 秒架构速览 | | [01-architecture.md](doc/01-architecture.md) | 系统架构、技术栈、进程/线程模型、端口分配 | | [02-data-model.md](doc/02-data-model.md) | 点位数据模型、Registry 设计、49 个种子点位 | | [03-data-flow.md](doc/03-data-flow.md) | **核心**:数据流与"配置即生效"机制 | | [04-protocol-implementation.md](doc/04-protocol-implementation.md) | 四个协议服务器实现细节 | | [05-api.md](doc/05-api.md) | REST API 参考(含请求/响应示例) | | [06-run-deploy.md](doc/06-run-deploy.md) | 运行、前端构建、Docker 部署、环境变量覆盖 | | [07-verification.md](doc/07-verification.md) | 验证与测试方法(三层验证体系) | > 以上文档均提供英文版,见 [`doc/en/`](doc/en/README.md)(英文版 README 为默认主文档 [README.md](./README.md))。 ## 项目结构 ``` . ├── app/ # 后端(单进程运行) │ ├── __main__.py # 启动入口:加载持久化配置/种子数据 + 4 个服务器线程 + uvicorn │ ├── main.py # FastAPI 实例,挂载 /api 与静态资源 │ ├── api.py # REST 路由(点位 CRUD / 值读写 / 导入导出 / 统计) │ ├── registry.py # PointRegistry:内存点位配置 + 值存储(线程安全) │ ├── persistence.py # 点位配置与当前值的 JSON 持久化 │ ├── seed.py # 49 个种子点位 │ ├── static/ # 前端构建产物(由 FastAPI 托管在 /) │ └── servers/ # 四个协议服务器 │ ├── modbus_server.py │ ├── opcua_server.py │ ├── bacnet_server.py │ └── s7_server.py ├── frontend/ # Vue 3 + Pinia + Vite + TypeScript 前端 │ └── src/ │ ├── api/ # REST 封装(fetch) │ ├── stores/ # Pinia store(点位列表/筛选/详情/操作) │ ├── types/ # TypeScript 类型(与后端点位结构对应) │ └── components/ # StatsBar / PointList / PointDetail / PointModal ├── doc/ # 技术文档 ├── img/ # README 截图 ├── tests/ # 单元 / 集成测试(pytest) ├── verify_point_config.py # 点位配置生效验证脚本(需启动服务后运行) ├── Dockerfile └── docker-compose.yml ``` ## 测试与验证 项目采用三层验证体系(详见 [`doc/07-verification.md`](doc/07-verification.md)): ```bash # 1. 单元测试(37 项,无需启动服务) python -m pytest tests -v -p no:cacheprovider # 2. 线级综合测试(需先启动模拟器,162 项) python tests/test_all_protocols.py # 3. 点位配置生效验证(需先启动模拟器,10 项) python verify_point_config.py ``` 四个协议均已实测验证"API 配置 ≤1s 同步到线侧"(新建点位、改值、RPC 写入等),结论见 [`doc/07-verification.md`](doc/07-verification.md#6-已知结论验证过程中确认)。 ## 环境变量覆盖初始值 无需修改代码即可在 `docker-compose.yml` 或 shell 中覆盖各协议初始值: | 前缀 | 说明 | 示例 | |------|------|------| | `MB_*` | Modbus 初始值 | `MB_FLOAT_0=42.5`、`MB_COIL_BITS=1023` | | `UA_*` | OPC UA 变量值 | `UA_MyDevice_Temperature=30.0` | | `BAC_*` | BACnet 对象 presentValue | `BAC_AV_2=70.0`、`BAC_BV_1=inactive` | | `S7_*` | S7 内存区字节 | `S7_DB1_DBD0=99999`、`S7_M_0=255` | | `API_PORT` | FastAPI 端口(默认 8000) | `API_PORT=8001` | ```yaml # docker-compose.yml 示例 environment: - MB_FLOAT_0=42.5 # Modbus 第 1 个 float 改为 42.5 - UA_MyDevice_Count=999 # OPC UA MyDevice.Count 改为 999 - BAC_AV_2=70.0 # BACnet HumiditySetpoint 改为 70% - S7_DB1_DBD0=88888 # S7 DB1.DBD0 改为 88888 ``` 完整变量清单见 [`doc/06-run-deploy.md`](doc/06-run-deploy.md#5-环境变量覆盖初始值)。 ## 常见问题 **Q: Modbus / S7 端口启动失败(Permission denied)?** 端口 502 / 102 属于特权端口,Linux 下需 root 或使用 Docker(容器内以 root 运行)。 **Q: Docker 构建时基础镜像拉取失败?** 如网络受限无法访问 `python:3.11-slim`,将 `Dockerfile` 中的基础镜像替换为可访问的镜像源后重新构建。 **Q: 修改点位值后线侧没有变化?** - OPC UA / BACnet / S7 / Modbus 均通过每秒同步循环从 Registry 拉值,理论上 ≤1s 生效。 - 外部工具原生写入的值会被同步循环以 Registry 值覆盖,如需持久请通过 REST API 写入保持一致(详见 [`doc/03-data-flow.md`](doc/03-data-flow.md))。 **Q: 验证/联调时读到的数据是旧的?** 可能有残留的旧模拟器进程占用端口,清理后重启即可。 ## 贡献指南 欢迎提交 Issue 与 Pull Request。 - 提交 Bug 时请附上协议、端口、复现步骤与日志。 - 代码风格遵循 PEP 8;修改后请运行 `python -m pytest tests` 确保测试通过。 - 补充或修改协议行为时,请同步更新 [`doc/`](doc/README.md) 下对应的技术文档。 ## 许可证 本项目基于 [Apache License 2.0](LICENSE) 开源。