🖥️ ProtoForge
一台电脑 = 31 种工业设备
零成本模拟 PLC、传感器、摄像头,测试你的上位机和物联网网关

🚀 在线体验 · 📖 5分钟上手 · 💬 加入QQ群 · English
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 登录
31 种协议 · 133 设备模板 · 9 种故障注入 · 协议录制回放 · 自动化测试引擎 · 测试数据闭环 · 性能基准 · ✅ Windows / Linux / macOS
⚠️ 唯一官方仓库声明:ProtoForge 的唯一官方仓库是 suoten/ProtoForge(Gitee 同步:gitee.com/suoten/ProtoForge)。GitHub 上其他同名或改名的仓库(如 sim-foundry 等)均为第三方搬运的旧版本快照,不提供更新、新协议与支持,最新版本(31 种协议 / 主站模式 / 桌面版 / 点表导入)以本仓库为准。发现疑似搬运仓库欢迎举报。

⚠️ 唯一官方仓库:github.com/suoten/ProtoForge(Gitee 镜像:gitee.com/suoten/ProtoForge),Docker 镜像 suoten/protoforge。其他同名仓库均为第三方转载,可能滞后数月。
🔥 为什么选 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套参数 |
31种协议一台电脑全搞定,Docker 30秒启动,一键生成100台虚拟设备 |
| 7 |
协议安全不敢测 |
OPC-UA证书/TLS加密/GB28181 SRTP,生产不敢动,测试又没有 |
证书自动生成、TLS加密、SRTP全支持,安全场景随便测 |
💰 硬件成本对比
| 场景 |
传统方式 |
ProtoForge |
| 测 Modbus |
买 PLC(¥3000+) |
1 条命令启动虚拟设备 |
| GB28181 联调 |
买摄像头(¥500+) |
自动注册、自动推流 |
| 测 31 种协议 |
买各种厂商设备(¥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。
📦 NAS 部署(飞牛 OS / 群晖等带 Docker 的 NAS):不用上传代码,直接用镜像——图形界面 / 一条命令 / compose 三种方式见 docs/飞牛OS部署指南.md
🌐 http://localhost:8000 就是 Web 界面,不是只有 API。ProtoForge 的后端(FastAPI)会自动托管前端页面,不需要单独的 Nginx 或前端服务器。API 文档在 /docs,前端页面直接访问根路径 /。
🔐 密码说明:
- 上面的命令通过
-e PROTOFORGE_ADMIN_PASSWORD=admin 指定了密码为 admin
- 如果不加这个参数,首次启动会自动生成随机密码并保存到容器的
/app/data/.admin_password(可用 docker exec protoforge cat /app/data/.admin_password 查看);重启不会更换该密码(v1.11.1 起沿用)
- 桌面版(便携包 exe):密码在程序旁的
data\.admin_password 文件,首次启动会有托盘气泡提示
- 生产环境请务必修改为强密码
🔧 登录不上(Invalid username or password)排查:
- 用上面说的 .admin_password 文件里的密码登录(不是 admin/admin);
- 或设定固定密码后重启:docker 加
-e PROTOFORGE_ADMIN_PASSWORD=新密码(pip/裸启动设同名环境变量)——环境变量密码每次启动都会生效;
- 多次输错触发账户锁定时,等 5 分钟或重启服务自动解锁;
- 老版本(≤v1.11.0)升级后密码"变了"属于已知缺陷(每次重启重新随机),升级到 v1.11.1+ 后按上述方式设定固定密码即可一劳永逸。
🎬 功能预览
📊 仪表盘 — 全局状态一目了然
设备总数、运行中协议、仿真场景、设备模板数量实时统计,快速操作入口一键触达。

📖 🎬 功能预览 — 其余 11 张实机截图(点击展开)
🔧 设备管理 — 所有仿真设备集中管控
支持按协议筛选、批量启停、快速创建。每台设备显示协议类型、在线状态、测点数量,支持测点读写、链路追踪、编辑配置。

🌐 协议服务 — 28 种从站仿真 + 3 种主站模式
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,全部支持独立配置端口和高级参数。

🔗 主站模式(v1.9.0 新增)— 不只有仿真,还能连真实设备
除了模拟从站,ProtoForge 现在可以主动拨出连接现场真实设备——Modbus Master(TCP/RTU-over-TCP/串口)、S7 Master(DB/M/I/Q 全地址)、IEC 104 Master(总召遥测遥信 + 遥控遥调)。远端数据进入本地点位存储:
- 协议转换免费获得 — SCADA 走 Modbus 采、上位机走 S7 读、调度走 104 遥信,同一个真实设备的数据随取随用
- 测试引擎直接断言 — "读真实从站 → 断言响应值 → 记录报告"自动回归,无需新增任何测试步骤类型
- 工程排障可靠 — 断线指数退避重连、点位质量标记(good/bad)、轮询统计与最后错误可查
另配套报文字段级解析器:粘贴一帧报文 hex,按协议逐字段展开(Wireshark 式),CRC/CS/BCC 自动校验,9 种协议覆盖——联调排障、驱动开发、教学演示一步到位。
🏭 仿真场景 — 组合多设备定义联动规则
创建场景、批量管理设备集合,支持导入导出,快速复现工厂环境。

🎨 场景编排器 — 可视化拖拽设备拓扑
自由拖拽布局设备节点,直观展示设备间关系,支持保存布局、添加设备、一键启停整个场景。

📦 模板市场 — 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 备份文件,跨环境迁移、版本控制、灾难恢复轻松搞定。

✨ 核心特性
- 31 种工业协议 — 28 种从站仿真(Modbus TCP/RTU、OPC-UA Server、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)+ 3 种主站模式(Modbus Master、S7 Master、IEC 104 Master)
- 协议黄金用例门禁 — 25/28 服务端协议字节级黄金帧回归 + 3 主站协议回环集成(真实 socket 收发、CI 强制门禁),协议实现对照标准原文逐字节验证,杜绝"模拟器不像真设备"
- 测试数据闭环(v1.10.0) — 环境即代码(YAML manifest 进 Git,
protoforge env apply/diff/export)、数据基线容差对比(回归结论直接出报告)、Allure2/归档 PDF 报告、测试计划 cron 定时执行 + 钉钉/企业微信/邮件/Webhook 通知、两次执行对比定位回归
- 性能基准与大规模(v1.11.0) — 1000 设备/10 万测点实测 tick 1.1ms;Modbus 线级读 P99 0.54ms、2458 读/秒;
protoforge benchmark 一条命令复现官方数字,回退 >10% CI 门禁;性能白皮书随版本发布
- 点表导入(v1.7.0) — 客户点表 Excel/CSV 粘贴或上传,自动识别西门子/三菱/欧姆龙/Modbus/DL-T645 等 15 类厂商地址风格,冲突与类型疑点预览确认后一键建设备
- 告警行为学(v1.8.0) — 告警风暴(突发/持续)、抖动 chattering、SOE 毫秒时标事件序列三大行为模型;配套官方演示场景(锅炉房/产线/泵站,
examples/scenarios/ 一键导入);传感器漂移支持按天粒度——测告警系统的数据不再是"假"的
- 桌面版(v1.6.0) —
protoforge desktop 或双击便携包 exe:自动起服务 + 自动打开界面 + 可选系统托盘 + 新版本气泡提示;数据随 exe 目录走,解压即用
protoforge doctor 一键自检 — 端口冲突、特权端口、依赖完整、数据库可写、容器网络拓扑逐项体检,部署类问题发 issue 前先自诊(支持 --json)
- 全链路仿真 — 不只是模拟数据,完整模拟协议交互过程(如 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 部署 — 完整 Kubernetes 部署方案(YAML 一键部署)
- IoT 测试平台 — 测试计划管理(版本化/克隆/执行历史)、协议合规检测(5 协议合规规则+评分报告)、JUnit/JSON/HTML 报告导出、CI/CD 集成(
protoforge test run)
- 故障切换 — 主备健康检查,自动晋升,回调通知
- 前端国际化 — 中英文双语,一键切换
- Docker 多架构 — 支持 amd64/arm64(通过 docker buildx 构建),CI 自动推送 Docker Hub + PyPI
📥 更多安装方式
方式二:一键脚本部署
✅ Windows · ✅ Linux · ✅ macOS
如果没有 Docker,也不想手动敲命令,用一键脚本。
第 1 步:下载项目代码
打开 https://github.com/suoten/ProtoForge,点击页面上的绿色 “Code” 按钮 → 点击 “Download ZIP” → 把下载的 ZIP 文件解压到一个文件夹(比如桌面)。
第 2 步:运行安装脚本
脚本会自动检测 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。
桌面版:双击就能用(v1.6.0 新增)
为"现场机器没 Docker、不想装 Python"的场景准备的一键形态:
便携包(推荐):从 GitHub Releases 下载
ProtoForge-v1.6.0-win64-portable.zip(约 45MB)→ 解压 → 双击 ProtoForge.exe →
界面自动在浏览器打开。数据(设备/场景/模板)保存在 exe 旁的 data\ 目录——
整个文件夹拷到 U 盘或另一台机器,配置原样带走。
📎 若 Release 尚未附带 zip 资产,可自行构建(下述开发者命令,需一次 Node.js + Python 环境)。
ProtoForge.exe ← 双击:起服务 + 自动开界面(托盘常驻)
ProtoForge.exe doctor ← 环境自检
ProtoForge.exe install-service ← 安装为 Windows 服务(开机自启)
自行构建便携包(开发者):
python scripts/build_desktop.py # PyInstaller 构建 + 产出 dist/*.zip(≤300MB 验收)
源码运行桌面模式:python -m protoforge desktop(默认端口 18080,被占用自动顺延;
重复启动直接打开已运行实例的界面)。可选托盘:pip install 'protoforge-sim[desktop]'。
📖 ⚙️ Windows 开机自启动与数据保存(点击展开)
开机自启动与数据保存(Windows)
开机自动运行 ProtoForge — 点击展开
日常启动:双击项目文件夹里的 quickstart.bat 即可(自动检查环境 → 启动服务 → 提示访问地址)。窗口保持开着服务就在运行,关闭窗口或按 Ctrl+C 即停止。
方式一(推荐,v1.5.0 起):安装为 Windows 系统服务——开机自启、崩溃自动拉起、日志自动轮转。两种入口等价:
protoforge install-service ← v1.6.0 起 CLI 直接安装(管理员终端)
scripts\install_service.bat ← 仓库脚本方式
需要 NSSM(放到 tools\nssm.exe 或 PATH)。卸载:
protoforge uninstall-service 或 scripts\uninstall_service.bat。
日志在 logs\service-out.log。详见 DEPLOYMENT.md 的「Windows 服务化」章节。
方式二(轻量):启动文件夹自启——不需要管理员权限,适合个人电脑:
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。大致流程:
- 安装系统依赖:
python3、nodejs、nginx、postgresql
- 克隆代码 + 构建前端 + 安装后端依赖
- 配置
.env 数据库连接和端口
- 配置 Nginx 反向代理
- 用
systemd 或 supervisor 管理进程
📋 前置条件速查
| 需要安装的 |
方式一(Docker) |
方式二(一键脚本) |
方式三(手动) |
| Docker Desktop |
✅ 必须 |
❌ |
❌ |
| Python 3.10+ |
❌ |
✅ 必须 |
✅ 必须 |
| Node.js 18+ |
❌ |
⚠️ 可选¹ |
✅ 必须 |
| Git |
❌ |
✅ 必须² |
✅ 必须 |
¹ 没装 Node.js 的话,脚本会自动使用仓库中已构建好的前端文件
² 需要从 GitHub 下载项目代码(可以 git clone,也可以网页下载 ZIP)
各软件下载地址:
📦 可选:安装更多协议
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]" # 安装全部 31 种协议
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协议 |
🧭 三大寻址哲学对照(选协议必读)
不同协议的"地址"概念完全不同,按你的主站/客户端会说哪种来选协议:
| 协议 |
寻址方式 |
地址写法示例 |
"标签"支持 |
| Modbus TCP/RTU |
寄存器区 + 偏移 |
HR100(保持寄存器)、C10(线圈)、40001 记法 |
❌ 纯地址寻址 |
| Siemens S7 |
DB 号 + 字节偏移 |
DB1.DBX0.0、DB1.DBW2、DB1.DBD4 |
❌ 符号表在博途离线解析,线上只有绝对地址 |
| Rockwell AB (EtherNet/IP) |
CIP 符号寻址(Tag) |
测点 address = tag 名,如 TEST_FLOAT |
✅ 客户端直接按 tag 名读写 |
| OPC-UA |
节点 NodeID |
MyNode01、ns=2;s=MyNode01、ns=3;i=100 |
✅ 节点即标签 |
AB 协议支持 CIP Tag 通讯:设备测点的 address 即 CIP tag 名,数据类型对应 CIP 类型(BOOL/INT/DINT/REAL),Kepware、FactoryTalk、pylogix、汇川 HMI 的 EtherNet/IP 驱动等客户端均可按 tag 名直接读写。已实测验证的客户端:Kepware (ControlLogix Ethernet)、pylogix、pycomm3、HSL、汇川 InoTouchPad (EtherNet/IP 驱动)、Modbus Poll。
OPC-UA 自定义节点指南
OPC-UA 设备的每个测点 = 一个自定义节点,测点的 address 就是 NodeID,支持四种格式:
| 地址写法 |
含义 |
MyNode01 |
字符串标识符(最常用,客户端直接按名字访问) |
ns=2;s=MyNode01 |
指定命名空间索引 + 字符串标识符 |
ns=3;i=100 |
指定命名空间 + 数字标识符 |
100 |
纯数字(自动按数字标识符处理) |
- 命名空间 URI 可在设备高级配置里自定义(默认
protoforge),客户端按命名空间区分设备;
- 数据类型对应 OPC-UA 类型(FLOAT32→Float、BOOL→Boolean、INT16→Int16、字符串→String);
- 证书:
certificate_path/private_key_path 留空则启动时自动生成自签名证书(~/.protoforge/opcua_certs),客户端首次连接时信任即可;security_policy 选 Basic256Sha256 + security_mode 选 SignAndEncrypt 可启用加密通信;
- 客户端验证:UaExpert(免费)连接,匿名登录即可浏览全部自定义节点。
🚀 5 分钟上手
前提:已按上述任一方式完成部署,浏览器能打开 http://localhost:8000。
🌐 不想安装?直接体验演示站点:https://protoforge.jjtt.net/ 用户名:admin 密码:Protoforge123
- 登录 — 默认账号
admin。密码取决于部署方式:
- quickstart.bat / docker-compose.simple.yml /
protoforge demo:密码为 admin
protoforge run(正式模式):首次启动自动生成随机密码,看启动横幅 Admin: 那一行,或打开 data/.admin_password 文件查看
- Docker:查看
docker logs protoforge 里的 Admin: 行(compose 指定了 PROTOFORGE_ADMIN_PASSWORD 的以设置为准)
- 登录 401? 见下方常见问题排查中的「admin/admin 登录失败」条目
- 启动协议 — 左侧菜单「协议服务」→ 点击「一键启动」
- 创建设备 — 左侧菜单「模板市场」→ 选择一个模板 → 填写名称 → 一键创建
- 查看数据 — 设备列表 → 点击「测点」→ 看到实时变化的仿真数据
- 运行测试 — 左侧菜单「仿真测试」→ 点击「一键测试全部」
⚠️ 页面空白? Docker 部署检查 docker logs protoforge。源码部署执行:cd web && npm install && npm run build,然后重启后端。
📖 需要更详细的操作指引? 请阅读完整的 操作手册,涵盖设备创建、协议连接、场景编排、故障注入、数据转发、调试排障等全流程。想用脚本 / CI 程序化驱动点位(自动写值、Force 钉值、故障注入、状态机控制)?请看 点位自动化控制指南。
📖 🔗 与第三方系统对接 & PLC 地址映射(精确到每个测点)(点击展开)
🔗 与第三方系统对接
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 种协议服务端 + 3 主站) │
└──────────┬──────────────────────┘
│ 标准 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}")
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 界面创建设备
- 进入「设备管理」→ 点击「创建设备」
- 选择协议
modbus_tcp,填写设备名称
- 在测点配置中,逐条添加上表中的参数
- 设置
slave_id(如 1)
- 保存并启动设备
第 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 为例:
- ProtoForge 中启动 Modbus TCP 协议服务(默认端口 5020)
- ProtoForge 中创建一台 Modbus 设备(记住 slave_id 和测点地址)
- Kepware 中新建一个 Modbus TCP 驱动,IP 填 ProtoForge 所在机器 IP,端口填 5020
- Kepware 中新建设备,slave_id 与 ProtoForge 中一致
- Kepware 中添加点位,地址与 ProtoForge 中一致
就是这么简单——ProtoForge 对你的网关来说,和一台真实 PLC 没有任何区别。
💡 核心理解:ProtoForge 不是网关,不采集数据,不转发数据。它是「被采集的对象」——一台虚拟设备。你的网关/SCADA/采集程序去连它,就像连真实设备一样。
📖 🔗 EdgeLite 网关对接 & 联合一键部署(点击展开)
🔗 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 秒让所有服务就绪,然后:
第 3 步:验证联调
- 打开 ProtoForge(http://localhost:8000),创建一台 Modbus 设备,在协议配置中填写:
edgelite_url: http://edgelite:8100
edgelite_username: admin
edgelite_password: (你在 .env.joint 里设的 EDGELITE_ADMIN_PASSWORD)
- 启动设备的 Modbus 协议,ProtoForge 会自动把设备推送到 EdgeLite
- 打开 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: 先跑自检命令 protoforge doctor(或 python -m protoforge doctor)——它会逐项检查端口占用、特权端口、依赖完整性、数据目录可写、容器网络拓扑,并给出修复建议。报 issue 时附上 protoforge doctor --json 的输出能大幅加快定位。
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 认证)
2. ←── MESSAGE Catalog(自动响应设备目录查询)
3. ←── INVITE(收到实时视频请求)
4. ──→ 200 OK + SDP(媒体协商应答)
5. ←── ACK
6. ══════════════► RTP/PS 视频流(25fps,352×288 CIF)
7. ←── BYE(停止视频,自动停止推流)
其他协议全链路
| 协议 |
仿真链路 |
使用方式 |
| Modbus TCP |
客户端连接→读寄存器→写寄存器→断开 |
你的程序作为 Modbus 客户端连接 |
| MQTT |
Broker启动→客户端订阅→数据发布→客户端收到 |
你的程序作为 MQTT 客户端连接 |
| OPC-UA |
客户端连接→浏览节点→读写值→断开 |
你的程序作为 OPC-UA 客户端连接 |
| S7 |
客户端连接→读DB块→写DB块→断开 |
你的程序作为 S7 客户端连接 |
| HTTP |
GET/POST请求→JSON响应 |
直接请求 API |
🐛 开发调试
ProtoForge 内置实时协议调试日志,帮你快速定位开发中的通信问题:
- 打开左侧菜单「调试日志」
- 实时查看所有协议的收发消息(WebSocket 推送,零延迟)
- 按协议筛选(只看 GB28181 / Modbus / MQTT…)
- 按方向筛选(← 收 / → 发 / 系统)
- 关键词搜索(搜索 “error”、“register”、“invite”…)
- 点击任意日志 → 查看完整 detail 信息
- 暂停日志流 → 仔细分析某条消息
- 导出为 JSON → 离线分析或分享
📖 ⚙️ 配置说明 / Webhook / 仿真测试框架 / 场景规则引擎(点击展开)
⚙️ 配置说明
所有配置项均可在 .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 通知系统:
# 创建 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, body)
| 特性 |
说明 |
| 事件订阅 |
按事件类型过滤,支持通配符 * |
| HMAC 签名 |
X-ProtoForge-Signature 头,防止伪造 |
| 异步队列 |
5000 条消息缓冲,批量发送 |
| 测试端点 |
POST /webhooks/{id}/test 发送测试消息 |
告警反应规则:
# 创建告警规则
POST /api/v1/integration/alarm-rules
{
"source_device_id": "device-001",
"severity": "critical",
"action": "stop_device" # stop_device / inject_fault / adjust_generator
}
| 动作 |
说明 |
stop_device |
自动停止触发告警的设备 |
inject_fault |
向设备注入故障 |
adjust_generator |
调整数据生成器参数 |
🧪 仿真测试框架
ProtoForge 内置完整的仿真测试框架,支持 14 种断言类型和 HTML 报告。
断言类型:
| 类型 |
说明 |
示例 |
equals |
等于 |
{"expected": 100} |
not_equals |
不等于 |
{"expected": 0} |
contains |
包含 |
{"expected": "online"} |
not_contains |
不包含 |
{"expected": "error"} |
greater_than |
大于 |
{"expected": 0} |
less_than |
小于 |
{"expected": 100} |
regex_match |
正则匹配 |
{"expected": "^device-"} |
json_path |
JSON 路径提取 |
{"json_path": "$.status", "expected": "ok"} |
not_null |
非空 |
— |
type_check |
类型检查 |
{"expected": "number"} |
status_code |
HTTP 状态码 |
{"expected": 200} |
length_equals |
长度等于 |
{"expected": 10} |
length_greater |
长度大于 |
{"expected": 0} |
length_less |
长度小于 |
{"expected": 100} |
变量提取和钩子:
{
"steps": [
{
"name": "创建设备",
"action": "create_device",
"extract": {"device_id": "$.id"},
"post_hook": "log('设备创建成功')"
},
{
"name": "读取测点",
"action": "read_points",
"params": {"device_id": "${device_id}"}
}
]
}
测试报告:
GET /tests/reports/{id}/html — 完整 HTML 报告(含步骤详情、断言结果、耗时统计)
GET /tests/reports/trend — 历史测试趋势数据
POST /tests/quick-test — 一键自动生成并运行测试
GET /tests/suggestions — 根据当前状态推荐测试
🎬 场景规则引擎
5 种规则类型 × 5 种动作,支持冷却机制、多设备协同链式联动和时间序列回放。
规则类型:
| 类型 |
说明 |
配置示例 |
threshold |
阈值规则(支持 AND/OR 多条件) |
{"conditions": [{"operator": ">", "value": 80}], "logic": "and"} |
value_change |
值变化规则(支持 delta 阈值) |
{"delta": 10} |
timer |
定时规则 |
{"interval": 60} |
script |
脚本规则(安全沙箱) |
{"expression": "value > 80 and value < 120"} |
collaboration |
多设备协同联动(链式动作 + 故障注入) |
见下方协同联动示例 |
规则动作:
| 动作 |
说明 |
set |
设定目标测点值 |
toggle |
切换布尔值 |
increment |
递增 |
decrement |
递减 |
inject_fault |
注入故障(传感器噪声/漂移/卡死等) |
协同联动示例(温度超 80°C → 启动风扇 → 注入传感器噪声):
{
"rule_type": "collaboration",
"source_device_id": "temp-sensor",
"source_point": "temperature",
"condition": {"operator": ">", "value": 80},
"actions": [
{"target_device_id": "fan", "target_point": "speed", "action_type": "set", "value": 100},
{"target_device_id": "temp-sensor", "target_point": "temperature", "action_type": "inject_fault", "value": {"fault_type": "sensor_noise", "parameters": {"noise_std": 2.0, "duration": 60}}}
],
"cooldown": 5.0
}
时间序列回放:场景支持 replay_config,从历史数据(内联 JSON / CSV 文件)驱动仿真,支持加速回放(speed)和循环(loop):
{
"replay_config": {
"source": [{"ts": 0, "d</details></http:></https:>
> README 内容过长,已截取前 64 KB。完整内容请前往 GitHub 仓库查看。
评论