Skip to content

Latest commit

 

History

History
679 lines (477 loc) · 21.6 KB

File metadata and controls

679 lines (477 loc) · 21.6 KB

📖 ProtoForge 操作手册

本手册覆盖从安装到实际使用的完整流程。如果你还没有部署 ProtoForge,请先看 README 中的安装部分。


目录


1. 快速入门(5 分钟)

以下假设你已完成部署,浏览器能打开 http://localhost:8000。 没有部署?试用在线演示站(用户名 admin,密码 Protoforge123)。

第一步:登录

打开 http://localhost:8000,输入 admin / admin(或你设置的密码)。

第二步:启动协议服务

  1. 点击左侧菜单 「协议服务」
  2. 点击页面右上角 「一键启动」 按钮
  3. 等待所有协议状态变为绿色 运行中

💡 你也可以单独启动某个协议:点击对应协议行的「启动」按钮。

第三步:创建仿真设备

  1. 点击左侧菜单 「模板市场」
  2. 浏览或搜索设备模板(如搜索 "Modbus" 或 "PLC")
  3. 选择一个模板(如 Modbus PLC 控制器)
  4. 输入设备名称(如 测试PLC)
  5. 点击 「创建并启动」

设备创建后会自动启动,状态显示为绿色 在线。

第四步:查看实时数据

  1. 点击左侧菜单 「设备管理」
  2. 找到刚创建的设备,点击 「测点」 按钮
  3. 可以看到所有测点的实时值,数据每隔 1 秒自动刷新

第五步:用你的程序连接 ProtoForge

这是最关键的一步——ProtoForge 启动的是协议服务端,你的程序作为客户端连接它。

以 Modbus TCP 为例,ProtoForge 默认监听 5020 端口:

# Python — 用 pymodbus 连接 ProtoForge
from pymodbus.client import ModbusTcpClient

client = ModbusTcpClient("127.0.0.1", port=5020)
client.connect()
result = client.read_holding_registers(address=0, count=2, device_id=1)
print(f"读取到的寄存器值: {result.registers}")

💡 不知道用什么地址连? 在设备管理页面,点击设备的 「指南」 按钮,系统会根据设备协议自动生成连接参数和代码示例。


2. 连接你的程序

核心理解

ProtoForge 是「被采集的对象」,不是「采集者」。

  • ProtoForge 启动协议服务端(Server),模拟 PLC / 传感器 / 摄像头
  • 你的程序 / 网关 / SCADA 作为客户端(Client)连接 ProtoForge
  • 对你的程序来说,ProtoForge 和真实设备没有任何区别

连接参数速查

协议 默认端口 连接方式 你的程序角色
Modbus TCP 5020 TCP 主站(Master)
OPC-UA 4840 TCP 客户端(Client)
MQTT 1883 TCP 发布者/订阅者
HTTP 8080 TCP HTTP 客户端
GB28181 5060 TCP+UDP 上级 SIP 平台
Siemens S7 102 TCP 客户端(Client)
Mitsubishi MC 5000 TCP 客户端(Client)
Omron FINS 9600 TCP+UDP 客户端(Client)
Rockwell AB 44818 TCP 客户端(Client)

连接指南功能

在「设备管理」页面,每台设备都有一个 「指南」 按钮。点击后系统会自动生成:

  • 连接参数:IP、端口、slave_id、设备地址等
  • 代码示例:Python / Node.js 等语言的连接代码
  • 协议状态:当前协议服务是否运行

💡 如果看不到设备地址或端口,先确认对应协议服务已启动。

Modbus 地址映射

ProtoForge 的 Modbus 地址遵循标准 PLC 地址格式:

你在 ProtoForge 填的地址 实际 Modbus 寄存器地址 区域
0 地址 0 Holding Register(自动判断)
100 地址 100 Holding Register(自动判断)
40001 地址 0 Holding Register(5 位 PLC 地址)
400100 地址 99 Holding Register(6 位 PLC 地址)
30001 地址 0 Input Register
00001 地址 0 Coil
10001 地址 0 Discrete Input
HR100 地址 100 Holding Register(显式前缀)
IR100 地址 100 Input Register
C100 地址 100 Coil

你的 Modbus 客户端读取时,直接使用 Modbus 协议地址(从 0 开始的偏移地址)。

常见协议连接示例

Modbus TCP

from pymodbus.client import ModbusTcpClient

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

# 读取 Holding Register,地址 0,数量 2,slave_id=1
result = client.read_holding_registers(address=0, count=2, device_id=1)
print(f"值: {result.registers}")

# 写入单个寄存器
client.write_register(address=0, value=1234, device_id=1)

MQTT

import paho.mqtt.client as mqtt

client = mqtt.Client()
client.connect("127.0.0.1", 1883)

# 订阅主题
client.subscribe("sensor/temperature")
client.on_message = lambda c, u, m: print(f"收到: {m.topic} = {m.payload.decode()}")
client.loop_start()

OPC-UA

from asyncua.sync import Client

with Client("opc.tcp://127.0.0.1:4840/freeopcua/server/") as client:
    # 浏览节点
    root = client.nodes.root
    children = root.get_children()
    print(f"节点: {[c.get_browse_name() for c in children]}")

Siemens S7

import snap7

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

# 读取 DB1 的前 4 个字节
data = client.db_read(1, 0, 4)
print(f"DB1.DBW0 = {int.from_bytes(data[0:2], 'big')}")

3. 设备管理详解

创建设备的三种方式

方式一:快速创建(推荐)

  1. 进入 「模板市场」
  2. 搜索或浏览模板
  3. 选择模板 → 输入名称 → 点击「创建并启动」

模板已预配置好协议类型、测点地址、数据生成器,开箱即用。

方式二:高级创建

  1. 进入 「设备管理」 → 点击「高级创建」
  2. 填写设备 ID(英文,如 pump-01)、设备名称
  3. 选择协议类型(Modbus TCP / S7 / MQTT...)
  4. 可选:选择一个模板导入测点配置
  5. 填写协议配置(如 Modbus 的 slave_id)
  6. 点击「创建」

方式三:批量创建

  1. 进入 「设备管理」 → 点击「批量创建」
  2. 选择模板
  3. 填写数量(最多 50 台)、名称前缀、ID 前缀
  4. 点击「批量创建」

批量创建适合压力测试场景,一次生成多台相同类型的设备。

编辑设备配置

  1. 在设备列表中点击 「编辑」 按钮
  2. 可以修改:
    • 设备名称
    • 协议配置(如 slave_id、端口号等)
    • 测点配置(核心功能):
      • 名称:测点标识(如 temperature)
      • 地址:协议地址(如 Modbus 地址 0、100、40001)
      • 数据类型:uint16 / int16 / float32 / int32 / bool / string
      • 访问权限:rw(读写)/ r(只读)/ w(只写)
      • 数据生成器:控制测点值的变化方式(见下表)
      • 最小值/最大值:随机数生成范围
      • 固定值:当生成器为 fixed 时使用
      • 单位:如 °C、MPa、rpm
  3. 点击「保存」

数据生成器类型

生成器 说明 适用场景
random 在 min~max 范围内随机变化 温度、压力、流量
sine 正弦波变化 周期性数据模拟
square 方波变化 开关量模拟
sawtooth 锯齿波变化 计数器、累计量
triangle 三角波变化 周期性变化
increment 递增(到 max 回绕到 min) 计数器、产量
fixed / constant 固定值不变 设定值、常量
script 自定义脚本 复杂逻辑

测点读写

  1. 在设备列表中点击 「测点」 按钮
  2. 查看实时测点值(每秒自动刷新)
  3. 写入测点:
    • 选择要写入的测点名称
    • 输入值
    • 点击「写入」
  4. 重置测点:
    • 点击「重置」恢复单个测点到生成器计算的值
    • 点击「全部重置」恢复所有测点

💡 写入测点后,外部 Modbus/S7 客户端会读到新写入的值。这是测试写控制功能的常用方法。

设备状态机

点击设备的 「详情」 按钮,可以看到设备状态机:

  • 当前状态:online / stopped / error / starting / maintenance / program
  • 状态转换:选择事件(如 stop、fault、reset),点击「状态转换」
  • 状态历史:记录所有状态变更事件

不同状态下,外部 Modbus 客户端会收到不同的异常码:

设备状态 Modbus 异常码 含义
online 无(正常响应) 正常
error 0x04 Slave Device Failure
starting / stopping 0x05 Acknowledge(请稍后重试)
maintenance 0x06 Slave Device Busy
program 0x0A Gateway Path Unavailable

设备启停

  • 单台启停:点击设备行的「启动」/「停止」按钮
  • 批量启停:勾选多台设备 → 点击「批量启动」/「批量停止」

4. 协议服务管理

启停协议

  1. 进入 「协议服务」 页面
  2. 可以看到 17 种协议及其状态和端口
  3. 操作:
    • 一键启动:启动所有已安装的协议
    • 单独启动/停止:操作单个协议
    • 一键停止:停止所有协议

修改协议端口

  1. 进入 「系统设置」 页面
  2. 找到「协议端口配置」区域
  3. 修改对应协议的端口号
  4. 点击保存
  5. 重启对应协议服务(在协议服务页面停止再启动)

⚠️ 修改端口后必须重启协议服务才能生效。

协议依赖说明

部分协议需要额外安装依赖才能使用:

协议 安装命令 说明
OPC-UA pip install -e ".[opcua]" 需要 asyncua 库
MQTT pip install -e ".[mqtt]" 需要 amqtt 库
BACnet pip install -e ".[bacnet]" 需要 bacpypes 库
Siemens S7 pip install -e ".[s7]" 需要 python-snap7 库
全部协议 pip install -e ".[all]" 一次安装所有依赖

Docker 部署的镜像已包含全部协议依赖,无需额外安装。


5. 场景编排与规则引擎

创建场景

  1. 进入 「仿真场景」 页面
  2. 点击「创建场景」
  3. 输入场景名称和描述
  4. 添加设备到场景
  5. 配置联动规则(可选)

场景编排器

进入 「场景编排器」 页面,可以用可视化拖拽方式编排设备拓扑:

  1. 选择一个场景
  2. 点击「添加设备」→ 选择设备或从模板创建
  3. 设备节点会出现在画布上,可以自由拖拽布局
  4. 创建联动规则:
    • 从源设备的连接点拖拽到目标设备
    • 弹出规则配置弹窗
    • 配置规则名称、类型、条件、动作
  5. 双击设备节点可以编辑测点配置
  6. 双击连线可以编辑规则
  7. 点击「保存布局」保存

规则类型

类型 说明 配置示例
阈值触发 测点值满足条件时触发 温度 > 80°C 时启动风扇
值变化 测点值发生变化时触发 状态从 0 变为 1 时告警
定时触发 按固定时间间隔触发 每 60 秒采样一次
脚本触发 自定义脚本判断 value > 80 and value < 120

规则动作

动作 说明
set 将目标测点设为指定值
toggle 切换布尔测点的值
increment 目标测点值递增
decrement 目标测点值递减

协同联动示例

场景:温度传感器超过 80°C → 启动风扇 → 注入传感器噪声

在场景编排器中:

  1. 添加「温度传感器」和「风扇」两个设备节点
  2. 从温度传感器拖拽连线到风扇
  3. 配置规则:
    • 规则名称:高温联动
    • 规则类型:阈值触发
    • 源测点:temperature
    • 条件:> 80
    • 目标测点:speed
    • 动作类型:set
    • 目标值:100
    • 冷却时间:5(秒)
  4. 保存并启动场景

冷却机制

每条规则可以设置 冷却时间(秒)。规则触发后,在冷却时间内不会重复触发,防止规则频繁执行。


6. 故障注入

注入故障

  1. 在「设备管理」页面,点击设备的 「详情」 按钮
  2. 找到「故障注入」区域
  3. 选择故障类型 → 填写参数 → 点击「注入故障」

故障类型

故障类型 说明 效果
sensor_stuck 传感器卡死 测点值冻结在当前值不再变化
sensor_drift 传感器漂移 测点值逐渐偏移,偏离真实值
sensor_noise 传感器噪声 测点值叠加随机噪声
sensor_failure 传感器失效 测点值变为 0 或异常值
comm_loss 通信中断 设备模拟离线,不响应请求
comm_delay 通信延迟 响应延迟指定时间
comm_intermittent 通信间歇中断 随机丢失部分请求
device_failure 设备故障 设备进入 error 状态
actuator_stuck 执行器卡死 写入操作不生效

故障参数

参数 说明
目标测点 要注入故障的测点名称(* 表示所有测点)
持续时间 故障持续时间(秒),-1 为永久
严重程度 low / medium / high / critical
触发方式 manual(手动)/ random(随机)/ scheduled(定时)/ conditional(条件)

清除故障

  • 在故障列表中,点击单条故障的「移除」按钮
  • 点击「清除所有故障」一次性清除全部故障

7. 数据转发

ProtoForge 可以将仿真数据实时转发到外部系统。

支持的转发目标

类型 说明 适用场景
InfluxDB 时序数据库 长期存储、Grafana 可视化
HTTP Webhook HTTP POST 推送 自定义接收端、第三方系统对接
文件 JSONL/CSV 文件 本地存储、离线分析

配置 InfluxDB 转发

  1. 进入 「数据转发」 页面
  2. 点击「添加目标」
  3. 填写:
    • 目标名称:influxdb-prod
    • 目标类型:InfluxDB
    • 主机地址:localhost
    • 端口:8086
    • 数据库:protoforge
  4. 点击「添加」

配置 HTTP Webhook 转发

  1. 点击「添加目标」
  2. 填写:
    • 目标名称:my-webhook
    • 目标类型:HTTP
    • 目标 URL:https://your-server.com/api/data
    • 请求头(可选):{"Authorization": "Bearer xxx"}
  3. 点击「添加」

启动/停止转发

  • 点击页面顶部的 「启动转发」 按钮开始转发
  • 点击 「停止转发」 按钮停止

转发启动后,ProtoForge 会将所有设备的测点数据实时推送到配置的目标。

查看转发统计

页面顶部显示实时统计:

  • 已发送:成功转发的数据条数
  • 已丢弃:因队列满等原因丢弃的条数
  • 错误数:发送失败次数
  • 速率:每秒转发条数

8. 调试日志

调试日志是排查通信问题的关键工具。

使用方法

  1. 进入 「调试日志」 页面
  2. 实时查看所有协议的收发报文(WebSocket 推送,零延迟)

筛选功能

筛选方式 说明
按协议 只看 Modbus / MQTT / S7 等特定协议
按方向 ← 收(接收)/ → 发(发送)/ 系统
关键词搜索 搜索报文内容,如 error、register、invite

其他操作

  • 点击日志条目:查看完整报文详情(十六进制 / JSON 格式)
  • 暂停日志流:暂停后可以仔细分析某条消息
  • 导出 JSON:将当前日志导出为文件,离线分析或分享

典型排查场景

问题:外部客户端读不到数据

  1. 打开调试日志,筛选对应协议
  2. 用外部客户端发起读取请求
  3. 查看是否收到请求报文(←收 方向)
  4. 查看返回的响应报文(→发 方向)
  5. 检查响应中的数据是否为 0 或异常值

问题:写入不生效

  1. 筛选对应协议
  2. 在 ProtoForge 或外部客户端写入测点
  3. 查看写入请求报文
  4. 再次读取,查看响应是否反映了写入的值

9. EdgeLite 网关对接

ProtoForge 支持将设备配置自动推送到 EdgeLite 物联网网关,免去手动在网关中添加设备。

配置方式

在创建或编辑设备时,在协议配置中填写 EdgeLite 信息:

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

不填就不推送,不影响 ProtoForge 正常使用。

验证联调

  1. 在设备管理页面,点击设备的 「验证链路」 按钮
  2. 系统自动执行四步验证:
    • ① 认证 EdgeLite
    • ② 注册设备
    • ③ 连接设备
    • ④ 采集数据
  3. 全部通过显示绿色 ✅

一键联合部署

使用 docker-compose.joint.yml 一条命令同时启动 ProtoForge + EdgeLite + MQTT + InfluxDB:

cp .env.joint.example .env.joint
# 编辑 .env.joint,修改所有 change_me_* 密码
docker compose -f docker-compose.joint.yml --env-file .env.joint up -d

启动后:

详见 README 中的 EdgeLite 联合部署章节。


10. 仿真测试

一键测试

  1. 进入 「仿真测试」 页面
  2. 点击「一键测试全部」
  3. 系统自动生成测试用例并运行
  4. 查看测试报告

测试内容

系统自动生成以下测试:

  • 协议连通性测试:验证协议服务是否正常响应
  • 设备读写测试:验证测点数据是否可读可写
  • 场景规则测试:验证联动规则是否正确触发
  • 状态转换测试:验证设备状态机是否正常

测试报告

  • 支持 HTML 格式报告(含步骤详情、断言结果、耗时统计)
  • 支持历史趋势数据查看

11. 系统设置

可配置项

进入 「系统设置」 页面,可以在线修改:

配置项 说明
服务器端口 Web 服务端口(默认 8000)
数据库路径 SQLite 文件路径或 PostgreSQL 连接串
日志级别 debug / info / warning / error
CORS 源 允许跨域访问的地址
InfluxDB 转发 InfluxDB 连接配置
协议端口 各协议服务的监听端口
gRPC 端口 gRPC 远程管理端口(0=禁用)

备份与恢复

  • 导出备份:点击「导出备份」按钮,下载全库 JSON 文件
  • 恢复备份:上传 JSON 文件,一键恢复

备份内容包括:设备配置、场景配置、模板、测试用例、审计日志。


12. 常见问题

Q: 创建了设备,但外部客户端连接不上?

排查步骤:

  1. 确认协议服务已启动(「协议服务」页面,状态为绿色运行中)
  2. 确认端口号正确(查看协议服务页面或系统设置)
  3. 确认防火墙没有拦截端口
  4. 打开「调试日志」页面,看是否有连接请求到达

Q: 外部客户端读到全 0?

排查步骤:

  1. 在「设备管理」页面点击「测点」,确认 ProtoForge 内部测点有值
  2. 确认 Modbus 的 slave_id 匹配(ProtoForge 设备的 slave_id 与客户端请求的一致)
  3. 确认地址映射正确(在设备的「指南」按钮中查看地址说明)
  4. 打开调试日志,检查响应报文中的实际值

Q: 设备创建后状态是「离线」?

设备创建后需要启动才能上线。在设备管理页面,确认设备状态是「在线」(绿色)。如果是「已停止」(灰色),点击「启动」按钮。

Q: 如何修改测点的数据变化方式?

在设备管理页面点击「编辑」→ 找到对应测点 → 修改「数据生成器」类型:

  • random:随机变化(默认)
  • sine:正弦波
  • fixed:固定值
  • increment:递增
  • 等等

保存后立即生效。

Q: 如何模拟设备故障?

在设备管理页面点击「详情」→ 故障注入区域 → 选择故障类型 → 点击「注入故障」。详见 故障注入章节。

Q: 数据能转发到 InfluxDB 吗?

可以。进入「数据转发」页面,添加 InfluxDB 目标并启动转发。详见 数据转发章节。

Q: 怎么同时模拟 100 台设备?

  1. 在「设备管理」页面点击「批量创建」
  2. 选择模板,填写数量(最多 50 台/次)
  3. 执行两次即可创建 100 台
  4. 全选后点击「批量启动」

Q: 忘记密码怎么办?

  • Docker 部署:删除数据卷重新创建,或设置 PROTOFORGE_ADMIN_PASSWORD 环境变量重置
  • 源码部署:删除 data/protoforge.db 文件后重启(⚠️ 会清空所有数据)

📖 更多技术文档:README.md | DEPLOYMENT.md | SECURITY.md

💬 有问题?加入 QQ 群 或 提 Issue