Profile
Back to NewsBack
GitHub Trending 11 min
Reader Mode
suoten/ProtoForge: ProtoForge: 零硬件仿真模拟 Modbus/S7/OPC-UA/BACnet 等28协议设备,测试上位机与网关通信。Python,开箱即用。

suoten/ProtoForge: ProtoForge: 零硬件仿真模拟 Modbus/S7/OPC-UA/BACnet 等28协议设备,测试上位机与网关通信。Python,开箱即用。

15 hours ago


🖥️ ProtoForge

一台电脑 = 28 种工业设备

零成本模拟 PLC、传感器、摄像头,测试你的上位机和物联网网关

Python</a> FastAPI</a> Vue</a> License</a> Docker</a>

🚀 在线体验 · 📖 5分钟上手 · 💬 加入QQ群 · English

⚠️ 唯一官方仓库声明:ProtoForge 的官方源码仓库仅有 github.com/suoten/ProtoForge(Gitee 镜像:gitee.com/suoten/ProtoForge),官方 Docker 镜像为 suoten/protoforge。GitHub/Gitee 上其他同名或改名的仓库均为第三方转载,内容可能滞后数月、缺失重要修复,请一律以本仓库为准。发现问题请到官方仓库提交 Issue。
✅ Windows · ✅ Linux · ✅ macOS
> 🔥 V1.3.0 工业标杆版 · 133 设备模板 · 28 种工业协议 · 设备/场景克隆 · 北向平台预设 · DAG 规则链编排 · 测试计划+合规检测 · EdgeLite 生态对接

!仪表盘


🔥 为什么选 ProtoForge?

💢 开发者的真实痛点

| # | 你遇到的痛点 | 有多痛 | ProtoForge 怎么解决 | |---|------------|--------|-------------------| | 1 | 协议报文对不上,不知道哪里错了 | 客户说读不到数据,你抓包看 hex 对了半天,3天找不到原因 | WebSocket 实时调试日志,按协议/方向/关键词筛选,点击查看报文详情,秒级定位问题 | | 2 | 模拟器太乖,上线就出事 | 测试环境永远返回正确值,上线后真实 PLC 断连/超时/返回异常码,全炸 | 内置9种故障注入:传感器卡死/漂移/噪声/失效、间歇断连/延迟/丢包、设备故障/执行器卡死,上线前测全异常场景 | | 3 | 测试全靠手点,回归一下午 | 每次改完代码:手动建设备→启动→读数据→验证,一个回归搞一下午 | 自动化测试引擎:13种断言、变量提取、测试套件、HTML报告+趋势分析,SDK一行代码跑全部测试 | | 4 | 客户现场出问题,没法复现 | 客户说昨天下午3点数据不对,没有录制,没法回放,只能猜 | 协议录制回放:录制通信报文→按需回放→验证修复,Gzip压缩存储 | | 5 | 新人不懂协议,教1周才干活 | 地址偏移、功能码、字节序全搞混,手把手教还是出错 | 每个协议内置4语言代码示例(Python/C#/Java/Go),133个模板即用型配置,照着抄就能干 | | 6 | 多协议联调,环境搭1周 | 同时测 Modbus+S7+MQTT,找3台不同厂商设备,配3套参数 | 28种协议一台电脑全搞定,Docker 30秒启动,一键生成100台虚拟设备 | | 7 | 协议安全不敢测 | OPC-UA证书/TLS加密/GB28181 SRTP,生产不敢动,测试又没有 | 证书自动生成、TLS加密、SRTP全支持,安全场景随便测 |

💰 硬件成本对比

| 场景 | 传统方式 | ProtoForge | |------|---------|------------| | 测 Modbus | 买 PLC(¥3000+) | 1 条命令启动虚拟设备 | | GB28181 联调 | 买摄像头(¥500+) | 自动注册、自动推流 | | 测 28 种协议 | 买各种厂商设备(¥50000+) | 一台电脑全部模拟 | | 压力测试 | 部署几十台物理设备 | 一键生成 100 台虚拟设备 | | 给客户演示 | 带一堆硬件出差 | 笔记本上完整演示 |


⚡ 30 秒启动(Docker 推荐)

docker run -d --name protoforge -p 8000:8000 -e PROTOFORGE_ADMIN_PASSWORD=admin -v protoforge-data:/app/data suoten/protoforge:latest

浏览器打开 http://localhost:8000,用 admin / admin 登录。

💡 第一次使用?这就是最简单的方式,不需要安装 Python、Node.js、Git。
> 🌐 http://localhost:8000 就是 Web 界面,不是只有 API。ProtoForge 的后端(FastAPI)会自动托管前端页面,不需要单独的 Nginx 或前端服务器。API 文档在 /docs,前端页面直接访问根路径 /。
> 🔐 密码说明:
- 上面的命令通过 -e PROTOFORGE_ADMIN_PASSWORD=admin 指定了密码为 admin
- 如果不加这个参数,系统会自动生成随机密码,查看方式:docker logs protoforge(找 Login: 那一行)
- 生产环境请务必修改为强密码

🎬 功能预览

📊 仪表盘 — 全局状态一目了然

设备总数、运行中协议、仿真场景、设备模板数量实时统计,快速操作入口一键触达。

!仪表盘

🔧 设备管理 — 所有仿真设备集中管控

支持按协议筛选、批量启停、快速创建。每台设备显示协议类型、在线状态、测点数量,支持测点读写、链路追踪、编辑配置。

!设备管理

🌐 协议服务 — 28 种工业协议一键启停

Modbus TCP/RTU、OPC-UA、MQTT、HTTP、GB28181、BACnet、Siemens S7、Mitsubishi MC、Omron FINS、Rockwell AB、OPC-DA、FANUC FOCAS、MTConnect、Mettler-Toledo、PROFINET IO、EtherCAT、IEC 60870-5-104、IEC 61850、CoAP、DDS,全部支持独立配置端口和高级参数。

!协议服务

🏭 仿真场景 — 组合多设备定义联动规则

创建场景、批量管理设备集合,支持导入导出,快速复现工厂环境。

!仿真场景

🎨 场景编排器 — 可视化拖拽设备拓扑

自由拖拽布局设备节点,直观展示设备间关系,支持保存布局、添加设备、一键启停整个场景。

!场景编排器

📦 模板市场 — 133 设备模板开箱即用

PLC、传感器、数控机床、IoT 设备、摄像头、楼宇设备、电力保护装置、IED、环境传感器等分类筛选,选择模板一键创建仿真设备。

!模板市场

🧪 仿真测试 — 自动生成测试用例

系统根据当前设备和场景自动生成测试任务,一键验证测点读写、场景启停、规则触发等功能。

!仿真测试

📋 测试计划 — 版本化测试用例管理

创建测试计划,定义测试套件和故障场景,一键执行并生成 JUnit XML / JSON / HTML 报告。支持克隆、版本管理、执行历史追踪,CI/CD 集成一行命令搞定。

🛡️ 合规检测 — 协议标准合规性验证

内置 Modbus TCP、S7、OPC-UA、IEC 104、MQTT 五大协议合规检测器,一键检测通信报文是否符合协议标准,生成合规评分和违规详情报告。

🐛 调试日志 — 实时协议报文追踪

WebSocket 零延迟推送,按协议/方向筛选,关键词搜索,支持暂停、导出 JSON,快速定位开发问题。

!调试日志

🔗 联调集成 — EdgeLite 网关无缝对接

对接 EdgeLite 网关,完成设备注册→连接→采集→验证→监控的完整联调链路,5 步可视化流程一目了然。

!联调集成

⚙️ 系统设置 — 可视化配置无需改代码

服务器端口、数据库路径、日志级别、CORS 源、InfluxDB 转发、协议端口等全部可在前端直接修改。

!系统设置

🛡️ 审计日志 — 全操作留痕

用户操作、资源变更全程记录,支持按用户名、操作类型、资源类型筛选审计。

!审计日志

💾 备份恢复 — 一键导出导入全库数据

将设备、场景、模板和审计日志导出为 JSON 备份文件,跨环境迁移、版本控制、灾难恢复轻松搞定。

!备份恢复


✨ 核心特性

  • 28 种工业协议 — Modbus TCP/RTU、OPC-UA(Server/Client)、MQTT、HTTP、GB28181、BACnet、Siemens S7/S7Comm-Plus、Mitsubishi MC、Omron FINS、Rockwell AB、OPC-DA、FANUC FOCAS、MTConnect、Mettler-Toledo、PROFINET IO、EtherCAT、IEC 60870-5-104、IEC 61850、CoAP、DDS、DLT/T 645、CJ/T 188、松下 MEWTOCOL、自定义 TCP/UDP
  • 全链路仿真 — 不只是模拟数据,完整模拟协议交互过程(如 GB28181:SIP注册→目录查询→INVITE→RTP视频推流→BYE)
  • 133 设备模板 — PLC、传感器、CNC、摄像头、HVAC、伺服驱动器、保护继电器、IED、环境传感器、微电网、智能电表、水/气/热表,选模板→起名字→一键创建
  • 实时调试日志 — WebSocket 实时推送协议交互报文,按协议/方向/关键词筛选,点击查看详情,快速定位开发问题
  • 可视化场景编排 — 可视化设备联动规则编辑器,支持阈值/值变化/定时/脚本四种规则类型
  • 一键仿真测试 — 自动生成测试用例,智能诊断问题
  • 数据转发 — InfluxDB / HTTP Webhook / 文件,一键对接
  • 协议录制回放 — 记录通信报文,按需回放验证,支持加密存储
  • Prometheus 指标 — 内置监控端点,对接 Grafana
  • JWT 认证 + RBAC — 4 种角色(admin/operator/user/viewer),100% API 端点权限覆盖,bcrypt 安全密码存储
  • API 限流保护 — 内置速率限制,防止暴力破解和滥用
  • 双数据库支持 — SQLite 开箱即用,PostgreSQL 生产级支持
  • EdgeLite 网关对接 — 设备配置中填写网关地址,自动注册到 EdgeLite
  • 可视化系统设置 — 前端直接修改端口和配置,无需改代码
  • 多语言 SDK — Python(同步/异步 90+ 方法,覆盖全部 API)、Java / Go / C#(核心方法:设备/场景/协议管理)
  • gRPC 远程管理 — 15 个 RPC 方法,支持跨语言远程调用
  • CSV 批量导入导出 — 设备配置一键导出 CSV,批量导入快速创建多台设备,跨环境迁移效率倍增
  • 录制回放压缩 — Gzip 压缩存储,节省磁盘空间
  • 数据库备份恢复 — 一键导出/导入全库数据 JSON
  • 协议安全增强 — OPC-UA 证书自动生成、MQTT TLS 加密、GB28181 SRTP、录制报文加密
  • K8s/Helm 部署 — 完整 Kubernetes 部署方案 + Helm Chart
  • IoT 测试平台 — 测试计划管理(版本化/克隆/执行历史)、协议合规检测(5 协议合规规则+评分报告)、JUnit/JSON/HTML 报告导出、CI/CD 集成(protoforge test run)
  • 故障切换 — 主备健康检查,自动晋升,回调通知
  • 前端国际化 — 中英文双语,一键切换
  • Docker 多架构 — 支持 amd64/arm64(通过 docker buildx 构建),CI 自动推送 Docker Hub + PyPI
*

📥 更多安装方式

方式二:一键脚本部署

✅ Windows · ✅ Linux · ✅ macOS

如果没有 Docker,也不想手动敲命令,用一键脚本。

第 1 步:下载项目代码

打开 ,点击页面上的绿色 "Code" 按钮 → 点击 "Download ZIP" → 把下载的 ZIP 文件解压到一个文件夹(比如桌面)。

第 2 步:运行安装脚本

  • Windows:进入解压出来的文件夹(通常叫 ProtoForge-main),双击 install.bat
  • Linux / macOS:打开终端,进入解压出来的文件夹(通常叫 ProtoForge-main),运行:
chmod +x install.sh
  ./install.sh

脚本会自动检测 Python 版本、创建虚拟环境、安装依赖、构建前端,然后自动启动服务。

启动后,浏览器打开 http://localhost:8000(即脚本窗口显示的地址),用 admin / 你设置的密码 登录。

🌐 http://localhost:8000 就是 Web 界面。后端自动托管前端,不需要 Nginx。
💡 如果脚本安装依赖时卡住不动,通常是网络问题。可以先设置国内镜像再重试:
>
> # pip 镜像(二选一,cmd 或 PowerShell 里运行)
> pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ > > # npm 镜像 > npm config set registry https://registry.npmmirror.com >

方式三:手动部署(开发者 / 高级用户)

✅ Windows · ✅ Linux · ✅ macOS

熟悉命令行的用户,或需要自定义配置。详细步骤见 DEPLOYMENT.md。

开机自启动与数据保存(Windows)

开机自动运行 ProtoForge — 点击展开

日常启动:双击项目文件夹里的 quickstart.bat 即可(自动检查环境 → 启动服务 → 提示访问地址)。窗口保持开着服务就在运行,关闭窗口或按 Ctrl+C 即停止。

开机自启:如果希望电脑开机登录后 ProtoForge 自动在后台运行(不弹黑框),双击 scripts\install_autostart.bat 安装即可:

scripts\install_autostart.bat   ← 双击,一键安装开机自启
  • 安装后会在你的"启动"文件夹放入一个隐藏启动脚本,每次开机登录后自动运行 ProtoForge
  • 卸载自启:按 Win + R,输入 shell:startup 回车,在打开的文件夹里删除 ProtoForge_AutoStart.vbs 即可
  • 自启运行日志在项目目录的 data\autostart.log,启动失败可以看这个文件排查
数据不会丢:所有配置(设备、测点、场景、模板、规则)都保存在项目目录的 data\protoforge.db(SQLite 数据库)中,与软件是否关闭、电脑是否重启无关。下次启动自动恢复所有设备和运行状态,不需要重新配置。
⚠️ 注意:升级版本时不要删除 data 文件夹;把它一起备份就能完整迁移所有配置。

Windows — 点击展开

git clone https://github.com/suoten/ProtoForge.git
cd ProtoForge
python -m venv venv
.\venv\Scripts\activate
pip install -e ".[all]"
cd web && npm install && npm run build && cd ..
protoforge demo

浏览器打开 http://localhost:8000,用 admin / admin 登录(demo 模式默认密码,旧数据也会自动同步)

可用环境变量 PROTOFORGE_ADMIN_PASSWORD 覆盖;正式模式(protoforge run)密码随机生成,见启动横幅

⚠️ 如果 .\venv\Scripts\activate 报错"在此系统上禁止运行脚本",以管理员身份打开 PowerShell,运行:
>
> Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
>
> 然后重新执行 activate。

Linux / macOS — 点击展开

git clone https://github.com/suoten/ProtoForge.git
cd ProtoForge
python3 -m venv venv
source venv/bin/activate
pip install -e ".[all]"
cd web && npm install && npm run build && cd ..
protoforge demo

或后台运行:protoforge demo -d

停止后台服务:protoforge stop

浏览器打开 http://localhost:8000,用 admin / admin 登录(demo 模式默认密码,旧数据也会自动同步)

可用环境变量 PROTOFORGE_ADMIN_PASSWORD 覆盖;正式模式(protoforge run)密码随机生成,见启动横幅

生产环境(Nginx + 域名 + PostgreSQL)— 点击展开

详见 DEPLOYMENT.md。大致流程:

  1. 安装系统依赖:python3、nodejs、nginx、postgresql
  2. 克隆代码 + 构建前端 + 安装后端依赖
  3. 配置 .env 数据库连接和端口
  4. 配置 Nginx 反向代理
  5. 用 systemd 或 supervisor 管理进程

*

📋 前置条件速查

| 需要安装的 | 方式一(Docker) | 方式二(一键脚本) | 方式三(手动) | | -------------- | :---------: | :-------: | :-----: | | Docker Desktop | ✅ 必须 | ❌ | ❌ | | Python 3.10+ | ❌ | ✅ 必须 | ✅ 必须 | | Node.js 18+ | ❌ | ⚠️ 可选¹ | ✅ 必须 | | Git | ❌ | ✅ 必须² | ✅ 必须 |

¹ 没装 Node.js 的话,脚本会自动使用仓库中已构建好的前端文件\
² 需要从 GitHub 下载项目代码(可以 git clone,也可以网页下载 ZIP)

各软件下载地址:

| 软件 | 下载链接 | 安装提示 | | ------------------ | ------------------------------------------------------------- | ---------------------------------------- | | Docker Desktop | docker.com | Windows 需启用 WSL2,macOS 直接装 | | Python | python.org | Windows 安装时务必勾选 "Add Python to PATH" | | Node.js | nodejs.org | 下载 LTS 版本(左边绿色按钮) | | Git | git-scm.com | 一路点 Next 就行 |

*

📦 可选:安装更多协议

pip install -e . 只安装核心协议(Modbus TCP/RTU、HTTP、GB28181、MC、FINS、AB、OPC-DA、FANUC、MTConnect、Toledo、PROFINET、EtherCAT、IEC 104、IEC 61850、CoAP、DDS、松下 MEWTOCOL 共 17 种,开箱即用)。以下 4 种协议需要额外依赖:

pip install -e ".[all]"        # 安装全部 28 种协议
pip install -e ".[opcua]"     # OPC-UA
pip install -e ".[mqtt]"      # MQTT
pip install -e ".[bacnet]"    # BACnet
pip install -e ".[s7]"        # Siemens S7

| 协议 | 需要额外安装? | 默认端口 | 说明 | | -------------- | ---------- | ----- | ---------------- | | Modbus TCP | 不需要 | 5020 | 工业标准通信协议 | | HTTP | 不需要 | 8080 | RESTful API 仿真 | | Modbus RTU | 不需要 | 串口 | 串口通信协议 | | GB28181 | 不需要 | 5060 | 视频监控国标协议 | | Mitsubishi MC | 不需要 | 5000 | 三菱 PLC SLMP 协议 | | Omron FINS | 不需要 | 9600 | 欧姆龙 PLC FINS 协议 | | Rockwell AB | 不需要 | 44818 | 罗克韦尔 EtherNet/IP | | OPC-DA | 不需要 | 51340 | OPC 经典数据访问 | | FANUC FOCAS | 不需要 | 8193 | FANUC CNC 数据采集 | | MTConnect | 不需要 | 7878 | 机床数据互联标准 | | Mettler-Toledo | 不需要 | 1701 | 称重仪表协议 | | PROFINET IO | 不需要 | 34964 | PI组织实时工业以太网协议 | | EtherCAT | 不需要 | 34980 | 倍福实时工业以太网协议 | | OPC-UA | [opcua] | 4840 | 统一架构协议 | | OPC-UA Client | [opcua] | 4840 | OPC-UA 客户端采集 | | MQTT | [mqtt] | 1883 | 物联网消息协议 | | BACnet | [bacnet] | 47808 | 楼宇自动化协议 | | Siemens S7 | [s7] | 102 | 西门子 PLC 协议 | | IEC 60870-5-104 | 不需要 | 2404 | 电力远动协议 (SCADA) | | IEC 61850 | 不需要 | 102 | 变电站自动化标准 (MMS) | | CoAP | 不需要 | 5683 | 受限 IoT 应用协议 (UDP) | | DDS | 不需要 | 7400 | 数据分发服务 (发布/订阅) | | 松下 MEWTOCOL | 不需要 | 2049 | 松下FP系列PLC协议 |

*

🚀 5 分钟上手

前提:已按上述任一方式完成部署,浏览器能打开
> 🌐 不想安装?直接体验演示站点:https://protoforge.jjtt.net/ 用户名:admin 密码:Protoforge123
  1. 登录 — 输入 admin / admin
  2. 启动协议 — 左侧菜单「协议服务」→ 点击「一键启动」
  3. 创建设备 — 左侧菜单「模板市场」→ 选择一个模板 → 填写名称 → 一键创建
  4. 查看数据 — 设备列表 → 点击「测点」→ 看到实时变化的仿真数据
  5. 运行测试 — 左侧菜单「仿真测试」→ 点击「一键测试全部」
⚠️ 页面空白? Docker 部署检查 docker logs protoforge。源码部署执行:cd web && npm install && npm run build,然后重启后端。
📖 需要更详细的操作指引? 请阅读完整的 操作手册,涵盖设备创建、协议连接、场景编排、故障注入、数据转发、调试排障等全流程。

*

🔗 与第三方系统对接

ProtoForge 是什么?—— 一句话搞懂

ProtoForge 是一台「虚拟设备工厂」。它启动标准协议服务端(Modbus TCP Server、OPC-UA Server、S7 Server……),任何能连接这些协议的软件都能直接对接,不需要任何适配层或特殊 SDK。

对接架构图

┌─────────────────────────────────┐
                    │        ProtoForge(仿真端)         │
                    │                                   │
                    │  Modbus TCP Server  ←─ 端口 5020  │
                    │  OPC-UA Server      ←─ 端口 4840  │
                    │  S7 Server          ←─ 端口 102   │
                    │  MQTT Broker        ←─ 端口 1883  │
                    │  HTTP Server        ←─ 端口 8080  │
                    │  GB28181 SIP        ←─ 端口 5060  │
                    │  ...(28 种协议服务端)              │
                    └──────────┬──────────────────────┘
                               │ 标准 TCP/UDP 协议通信
                               │(和真实设备一模一样)
          ┌──────────┬─────────┼─────────┬──────────┐
          ▼          ▼         ▼         ▼          ▼
     ┌─────────┐ ┌────────┐ ┌───────┐ ┌───────┐ ┌─────────┐
     │ EdgeLite│ │Kepware │ │Node-RED│ │Ignition│ │ 你的程序 │
     │  网关   │ │  网关  │ │       │ │ SCADA │ │(pymodbus│
     │         │ │        │ │       │ │       │ │  等)   │
     └─────────┘ └────────┘ └───────┘ └───────┘ └─────────┘
       自动注册      手动配置    手动配置   手动配置    直接连接

三种对接方式

| 方式 | 适合场景 | 怎么做 | |------|---------|--------| | ① 直接连接(推荐) | 你有自己的采集程序或网关 | ProtoForge 启动协议服务后,你的程序作为客户端连接对应端口即可(如 pymodbus 连 5020) | | ② EdgeLite 自动注册 | 你用 EdgeLite 做网关 | 设备配置中填 edgelite_url,ProtoForge 自动把设备配置推送到 EdgeLite,免手动配置 | | ③ 标准网关手动配置 | 你用 Kepware/Node-RED/Ignition 等第三方网关 | 在网关中手动添加设备,地址填 ProtoForge 的 IP 和端口(如 127.0.0.1:5020) |

方式 ①:直接连接(最通用)

ProtoForge 启动协议服务后,任何协议客户端都能直接连接。不需要在 ProtoForge 做任何额外配置。

# Python — 用 pymodbus 连接 ProtoForge 的 Modbus TCP 仿真设备
from pymodbus.client import ModbusTcpClient

client = ModbusTcpClient("127.0.0.1", port=5020) client.connect() result = client.read_holding_registers(address=100, count=2, device_id=1) print(f"温度: {result.registers}")

// Node.js — 用 mqtt 库连接 ProtoForge 的 MQTT 仿真设备
import mqtt from 'mqtt'
const client = mqtt.connect('mqtt://127.0.0.1:1883')
client.on('message', (topic, message) => {
  console.log(${topic}: ${message.toString()})
})
client.subscribe('sensor/temperature')
⚠️ MQTT 连接注意事项
> - 角色先分清:ProtoForge 的 MQTT 协议服务是一个仿真 Broker(服务器),不是连接外部服务器的客户端。高级配置里的 host/port 是 ProtoForge 自己监听的地址和端口(host 填 0.0.0.0 监听全部网卡),不是 EMQX 的地址——填了外部服务器 IP 会导致绑定失败、服务起不来。
- 想把设备数据上报到你自己的 EMQX/Mosquitto/阿里云 IoT? 不需要动协议服务的 host/port——在设备协议配置中填写「自定义 MQTT 服务器」(server_host / server_port,可选认证用户名密码),设备将以 MQTT 客户端身份连接并上报数据。
- 内置 MQTT Broker 仅支持 MQTT 3.1.1 协议,不支持 MQTT 5.0。MQTTX 等客户端连接时,请在连接设置中手动将 Protocol Version 选为 3.1.1(默认 5.0 会连接失败,这是最常踩的坑)。
- 开启认证后客户端必须携带用户名密码;auth_users 支持多账号,格式为 JSON:{"user1":"pass1"},留空则使用单账号配置。
- 其他协议的角色:Modbus / S7 / OPC-UA / IEC104 等协议中,仿真设备同样是"被访问的服务端"(由你的主站/网关连接设备),不存在"设备外连上报"的语义;若需把这些设备的数据推送到你自己的 HTTP 服务器,请使用平台的数据转发功能。GB28181 仿真设备则会主动向你配置的 SIP 平台注册。

📍 PLC 地址映射 — 精确到每个测点

ProtoForge 的每个测点都绑定了具体的 PLC 协议地址,你的上位机/网关按这个地址去读,和读真实 PLC 一模一样。

各协议地址格式

| 协议 | 地址格式 | 示例 | 说明 | | ---- | ------- | ---- | ---- | | Modbus TCP/RTU | 寄存器偏移量(数字) | address: "0" | 寄存器 40001(holding register),"2" = 40003。布尔量(bool)点位自动落线圈区(0xxxxx):主站用功能码 01 读线圈、05 写线圈,读保持寄存器(FC03)看不到布尔量点位 | | Siemens S7 | DB块.类型+偏移 | address: "DB1.DBD2" | DB块1,D=双字,偏移2字节;DBX = 位,DBW = 字 | | Omron FINS | 区域+地址 | address: "DM100" | DM区域地址100;CIO0 = CIO区域地址0 | | Mitsubishi MC | 设备号+地址 | address: "D100" | D寄存器100;M0 = 中间继电器0 | | OPC-UA | 节点ID | address: "ns=2;s=Temperature" | 命名空间2,节点名 Temperature | | IEC 60870-5-104 | ASDU地址 | address: "1" | IOA(信息对象地址)= 1 |

完整示例:智能水表模板(Modbus TCP)

设备模板中的测点定义:

{
  "name": "total_flow",
  "address": "0",           // ← Modbus 寄存器 40001
  "data_type": "float32",
  "unit": "m³",
  "generator_type": "increment",
  "min_value": 0,
  "max_value": 999999
}

你的采集程序这样读:

from pymodbus.client import ModbusTcpClient

client = ModbusTcpClient("127.0.0.1", port=5020) client.connect()

读 total_flow(address=0 → 寄存器 40001,float32 占 2 个寄存器)

result = client.read_holding_registers(address=0, count=2, slave_id=1)

解析 float32

value = struct.unpack('>f', struct.pack('>HH', *result.registers))[0] print(f"累计流量: {value} m³")

读 instant_flow(address=2 → 寄存器 40003)

result = client.read_holding_registers(address=2, count=2, slave_id=1)

同样解析 float32

完整示例:西门子 S7-1200 模板

{
  "name": "temperature",
  "address": "DB1.DBD2",     // ← DB块1,双字,偏移2
  "data_type": "real",
  "unit": "°C"
}

用 snap7 读取:

import snap7

client = snap7.client.Client() client.connect("127.0.0.1", 0, 1) # rack=0, slot=1

读 DB1.DBD2(Real/Float,4字节)

data = client.db_read(1, 2, 4) # db_number=1, start=2, size=4 temperature = snap7.util.get_real(data, 0) print(f"温度: {temperature} °C")

完整示例:欧姆龙 FINS 模板

{
  "name": "motor_speed",
  "address": "DM100",       // ← DM区域地址100
  "data_type": "int16"
}
💡 在 Web 界面查看地址:设备管理 → 点击「数据测点」→ 可以看到每个测点的名称、当前值、时间、质量。点击「编辑」设备可以查看和修改每个测点的协议地址、数据类型、生成器参数。
> 💡 自定义地址:创建设备时可以自由指定每个测点的 PLC 地址,完全匹配你真实设备的地址表。

Modbus 寄存器类型与功能码映射

ProtoForge 支持完整的 Modbus 四种寄存器区域,通过地址格式自动识别:

| 寄存器区域 | 地址格式示例 | Modbus 地址范围 | 功能码 | 说明 | | --------- | ----------- | -------------- | ------ | ---- | | 线圈 (Coil) | 0, 00001, 0x0, C0 | 00001–09999 | FC01 读 / FC05 写单 / FC0F 写多 | 位操作,可读可写 | | 离散输入 (Discrete Input) | 10001, 1x0, DI0 | 10001–19999 | FC02 读 | 位操作,只读 | | 输入寄存器 (Input Register) | 30001, 3x0, IR0, I0 | 30001–39999 | FC04 读 | 字操作,只读 | | 保持寄存器 (Holding Register) | 0, 40001, 4x0, HR0, H0 | 40001–49999 | FC03 读 / FC06 写单 / FC10 写多 | 字操作,可读可写 |

💡 纯数字地址的自动判断规则:bool 类型 → 线圈 (Coil);其他类型 → 保持寄存器 (Holding Register)。如果你想使用输入寄存器或离散输入,请使用 30001、10001 等 5 位 PLC 地址格式,或 IR0、DI0 等前缀格式。

数据类型与寄存器占用

不同数据类型占用的寄存器数量和字节序:

| 数据类型 | 字节数 | 占用寄存器数 | 字节序 | 适用协议 | | -------- | ----- | ----------- | ------ | ------- | | bool | 1 bit | 1 (位) | — | Modbus (Coil/DI)、S7 (DBX)、FINS (CIO bit) | | int16 | 2 | 1 | 大端序 (Big-Endian) | Modbus、S7 (DBW)、FINS、MC | | uint16 | 2 | 1 | 大端序 | Modbus、S7、MC | | int32 | 4 | 2 | 大端序 | Modbus、S7 (DBD)、MC | | uint32 | 4 | 2 | 大端序 | Modbus、S7、MC | | float32 | 4 | 2 | 大端序 (IEEE 754) | Modbus、S7 (DBD Real)、FINS、MC | | float64 | 8 | 4 | 大端序 (IEEE 754) | Modbus、S7 | | string | 可变 | 可变 (每寄存器 2 字节) | 大端序 (UTF-8) | Modbus、S7 | | real | 4 | 2 | 大端序 | S7 专用(等同 float32) |

⚠️ 字节序说明:ProtoForge 所有协议统一使用大端序 (Big-Endian),这是工业设备最常用的字节序。如果你的上位机使用小端序,需要在采集端做字节翻转。
> 例如:float32 值 1.0 在 ProtoForge 中存储为 0x3F800000,拆分为两个寄存器 → HR[n]=0x3F80, HR[n+1]=0x0000。用 pymodbus 读取后:struct.unpack('>f', struct.pack('>HH', 0x3F80, 0x0000)) → 1.0。

📋 从真实地址表创建设备教程

假设你有一份设备说明书上的 Modbus 地址表:

| 参数名 | Modbus 地址 | 数据类型 | 单位 | 读写 | | ------ | ----------- | -------- | ---- | ---- | | A相电压 | 40001 | float32 | V | RO | | B相电压 | 40003 | float32 | V | RO | | 有功功率 | 40005 | float32 | kW | RO | | 功率因数 | 40007 | float32 | - | RO | | 开关状态 | 00001 | bool | - | RW |

第 1 步:转换为 ProtoForge 地址格式

| 参数名 | 说明书地址 | ProtoForge address | data_type | | ------ | --------- | ------------------ | --------- | | A相电压 | 40001 | 0 (40001-40001=0) | float32 | | B相电压 | 40003 | 2 (40003-40001=0) | float32 | | 有功功率 | 40005 | 4 | float32 | | 功率因数 | 40007 | 6 | float32 | | 开关状态 | 00001 | 00001 或 0 | bool |

💡 5 位 PLC 地址自动转换:你也可以直接填 40001、30001、10001、00001,ProtoForge 会自动减去基地址(40001→偏移 0,30001→偏移 0)。

第 2 步:在 Web 界面创建设备

  1. 进入「设备管理」→ 点击「创建设备」
  2. 选择协议 modbus_tcp,填写设备名称
  3. 在测点配置中,逐条添加上表中的参数
  4. 设置 slave_id(如 1)
  5. 保存并启动设备
第 3 步:用你的采集程序验证
from pymodbus.client import ModbusTcpClient
import struct

client = ModbusTcpClient("127.0.0.1", port=5020) client.connect()

读 A相电压 (address=0, float32, 占2个寄存器)

result = client.read_holding_registers(address=0, count=2, slave_id=1) voltage_a = struct.unpack('>f', struct.pack('>HH', *result.registers))[0]

读 B相电压 (address=2)

result = client.read_holding_registers(address=2, count=2, slave_id=1) voltage_b = struct.unpack('>f', struct.pack('>HH', *result.registers))[0]

读开关状态 (address=00001 → coil 0)

result = client.read_coils(address=0, count=1, slave_id=1) switch_status = result.bits[0]

print(f"A相电压: {voltage_a}V, B相电压: {voltage_b}V, 开关: {'ON' if switch_status else 'OFF'}")

就是这么简单——ProtoForge 的地址和真实设备完全一致,你的采集代码不需要改一行。

Modbus RTU 串口配置

Modbus RTU 模板支持完整的串口参数配置:

{
  "protocol": "modbus_rtu",
  "protocol_config": {
    "slave_id": 2,
    "serial_port": "COM3",
    "baudrate": 9600,
    "databits": 8,
    "parity": "even",
    "stopbits": 1
  }
}

| 参数 | 说明 | 可选值 | 默认值 | | ---- | ---- | ------ | ------ | | serial_port | 串口设备路径 | Windows: COM3; Linux: /dev/ttyUSB0 | — | | baudrate | 波特率 | 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 | 9600 | | databits | 数据位 | 7, 8 | 8 | | parity | 校验位 | none, even, odd | even | | stopbits | 停止位 | 1, 1.5, 2 | 1 |

💡 无串口硬件也能用:ProtoForge 的 Modbus RTU 模式在没有物理串口时也可以启动(使用虚拟串口或 TCP-over-RTU 桥接)。在 Linux 上可以用 socat 创建虚拟串口:socat -d -d PTY,raw,echo=0 PTY,raw,echo=0。

多设备共存仿真

ProtoForge 支持在同一协议端口下同时仿真多台设备,就像一条 RS-485 总线上挂多个从站:

Modbus 多 Slave 共存:

设备A: slave_id=1, 协议=modbus_tcp, 端口=5020
设备B: slave_id=2, 协议=modbus_tcp, 端口=5020  ← 同端口不同 slave_id
设备C: slave_id=3, 协议=modbus_tcp, 端口=5020

采集程序通过 slave_id 区分不同设备:

# 读设备A的数据
result = client.read_holding_registers(address=0, count=2, slave_id=1)

读设备B的数据

result = client.read_holding_registers(address=0, count=2, slave_id=2)
💡 每个 Modbus 设备在创建时可以指定不同的 slave_id,它们共享同一协议端口但拥有独立的数据空间。

S7/OPC-UA/MQTT 等协议多设备:每种协议都支持在同端口下创建多台虚拟设备,通过设备名/节点空间区分。

写入行为说明

当你的采集程序向 ProtoForge 写入数据时,行为与真实 PLC 完全一致:

| 操作 | ProtoForge 响应 | 后续读取行为 | | ---- | --------------- | ----------- | | 写单个线圈 (FC05) | 返回正常响应(回显地址+值) | 读该地址返回写入的值 | | 写多个线圈 (FC0F) | 返回正常响应(回显起始地址+数量) | 读该地址范围返回写入的值 | | 写单个寄存器 (FC06) | 返回正常响应(回显地址+值) | 读该地址返回写入的值 | | 写多个寄存器 (FC10) | 返回正常响应(回显起始地址+数量) | 读该地址范围返回写入的值 | | 读写多个寄存器 (FC17) | 返回读部分的值 | 写入部分同时生效 | | 掩码写寄存器 (FC16) | 返回正常响应 | 按掩码 AND/OR 逻辑更新寄存器 |

⚠️ 写入与生成器的关系:如果测点配置了 generator_type(如 random、sine),生成器会在每次更新周期覆盖写入的值。要保留写入值,请将 generator_type 设为 fixed。

数据更新频率与生成器

每个测点可以配置数据生成器来模拟真实设备的变化行为:

| 生成器类型 | 说明 | 关键参数 | 适用场景 | | ---------- | ---- | -------- | ------- | | fixed | 固定值 | fixed_value | 状态量、开关 | | random | 随机值 | min_value, max_value | 传感器噪声模拟 | | sine | 正弦波 | min_value, max_value, period | 周期性变化量 | | increment | 递增值 | min_value, max_value, step | 流量计、计数器 | | ramp | 线性变化 | start_value, end_value, duration | 渐变过程模拟 |

{
  "name": "temperature",
  "address": "0",
  "data_type": "float32",
  "generator_type": "sine",
  "min_value": 20.0,
  "max_value": 80.0,
  "period": 60,
  "update_frequency": 1.0
}

| 参数 | 说明 | 默认值 | | ---- | ---- | ------ | | update_frequency | 数据更新频率(秒/次) | 1.0(1秒更新一次) | | period | 正弦周期(秒) | 60 | | step | 递增步长 | 1.0 | | duration | 渐变持续时间(秒) | 10 |

💡 update_frequency 决定了数据多久变化一次。设为 0.5 表示每 0.5 秒更新一次(2Hz),设为 5 表示每 5 秒更新一次。这与真实设备的采样周期类似。

方式 ②:EdgeLite 自动注册(便捷)

如果你用 EdgeLite 做网关,ProtoForge 可以自动把设备配置推送过去,免去手动在 EdgeLite 中添加设备的步骤。详见下方 EdgeLite 网关对接 章节。

方式 ③:标准网关手动配置(Kepware / Node-RED / Ignition 等)

以 Kepware 为例:

  1. ProtoForge 中启动 Modbus TCP 协议服务(默认端口 5020)
  2. ProtoForge 中创建一台 Modbus 设备(记住 slave_id 和测点地址)
  3. Kepware 中新建一个 Modbus TCP 驱动,IP 填 ProtoForge 所在机器 IP,端口填 5020
  4. Kepware 中新建设备,slave_id 与 ProtoForge 中一致
  5. Kepware 中添加点位,地址与 ProtoForge 中一致
就是这么简单——ProtoForge 对你的网关来说,和一台真实 PLC 没有任何区别。
💡 核心理解:ProtoForge 不是网关,不采集数据,不转发数据。它是「被采集的对象」——一台虚拟设备。你的网关/SCADA/采集程序去连它,就像连真实设备一样。

*

🔗 EdgeLite 网关对接

ProtoForge 支持将模拟设备自动注册到 EdgeLite 物联网网关,和 GB28181 填「上级SIP服务器地址」一样的体验:

GB28181:设备 protocol_config 填 sip_server_addr → 自动注册到国标平台
EdgeLite:设备 protocol_config 填 edgelite_url → 自动注册到 EdgeLite 网关

使用方式:创建设备时,在协议配置中填写 EdgeLite 网关地址即可:

| 字段 | 说明 | 示例 | | ------------------- | ------------- | --------------------------- | | edgelite_url | EdgeLite 网关地址 | http://192.168.1.200:8100 | | edgelite_username | 用户名 | admin | | edgelite_password | 密码 | admin123 |

不填就不推送,不影响 ProtoForge 正常使用。详见 INTEGRATION.md。

🔌 EdgeLite 联合一键部署(推荐)

不想手动配置两套系统?ProtoForge 提供 docker-compose.joint.yml,一条命令同时启动 ProtoForge + EdgeLite + MQTT + InfluxDB,开箱即用联调。

第 1 步:准备配置文件

# 复制环境变量模板
cp .env.joint.example .env.joint

用编辑器打开 .env.joint,把所有 change_me_* 改成你自己的密码

重点修改这几项:

PROTOFORGE_ADMIN_PASSWORD=你的强密码

PROTOFORGE_JWT_SECRET=至少32位随机字符串

EDGELITE_ADMIN_PASSWORD=你的强密码

SECRET_KEY=至少32位随机字符串

💡 JWT 密钥可以用这个命令生成:python -c "import secrets; print(secrets.token_urlsafe(32))"

第 2 步:一键启动

docker compose -f docker-compose.joint.yml --env-file .env.joint up -d

等待 30 秒让所有服务就绪,然后:

  • ProtoForge 界面:http://localhost:8000 (用 .env.joint 里的 PROTOFORGE_ADMIN_PASSWORD 登录)
  • EdgeLite 界面:http://localhost:8081 (用 .env.joint 里的 EDGELITE_ADMIN_PASSWORD 登录)

第 3 步:验证联调

  1. 打开 ProtoForge(http://localhost:8000),创建一台 Modbus 设备,在协议配置中填写:
edgelite_url: http://edgelite:8100
   edgelite_username: admin
   edgelite_password: (你在 .env.joint 里设的 EDGELITE_ADMIN_PASSWORD)
  1. 启动设备的 Modbus 协议,ProtoForge 会自动把设备推送到 EdgeLite
  2. 打开 EdgeLite(http://localhost:8081),在设备列表中能看到刚推送的设备,数据实时采集
🔍 也可以调用 ProtoForge 的 API 一键验证全链路:
> curl -X POST http://localhost:8000/api/v1/edgelite/verify-pipeline \
> -H "Authorization: Bearer <你的token>" \ > -H "Content-Type: application/json" \ > -d '{"device_id": "你的设备ID", "auto_fix": true}' >
返回 {"ok": true} 说明认证→注册→连接→采集四步全通。

📋 端口映射表

联合部署后,以下端口被占用(如需修改请在 .env.joint 中调整):

| 服务 | 端口 | 说明 | |------|------|------| | ProtoForge Web/API | 8000 | 主界面 + REST API | | ProtoForge Modbus TCP | 5020 | Modbus 仿真设备 | | ProtoForge OPC-UA | 4840 | OPC-UA 仿真设备 | | ProtoForge MQTT | 1883 | MQTT 仿真设备 | | ProtoForge HTTP | 8080 | HTTP Webhook 仿真 | | EdgeLite Web/API | 8081 | EdgeLite 管理界面(避让 ProtoForge 8080) | | EdgeLite MQTT | 1884 | EdgeLite MQTT 服务(避让 ProtoForge 1883) | | InfluxDB | 8086 | 时序数据库 |

🛠 故障排查 FAQ

Q: 启动时报端口占用? A: 检查本机是否已有其他服务占用上述端口。Windows 用 netstat -ano | findstr :8000,Linux 用 lsof -i:8000。可在 .env.joint 中修改端口映射。

Q: EdgeLite 设备列表里看不到推送的设备? A: ① 确认设备协议配置里的 edgelite_url 填的是 http://edgelite:8100(容器内网名),不是 localhost;② 在 ProtoForge 调用 verify-pipeline API 看具体哪一步失败;③ 查看 EdgeLite 日志 docker compose -f docker-compose.joint.yml logs edgelite。

Q: 联调 API 返回 401? A: EdgeLite 密码不匹配。确认设备配置里的 edgelite_password 与 .env.joint 中的 EDGELITE_ADMIN_PASSWORD 一致。首次登录 EdgeLite 可能要求改密码,改完后同步更新 ProtoForge 设备配置。

Q: 停止联合部署? A: docker compose -f docker-compose.joint.yml down(加 -v 会同时删除数据卷,谨慎使用)。

*

🔗 全链路仿真

ProtoForge 不只是模拟数据值,而是完整模拟协议交互过程,让你在开发时就能发现通信链路中的问题。

GB28181 视频监控全链路

1. SIP REGISTER ──→ 上级平台(自动注册,支持 Digest 认证)
  1. ←── MESSAGE Catalog(自动响应设备目录查询)
  2. ←── INVITE(收到实时视频请求)
  3. ──→ 200 OK + SDP(媒体协商应答)
  4. ←── ACK
  5. ══════════════► RTP/PS 视频流(25fps,352×288 CIF)
  6. ←── BYE(停止视频,自动停止推流)

其他协议全链路

| 协议 | 仿真链路 | 使用方式 | | ---------- | ------------------------- | ------------------- | | Modbus TCP | 客户端连接→读寄存器→写寄存器→断开 | 你的程序作为 Modbus 客户端连接 | | MQTT | Broker启动→客户端订阅→数据发布→客户端收到 | 你的程序作为 MQTT 客户端连接 | | OPC-UA | 客户端连接→浏览节点→读写值→断开 | 你的程序作为 OPC-UA 客户端连接 | | S7 | 客户端连接→读DB块→写DB块→断开 | 你的程序作为 S7 客户端连接 | | HTTP | GET/POST请求→JSON响应 | 直接请求 API |

*

🐛 开发调试

ProtoForge 内置实时协议调试日志,帮你快速定位开发中的通信问题:

  1. 打开左侧菜单「调试日志」
  2. 实时查看所有协议的收发消息(WebSocket 推送,零延迟)
  3. 按协议筛选(只看 GB28181 / Modbus / MQTT...)
  4. 按方向筛选(← 收 / → 发 / 系统)
  5. 关键词搜索(搜索 "error"、"register"、"invite"...)
  6. 点击任意日志 → 查看完整 detail 信息
  7. 暂停日志流 → 仔细分析某条消息
  8. 导出为 JSON → 离线分析或分享
*

⚙️ 配置说明

所有配置项均可在 .env 文件中修改,也可登录后台在「系统设置」页面直接修改。

# .env 文件示例
PROTOFORGE_HOST=0.0.0.0          # Web 服务监听地址
PROTOFORGE_PORT=8000             # Web 服务端口
PROTOFORGE_DB_PATH=data/protoforge.db  # 数据库路径(SQLite 或 PostgreSQL)
PROTOFORGE_JWT_SECRET=           # JWT 密钥(留空自动生成,生产环境建议设置)
PROTOFORGE_ADMIN_PASSWORD=admin  # 管理员密码(不设置则自动生成随机密码,生产环境务必设置强密码!)
PROTOFORGE_DEMO_MODE=false       # 演示模式
PROTOFORGE_LOG_LEVEL=info        # 日志级别
PROTOFORGE_GRPC_PORT=0           # gRPC 端口(0=禁用,设为 50051 启用)

协议端口(修改后需重启对应协议生效)

PROTOFORGE_MODBUS_TCP_PORT=5020 PROTOFORGE_OPCUA_PORT=4840 PROTOFORGE_MQTT_PORT=1883 PROTOFORGE_HTTP_PORT=8080 PROTOFORGE_GB28181_PORT=5060

端口说明

| 端口 | 服务 | 说明 | | ----- | -------------- | ----------------------------------- | | 8000 | Web API + 前端 | 主服务端口,浏览器访问此端口 | | 5020 | Modbus TCP | 工业标准通信协议 | | 4840 | OPC-UA | 统一架构协议(需 [opcua]) | | 1883 | MQTT | 物联网消息协议(需 [mqtt]) | | 8080 | HTTP | RESTful API 仿真 | | 5060 | GB28181 | 视频监控国标协议(TCP + UDP) | | 47808 | BACnet | 楼宇自动化协议(UDP,需 [bacnet]) | | 102 | Siemens S7 | 西门子 PLC 协议(需 [s7]) | | 5000 | Mitsubishi MC | 三菱 PLC SLMP 协议 | | 9600 | Omron FINS | 欧姆龙 PLC FINS 协议 | | 44818 | Rockwell AB | 罗克韦尔 EtherNet/IP | | 51340 | OPC-DA | OPC 经典数据访问 | | 8193 | FANUC FOCAS | FANUC CNC 数据采集 | | 7878 | MTConnect | 机床数据互联标准 | | 1701 | Mettler-Toledo | 称重仪表协议 | | 34964 | PROFINET IO | PI组织实时工业以太网协议 | | 34980 | EtherCAT | 倍福实时工业以太网协议 | | 2404 | IEC 60870-5-104 | 电力远动协议(SCADA) | | 102 | IEC 61850 | 变电站自动化标准(MMS) | | 5683 | CoAP | 受限 IoT 应用协议(UDP) | | 7400 | DDS | 数据分发服务(发布/订阅) | | 50051 | gRPC | 远程管理接口(默认禁用,设 GRPC_PORT=50051 启用) |

数据库配置

SQLite(默认,适合开发和单机部署):

PROTOFORGE_DB_PATH=data/protoforge.db

PostgreSQL(生产环境推荐):

# 安装 PostgreSQL 支持
pip install -e ".[postgres]"

配置连接字符串

PROTOFORGE_DB_PATH=postgresql://user:password@localhost:5432/protoforge

*

🔔 Webhook 通知和告警规则

ProtoForge 内置 Webhook 通知和告警反应规则系统,支持事件驱动的自动化。

Webhook 通知系统:

```bash

创建 Webhook

POST /api/v1/webhooks { "name": "告警通知", "url": "https://your-server.com/webhook", "events": ["rule_triggered", "device_error"], "secret": "your-hmac-secret" # 可选,启用 HMAC-SHA256 签名 }

验证签名(接收端)

请求头 X-ProtoForge-Signature = HMAC-SHA256(secret, bo

... (README truncated for length)

Chat with me