Skip to content

Latest commit

 

History

434 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


🖥️ ProtoForge

一台电脑 = 21 种工业设备

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

Python FastAPI Vue License Docker

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

Windows · ✅ Linux · ✅ macOS

🔥 V1.2.0 测试平台版 · 122 设备模板 · 21 种工业协议 · 测试计划+合规检测 · CSV 批量导入导出 · EdgeLite 生态对接 · 31 项 E2E 测试全通过

仪表盘


🔥 为什么选 ProtoForge?

💢 开发者的真实痛点

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

💰 硬件成本对比

场景 传统方式 ProtoForge
测 Modbus 买 PLC(¥3000+) 1 条命令启动虚拟设备
GB28181 联调 买摄像头(¥500+) 自动注册、自动推流
测 21 种协议 买各种厂商设备(¥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: 那一行)
  • 生产环境请务必修改为强密码

🎬 功能预览

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

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

仪表盘

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

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

设备管理

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

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,全部支持独立配置端口和高级参数。

协议服务

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

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

仿真场景

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

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

场景编排器

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

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

备份恢复


✨ 核心特性

  • 21 种工业协议 — 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
  • 全链路仿真 — 不只是模拟数据,完整模拟协议交互过程(如 GB28181:SIP注册→目录查询→INVITE→RTP视频推流→BYE)
  • 122 设备模板 — 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 步:下载项目代码

打开 https://github.com/suoten/ProtoForge,点击页面上的绿色 "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 — 点击展开
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 登录

⚠️ 如果 .\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 登录
生产环境(Nginx + 域名 + PostgreSQL)— 点击展开

详见 DEPLOYMENT.md。大致流程:

  1. 安装系统依赖:python3nodejsnginxpostgresql
  2. 克隆代码 + 构建前端 + 安装后端依赖
  3. 配置 .env 数据库连接和端口
  4. 配置 Nginx 反向代理
  5. systemdsupervisor 管理进程

📋 前置条件速查

需要安装的 方式一(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 共 17 种,开箱即用)。以下 4 种协议需要额外依赖:

pip install -e ".[all]"        # 安装全部 21 种协议
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 统一架构协议
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 数据分发服务 (发布/订阅)

🚀 5 分钟上手

前提:已按上述任一方式完成部署,浏览器能打开 http://localhost:8000。

🌐 不想安装?直接体验演示站点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  │
                    │  ...(21 种协议服务端)              │
                    └──────────┬──────────────────────┘
                               │ 标准 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')

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

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

各协议地址格式

协议 地址格式 示例 说明
Modbus TCP/RTU 寄存器偏移量(数字) address: "0" 寄存器 40001(holding register),"2" = 40003
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": "",
  "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)。如果你想使用输入寄存器或离散输入,请使用 3000110001 等 5 位 PLC 地址格式,或 IR0DI0 等前缀格式。

数据类型与寄存器占用

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

数据类型 字节数 占用寄存器数 字节序 适用协议
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),这是工业设备最常用的字节序。如果你的上位机使用小端序,需要在采集端做字节翻转。

例如:float321.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 000010 bool

💡 5 位 PLC 地址自动转换:你也可以直接填 40001300011000100001,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(如 randomsine),生成器会在每次更新周期覆盖写入的值。要保留写入值,请将 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 秒让所有服务就绪,然后:

第 3 步:验证联调

  1. 打开 ProtoForge(http://localhost:8000),创建一台 Modbus 设备,在协议配置中填写:
    edgelite_url: http://edgelite:8100
    edgelite_username: admin
    edgelite_password: (你在 .env.joint 里设的 EDGELITE_ADMIN_PASSWORD)
    
  2. 启动设备的 Modbus 协议,ProtoForge 会自动把设备推送到 EdgeLite
  3. 打开 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 认证)
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 内置实时协议调试日志,帮你快速定位开发中的通信问题:

  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 通知系统

# 创建 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, "device_id": "sensor", "point": "temp", "value": 25.0}],
    "speed": 2.0,
    "loop": true
  }
}

冷却机制:协同规则在 Rule 级设置 cooldown(秒),防止规则频繁触发:

{"cooldown": 30}

🛠 CLI 命令

命令 说明
protoforge run 启动服务(--host / --port / --reload / --log-level / --daemon
protoforge demo 演示模式(自动创建示例设备和场景,--daemon / -d 后台运行)
protoforge stop 停止后台运行的服务(仅 Linux / macOS)
protoforge init 初始化数据目录和默认配置(创建 data/ 目录,从 .env.example 复制 .env
protoforge migrate 运行数据库迁移(--revision head
protoforge test run 执行测试计划(CI/CD 集成,支持 --plan-id 指定计划)
protoforge version 查看版本号

📊 性能基准参考

场景 预估参考值 说明
Modbus TCP 并发连接 ~200 连接 受限于文件描述符和内存
MQTT 并发客户端 ~500 连接 aMQTT 性能有限,生产建议用 Mosquitto
OPC-UA 并发会话 ~50 连接 asyncua 资源消耗较大
GB28181 RTP 推流 ~10 路 受 CPU 和带宽限制
内存占用(空载) ~150MB Python + FastAPI 基础开销
内存占用(100 设备) ~500MB 含协议栈和仿真数据
CPU 占用(空载) <5% 等待连接状态
CPU 占用(100 设备活跃) 30-60% 取决于数据更新频率

⚠️ 以上为估算值,实际性能取决于硬件配置、协议类型和数据更新频率。建议在目标环境进行基准测试。


🔄 升级指南

升级步骤

# 1. 备份数据
curl -H "Authorization: Bearer $TOKEN" http://localhost:8000/api/v1/backup -o backup.json

# 2. 拉取最新代码
git pull origin main

# 3. 更新依赖
pip install -e ".[all]"

# 4. 运行数据库迁移
protoforge migrate

# 5. 重新构建前端(如有更新)
cd web && npm install && npm run build && cd ..

# 6. 重启服务
protoforge run

回滚

# 回滚数据库到上一个版本
alembic downgrade -1

# 恢复数据备份
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @backup.json \
  http://localhost:8000/api/v1/backup/restore

🖥 前端开发

cd web
npm install
npm run dev     # 开发服务器(热更新)
npm run build   # 生产构建 → web/dist/

🧪 测试

# 运行全部单元测试
python -m pytest tests/ -v

# 运行测试并生成覆盖率报告
python -m pytest tests/ -v --cov=protoforge --cov-report=html

📐 项目结构

ProtoForge/
├── protoforge/                # Python 后端包
│   ├── api/v1/               # REST API 端点
│   │   ├── common.py         # 统一响应格式和异常处理
│   │   ├── rate_limit.py     # API 限流中间件
│   │   ├── router.py         # API 路由
│   │   ├── test_plan_routes.py # 测试计划 API
│   │   └── compliance_routes.py # 合规检测 API
│   ├── core/                 # 核心引擎
│   │   ├── engine.py         # 仿真引擎(设备/场景调度)
│   │   ├── auth.py           # JWT 认证与 bcrypt 密码哈希
│   │   ├── audit.py          # 操作审计日志
│   │   ├── edgelite.py       # EdgeLite 网关对接
│   │   ├── device.py         # 设备实例
│   │   ├── scenario.py       # 场景规则引擎
│   │   ├── testing.py        # 测试框架(14种断言)
│   │   ├── forward.py        # 数据转发
│   │   ├── recorder.py       # 协议录制回放(含加密)
│   │   ├── failover.py       # 故障切换管理
│   │   ├── webhook.py        # Webhook 通知系统
│   │   └── metrics.py        # Prometheus 指标
│   ├── grpc/                 # gRPC 远程管理接口
│   │   ├── protoforge.proto  # Protobuf 定义
│   │   └── server.py         # gRPC 服务实现
│   ├── config.py             # 配置管理
│   ├── db/                   # 数据库层(SQLite + PostgreSQL)
│   ├── models/               # 数据模型
│   ├── protocols/            # 21 种协议服务端实现
│   ├── testing/              # IoT 测试平台(计划/执行/合规检测)
│   ├── sdk/                  # Python SDK(同步/异步)
│   └── templates/            # 122 设备模板(JSON)
├── sdk/                       # 多语言 SDK
│   ├── java/                 # Java SDK
│   ├── go/                   # Go SDK
│   └── csharp/               # C# SDK
├── web/                       # Vue3 前端
│   ├── e2e/                  # Playwright E2E 浏试(31 项全通过)
│   └── src/
│       ├── views/            # 页面组件(含 TestPlans/Compliance)
│       ├── App.vue           # 主布局(含i18n)
│       ├── i18n.js           # 国际化框架(中英文)
│       ├── api.js            # API 调用
│       └── main.js           # 入口
├── k8s/                       # Kubernetes 部署
│   ├── deployment.yaml       # ProtoForge + PostgreSQL
│   ├── ingress.yaml          # Ingress(WebSocket支持)
│   └── secrets.yaml          # 密钥配置
├── helm/                      # Helm Chart
│   └── protoforge/
│       ├── Chart.yaml
│       ├── values.yaml
│       └── templates/        # K8s 模板
├── tests/                     # 测试用例
├── migrations/                # Alembic 数据库迁移
├── grafana/                   # Grafana Dashboard 模板
├── Dockerfile
├── docker-compose.yml
└── pyproject.toml             # 项目配置和依赖

📡 API 文档

后端启动后,访问以下地址查看交互式 API 文档(直接访问后端端口):

这是后端 API 文档,不是前端页面。前端页面请访问 http://localhost:8000(与后端同端口)。


📦 Python SDK

ProtoForge 提供同步和异步两种 Python SDK 客户端,覆盖全部 API 功能。

安装

pip install protoforge

快速上手

from protoforge.sdk import ProtoForgeClient

# 创建客户端
with ProtoForgeClient("http://localhost:8000") as client:
    # 登录
    client.login("admin", "admin")

    # 列出所有协议
    protocols = client.list_protocols()

    # 启动 Modbus TCP 协议
    client.start_protocol("modbus_tcp")

    # 从模板快速创建设备
    device = client.quick_create("modbus-plc-controller", "测试PLC")

    # 读取设备测点
    points = client.read_points(device["id"])
    print(points)

    # 运行一键测试
    report = client.quick_test()
    print(report)

异步客户端

from protoforge.sdk import AsyncProtoForgeClient

async with AsyncProtoForgeClient("http://localhost:8000") as client:
    await client.login("admin", "admin")
    devices = await client.list_devices()
    print(devices)

SDK 方法一览(70+ 方法):

类别 方法 说明
认证 login, refresh_token, change_password JWT 认证管理
协议 list_protocols, start_protocol, stop_protocol, get_protocol_config 协议启停和配置
设备 create_device, quick_create, read_points, write_point, update_device, delete_device 设备 CRUD + 测点读写
批量 batch_create_devices, batch_start_devices, batch_stop_devices, batch_delete_devices 批量操作
模板 list_templates, search_templates, instantiate_template, create_template 模板搜索和实例化
场景 create_scenario, start_scenario, stop_scenario, export_scenario, import_scenario 场景编排
测试 quick_test, create_test_case, run_tests, get_test_report 仿真测试
转发 add_forward_target, start_forward, stop_forward, get_forward_stats 数据转发
录制 start_recording, stop_recording, replay_recording, export_recording 协议录制回放
集成 import_edgelite, import_pygbsentry, list_webhooks, add_webhook 第三方集成
系统 get_settings, update_settings, setup_demo, get_setup_status 系统管理

Java SDKsdk/java/ProtoForgeClient.java):

import io.github.suoten.protoforge.ProtoForgeClient;

public class Example {
    public static void main(String[] args) throws Exception {
        ProtoForgeClient client = new ProtoForgeClient("http://localhost:8000");
        client.login("admin", "admin");
        var devices = client.listDevices();
        System.out.println(devices);
    }
}

Go SDKsdk/go/protoforge/client.go):

package main

import (
    "fmt"
    "protoforge"
)

func main() {
    client := protoforge.NewClient("http://localhost:8000")
    client.Login("admin", "admin")
    devices, _ := client.ListDevices()
    fmt.Println(devices)
}

C# SDKsdk/csharp/ProtoForgeClient.cs):

using ProtoForge;

var client = new ProtoForgeClient("http://localhost:8000");
await client.LoginAsync("admin", "admin");
var devices = await client.ListDevicesAsync();
Console.WriteLine(devices);

📊 监控端点

端点 格式 说明
GET /health JSON 健康检查(数据库状态、活跃设备数、协议状态)
GET /metrics Prometheus 标准指标格式(uptime、设备数、转发/录制计数)
GET /api/v1/forward/stats JSON 数据转发统计
GET /api/v1/recorder/stats JSON 录制统计

🔒 安全说明

ProtoForge 内置多层安全机制:

  • 密码安全:使用 bcrypt 算法存储密码,自动加盐,抵抗彩虹表攻击
  • JWT 认证:访问令牌有效期 30 分钟,支持刷新令牌续期
  • 登录保护:连续 5 次登录失败自动锁定账户 5 分钟,防止暴力破解
  • API 限流:普通接口 100 次/分钟,认证接口 10 次/分钟
  • 密钥管理:JWT 密钥支持环境变量配置,未配置时自动生成随机密钥

生产环境部署前,请务必阅读 SECURITY.md 完成安全加固。

RBAC 角色权限

角色 权限说明 可访问端点
admin 系统管理员,拥有全部权限 所有端点 + 用户管理 + 系统设置
operator 运维人员,可管理设备和协议 设备/协议/场景/转发/录制的增删改
user 普通用户,可运行测试 读操作 + 测试用例/套件的增删改
viewer 只读用户,仅可查看数据 所有 GET 端点

协议安全说明

协议 认证支持 加密支持 说明
HTTP ✅ JWT + RBAC ✅ HTTPS API 端点受完整认证保护
Modbus TCP ❌ 无 ❌ 无 协议本身无认证机制,建议网络隔离
OPC-UA ⚠️ 可配置 ⚠️ 可配置 支持 Sign/SignAndEncrypt 模式,模板默认未启用
MQTT ⚠️ 可配置 ⚠️ 可配置 支持用户名/密码认证,模板默认未启用
GB28181 ⚠️ Digest ⚠️ 可配置 SRTP SIP 支持 Digest 认证,RTP 流可启用 SRTP 加密
S7/MC/FINS/AB ❌ 无 ❌ 无 工业协议通常在 PLC 端做访问控制
BACnet ❌ 无 ❌ 无 BACnet/IP 协议本身无内置认证

⚠️ 仿真环境下的协议安全限制与真实设备一致。生产部署时建议通过防火墙、VPN 或网络隔离保护协议端口。

协议安全增强

协议 安全特性 配置方式
OPC-UA ✅ 证书自动生成(RSA-2048,10年有效期) security_mode=Sign 时自动生成,也可指定 certificate_path/private_key_path
MQTT ✅ TLS 加密通道 配置 tls_enabled=true + tls_cert_path/tls_key_path
GB28181 ✅ SRTP 加密传输 配置 srtp_enabled=true
录制回放 ✅ 报文加密存储 调用 recorder.set_encryption_key("your-key") 启用

💾 数据库备份与恢复

# 导出全库备份(含设备/场景/模板/测试/用户/录制/审计日志)
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8000/api/v1/backup -o backup.json

# 恢复备份
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @backup.json \
  http://localhost:8000/api/v1/backup/restore

备份文件为标准 JSON 格式,可版本控制、差异对比、跨环境迁移。


🔌 gRPC 远程管理

设置 PROTOFORGE_GRPC_PORT 环境变量即可启用 gRPC 服务:

PROTOFORGE_GRPC_PORT=50051 protoforge run

15 个 RPC 方法

方法 说明
GetHealth 健康检查
ListDevices / GetDevice / CreateDevice / DeleteDevice 设备管理
StartDevice / StopDevice 设备启停
ReadPoints / WritePoint 测点读写
ListScenarios / StartScenario / StopScenario 场景管理
GetSettings / UpdateSettings 系统设置

生成客户端代码

# Python
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. protoforge/grpc/protoforge.proto

# Go
protoc --go_out=. --go-grpc_out=. protoforge/grpc/protoforge.proto

# Java
protoc --java_out=. --grpc-java_out=. protoforge/grpc/protoforge.proto

# C#
protoc --csharp_out=. --grpc-csharp_out=. protoforge/grpc/protoforge.proto

☸️ Kubernetes / Helm 部署

方式一:直接使用 K8s YAML

# 1. 创建 Secret(修改密码!)
kubectl apply -f k8s/secrets.yaml

# 2. 部署应用 + PostgreSQL
kubectl apply -f k8s/deployment.yaml

# 3. 配置 Ingress(可选)
kubectl apply -f k8s/ingress.yaml

方式二:使用 Helm Chart

# 1. 修改配置
helm show values helm/protoforge > my-values.yaml
# 编辑 my-values.yaml:修改密码、域名、存储等

# 2. 安装
helm install protoforge helm/protoforge -f my-values.yaml

# 3. 升级
helm upgrade protoforge helm/protoforge -f my-values.yaml

# 4. 卸载
helm uninstall protoforge

Helm values 主要配置

参数 默认值 说明
replicaCount 1 副本数
image.repository suoten/protoforge 镜像仓库
ingress.enabled false 启用 Ingress
postgresql.enabled true 内置 PostgreSQL
persistence.size 5Gi 数据持久化大小
resources.limits.memory 1Gi 内存限制

🔄 故障切换

配置主备模式实现自动故障切换:

# 主节点
PROTOFORGE_FAILOVER_ROLE=primary
PROTOFORGE_FAILOVER_PRIMARY=http://primary:8000
PROTOFORGE_FAILOVER_STANDBY=http://standby:8000
PROTOFORGE_FAILOVER_INTERVAL=10  # 健康检查间隔(秒)

# 备节点
PROTOFORGE_FAILOVER_ROLE=standby
PROTOFORGE_FAILOVER_PRIMARY=http://primary:8000
PROTOFORGE_FAILOVER_STANDBY=http://standby:8000

工作原理

  1. 备节点定期检查主节点 /health 端点
  2. 连续 3 次检查失败后,备节点自动晋升为主节点
  3. 晋升时触发回调通知(可注册自定义回调)
  4. 原主节点恢复后,可手动降级为备节点

📊 竞品对比

ProtoForge vs 同类工具

特性 ProtoForge Modbus Slave/Poll Kepware Node-RED Mock 真实 PLC
协议数量 21 种 仅 Modbus 150+ (需付费驱动) 仅 MQTT/HTTP 单一品牌
开源免费 ✅ MIT ❌ 付费 ❌ 商业 ✅ 但需自建
多协议同时仿真 ✅ 21 种同时 ✅ (需购买驱动)
Web 管理界面 ✅ 开箱即用 ❌ 桌面软件 品牌专用
设备模板库 ✅ 122+ 模板 ❌ 手动配置
批量设备生成 ✅ 一键 100 台 ✅ (付费)
数据生成器 ✅ 5 种 (随机/正弦/递增/渐变/固定) ❌ 手动改值 ✅ 简单 ✅ 真实数据
异常码模拟 ✅ 设备状态映射异常码
写入支持 ✅ 完整读写
Docker 部署 ✅ 30 秒启动
ARM/树莓派 ✅ 支持
中文支持 ✅ 双语
成本 免费 $69+ $1,500+/驱动 免费 $500+

💡 ProtoForge 的独特价值:一台电脑同时仿真 21 种协议设备,零硬件成本。不是替代真实 PLC,而是让你在没有硬件时也能开发、测试、联调。

协议一致性说明

ProtoForge 严格遵循工业协议标准,确保你的采集程序对接真实设备时无缝切换:

协议 遵循标准 异常码/错误处理
Modbus TCP/RTU Modbus Application Protocol v1.1b3 完整异常码:0x01 非法功能、0x02 非法地址、0x03 非法数据值、0x04 从站故障、0x05 确认、0x06 从站忙、0x0A 网关不可达
Siemens S7 S7 Communication (ISO-on-TCP, RFC1006) SZL 请求响应、错误帧完整支持
Omron FINS FINS/TCP (CV-mode 命令) EndCode 错误码完整返回
Mitsubishi MC SLMP 3E/4E 帧格式 子头 0x5000,大端序读写
OPC-UA OPC 1.05 Part 6: Mappings NodeId/QualifiedName/DataValue 完整
IEC 60870-5-104 IEC 60870-5-104 (TI/CI/CD 等 ASDU) APDU/APCI 帧、IOA 地址完整
MQTT MQTT 3.1.1 / 5.0 QoS 0/1/2、Retain、Last Will
BACnet BACnet/IP (ASHRAE 135) ReadProperty/WriteProperty 服务

💡 设备状态→异常码映射:ProtoForge 仿真设备的运行状态(stop/error/starting/stopping/maintenance/program)会自动映射为对应协议的异常码,就像真实设备在故障时会返回错误一样。例如 Modbus 设备处于 error 状态时返回异常码 0x04 (Slave Device Failure)。


🍓 ARM / 树莓派部署

ProtoForge 支持 ARM64 架构,可以在树莓派、工业网关等低功耗设备上运行:

Docker 部署(推荐)

# 树莓派 / ARM64 设备
docker run -d --name protoforge \
  -p 8000:8000 \
  -e PROTOFORGE_ADMIN_PASSWORD=admin \
  -v protoforge-data:/app/data \
  suoten/protoforge:latest

Docker 镜像自动识别 CPU 架构(amd64 / arm64),无需指定平台。

Python 源码部署

# 安装 Python 3.10+
sudo apt install python3.10 python3.10-venv

# 克隆并安装
git clone https://github.com/suoten/ProtoForge.git
cd ProtoForge
python3.10 -m venv .venv
source .venv/bin/activate
pip install -e .

# 启动
protoforge run --host 0.0.0.0 --port 8000

资源消耗参考

配置项 最低要求 推荐 测试基准
CPU ARM Cortex-A53 (1.2GHz) ARM Cortex-A72 (1.5GHz+) 树莓派 4B (4GB)
内存 256MB (10 台设备) 512MB (50 台设备) 1GB (100+ 台设备)
磁盘 100MB (应用) 1GB (含数据)
并发设备 10 台 50 台 100+ 台
协议端口 5 个同时 10 个同时 全部 21 种

💡 树莓派实测:在树莓派 4B (4GB) 上运行 50 台设备(Modbus + S7 + MQTT 同时),CPU 占用约 15%,内存约 180MB,完全流畅。

⚠️ ARM 限制:部分协议驱动(如 OPC-DA、FANUC FOCAS)依赖 Windows 原生 DLL,在 ARM 上不可用。核心协议(Modbus、S7、OPC-UA、MQTT、FINS、MC、IEC 104、BACnet、CoAP、DDS)均完整支持 ARM64。


📋 开源版 vs 企业版功能对比

功能 开源版 (MIT) 企业版
协议数量 21 种全支持 21 种 + 定制协议
设备模板 122+ 模板 122+ + 行业定制模板
同时仿真设备数 无限制 无限制
Web 管理界面 ✅ 完整功能 ✅ + 品牌定制
API 接口 ✅ 完整 REST API ✅ + gRPC 批量接口
Python SDK ✅ 同步+异步 ✅ + Java/Go SDK
Docker 部署 ✅ + Helm/K8s Operator
ARM 支持
CSV 导入导出
测试计划 ✅ + CI/CD 插件
合规检查 ✅ + 行业标准包
SSO / LDAP
多租户
审计日志
SLA 支持 ✅ 7×24
专业服务 社区支持 专属技术经理

💡 开源版永久免费:ProtoForge 开源版包含全部核心功能,没有任何功能限制、设备数量限制或协议限制。企业版提供组织级管理能力和专业服务支持。


❓ 常见问题排查

后端相关

Q: pip install -e . externally-managed-environment

A: 你没有激活虚拟环境。请先在项目目录执行:

python -m venv venv
# Windows: .\venv\Scripts\activate
# macOS/Linux: source venv/bin/activate
pip install -e .

Q: protoforge run No module named 'protoforge'

A: 依赖还没装,先执行 pip install -e .

Q: 启动后打开 http://localhost:8000 看到 Swagger 文档?

A: 你可能访问了 http://localhost:8000/docs。直接访问 http://localhost:8000(不带 /docs)就是前端 Web 界面。前端和后端都在 8000 端口上,由 FastAPI 统一托管,不需要 Nginx。

Q: 某些协议(OPC-UA / MQTT / BACnet / S7)启动失败?

A: 这些协议需要额外安装依赖,只用 pip install -e . 是不够的。请执行:

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

Q: 端口被占用(port already in use)?

A: 编辑项目根目录的 .env 文件,修改对应端口的配置。也可以运行:

# Windows 查看端口占用
netstat -ano | findstr :8000
# macOS / Linux
lsof -i :8000

前端相关

Q: npm install 报错或很慢?

A: 检查 Node.js 版本是否 ≥ 18:

node --version

如果版本太低,去 nodejs.org 下载 LTS 版。

如果网络慢,可设置国内镜像:

npm config set registry https://registry.npmmirror.com

Q: 前端页面空白?

A: 按你的部署方式排查:

源码 / Nginx 部署:

  • 最常见原因:web/dist/ 目录不存在。执行 cd web && npm install && npm run build 构建前端。
  • Nginx 部署:检查 nginx -t 配置是否正确,root 路径是否指向了正确的 web/dist/
  • 确认访问的是 http://localhost:8000(前端和后端都在此端口,由 FastAPI 统一托管)。

Docker 部署:

  • 检查容器日志:docker logs protoforge,看是否有 "前端静态文件目录不存在" 的警告。如果有,说明 Docker 镜像构建时前端编译失败了。
  • 确认访问的是 http://localhost:8000(不带 /docs)。

通用排查:

  • 打开浏览器开发者工具(F12)→ Console / Network,看是否有红色报错或 404 请求。
  • 检查后端是否正常:访问 /api/v1/health 看是否返回 JSON。

Q: Linux 上部署失败?

A: 按以下步骤逐项排查:

  1. 检查 Python 版本python3 --version,需要 ≥ 3.10。如果版本太低,用 apt install python3.12dnf install python3.12
  2. 检查 Node.js 版本node --version,需要 ≥ 18。如果 apt 装的版本太旧,用 NodeSource 安装:
    curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
    sudo apt install -y nodejs
  3. 检查虚拟环境 — 是否激活了 venv?(终端前面应该有 (venv) 前缀)
  4. 检查端口lsof -i :8000(或你设置的端口),确认没有被其他进程占用。
  5. 检查 .env 配置cat .env,确认 PROTOFORGE_PORT 等配置正确。
  6. 查看后端日志 — 如果用的 nohup,查看 protoforge.log;如果用的 systemd,查看 journalctl -u protoforge
  7. 从源码安装时 — 确保用了 pip install -e "."(带引号和点号),不是 pip install -e .(Unix shell 下点号会被解释成当前目录,两者效果相同但格式要正确)。

如果是串口相关错误(Modbus RTU): Linux 上没有 COM1,默认使用 /dev/ttyUSB0。如果你没有物理串口,在设备的协议配置中设置 port=0 即可自动切换到 TCP 桥接模式。

Docker 相关

Q: 容器启动后频繁重启?

A: 通常是内存不够。试试用简易部署模式(纯 SQLite,内存更低):

docker compose -f docker-compose.simple.yml up -d

或者直接用预构建镜像:

docker run -d --name protoforge -p 8000:8000 -v protoforge-data:/app/data suoten/protoforge:latest

Q: docker compose 命令报错?

A: 检查你的 Docker 版本。新版 Docker 用 docker compose(无连字符),旧版用 docker-compose。试试哪个能用:

docker compose version   # 或 docker-compose --version

Q: Docker 构建时 npm run build 失败?

A: 建议用 Docker Hub 上的预构建镜像 suoten/protoforge:latest,跳过编译步骤:

docker run -d --name protoforge -p 8000:8000 suoten/protoforge:latest

如果你必须从源码构建,最新 Dockerfile 已使用 NodeSource 安装 Node.js 20.x(LTS),确保版本可靠。

其他

Q: 忘记管理员密码怎么办?

A: 删除 data/protoforge.db 文件(SQLite 模式)然后重启,系统会重新创建 admin 账号并生成新的随机密码(显示在终端日志中)。你也可以设置 PROTOFORGE_ADMIN_PASSWORD 环境变量来指定新密码。

⚠️ 这会清空所有数据!如果数据重要,请先备份 data/ 目录。

Q: 怎么备份数据?

A: 登录后进入「系统设置」页面,点击「导出备份」按钮即可下载 JSON 文件。也可以直接用命令:

curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8000/api/v1/backup -o backup.json

Token 可以在浏览器开发者工具(F12)→ Application → Local Storage → token 中找到。


🔗 相关项目

项目 说明 仓库地址
EdgeLiteGateway 轻量级边缘计算物联网网关,22 种工业协议开箱即用 Gitee · GitHub

💬 社区交流

QQ群 进群答案:ProtoForge


🏢 企业服务 & 专业支持

ProtoForge 开源版永久免费。如果你的团队需要更深层次的支持,我们提供以下专业服务:

服务 说明 适用场景
🔧 协议联调服务 专家协助完成特定协议的联调测试,快速定位报文/地址/编码问题 项目上线前联调
🎨 协议定制开发 定制非标协议、特殊报文格式、私有协议扩展 标准协议不满足需求
🚀 私有化部署 ProtoForge + EdgeLite 私有化部署、集成、培训 企业内网环境
📊 企业版 License SSO/LDAP、多租户、审计日志、SLA 支持 生产级使用
🎓 技术培训 工业协议体系化培训 + ProtoForge 实操 团队技能提升

💬 联系方式:QQ群(群主)或邮箱 suoten@163.com


☕ 赞助作者

ProtoForge 是一个开源项目,如果你觉得它对你有帮助,可以考虑请作者喝杯咖啡 ☕ 你的支持是项目持续维护的动力!


微信赞赏

支付宝赞赏

💝 感谢每一位支持者!如果在企业项目中使用了 ProtoForge,欢迎反馈使用场景,也欢迎在 GitHub Issues 留言。

Releases

Packages

Contributors

Languages