
WHC系列:ProtoForge --- 工业协议仿真与联调平台
https://appstore.lazycat.cloud/#/shop/detail/cloud.lazycat.app.protoforge
## 🎯 What —— 这是什么?
ProtoForge 是一个把“虚拟设备、工业协议、场景编排和测试记录”放在同一个 Web 控制台里的仿真平台。它适合在没有真实 PLC、传感器或摄像机的情况下,先把上位机、网关和数据采集程序联调起来。
它的工作方式可以概括为:
- 在管理页面创建一个虚拟设备,并为设备提供温度、湿度、压力、流量等测点。
- 在“协议服务”启动 Modbus TCP、OPC UA、MQTT、Siemens S7、Omron FINS、GB28181、BACnet/IP、HTTP REST 等协议。
- 用场景把多个设备组合起来,设置阈值、值变化、定时或脚本规则。
- 通过外部工业客户端连接懒猫盒子发布的 TCP/UDP 端口,观察调试日志、录制交互并回放。
- 把数据转发到 EdgeLite、InfluxDB、HTTP 服务或 Webhook,或者导出备份留档。
当前实例展示了 **97 个设备模板、18 类协议**。数据保存在服务端 SQLite 中,同一懒猫实例的设备、场景和日志不依赖浏览器本地缓存。
## 🛠️ How —— 怎么用?
### 一、访问应用并用懒猫账号登录


> 如果 OIDC 暂时不可用,可以使用本地兜底账号 `admin / admin123` 进入,再到“系统设置 → 用户管理”修改密码。生产环境不要长期保留默认密码。
### 二、用温湿度传感器完成第一条联调链路
下面是一组可以直接照抄的中文业务数据,适合做第一次体验:
- 场景:一号车间冷却水回路联调
- 设备:一号车间冷却水回水温湿度监测
- 协议:Modbus TCP
- 测点:`temperature`、`humidity`、`dew_point`、`alarm_status`
#### 1. 先启动协议服务
1. 左侧进入 **协议服务**。
2. 找到 **Modbus TCP**,确认端口为 `5020`。
4. 点击 **一键启动**,在确认框中点击 **启动**。
5. 等待启动进度走完,状态变为 **运行中**。


这里的顺序很重要:如果协议服务尚未启动,模板市场中的“创建并启动”仍可能提示创建成功,但设备会显示“离线”,因为它没有可用的协议引擎。
#### 2. 从模板市场创建设备
1. 进入 **模板市场**,搜索“温湿度”。

2. 选择 **温湿度传感器 / Modbus TCP**,点击 **一键创建设备**。

3. 在弹窗中把名称改成 `一号车间冷却水回水温湿度监测`,点击 **创建并启动**。

4. 回到 **设备管理**,确认设备协议为 `Modbus TCP`、测点数为 `4`、状态为 **在线**。

本次实测生成的设备 ID 为 `dev-mu83r917`。每次部署生成的 ID 不同,联调时应以页面实际显示的 ID 为准。
#### 3. 查看并写入测点
在设备行点击 **数据测点**,可以看到实时值、采样时间和质量。温湿度模板的四个点分别是:
| 测点 | 用途 | 示例 |
| --- | --- | ---: |
| `temperature` | 回水温度 | 34.3 |
| `humidity` | 相对湿度 | 32.3 |
| `dew_point` | 露点温度 | 7.28 |
| `alarm_status` | 告警状态寄存器 | 0 或设备当前值 |

数值会按仿真逻辑变化,表格中的示例只用于理解量纲。使用“快速写入测点值”可以把测试值改成例如 `22.5`、`55`,然后刷新确认时间和质量仍为 `good`。
#### 4. 从局域网客户端连接
工业客户端优先连接应用域名加发布端口;如果客户端仅支持 IPv4、域名没有 A 记录或 IPv6 路径不可达,再改用懒猫盒子的局域网 IPv4:
```text
主机:protoforge.你的懒猫微服名.heiyu.space
端口:5020
协议:Modbus TCP
```
先用命令检查端口,再用 Modbus 客户端执行读写:
```bash
nc -vz protoforge.你的懒猫微服名.heiyu.space 5020
```

如果客户端不支持 IPv6,或 `dig +short A protoforge.你的懒猫微服名.heiyu.space` 没有结果,则把主机替换为懒猫盒子的局域网 IPv4。容器名 `protoforge` 和 `172.*` 容器地址不能给外部客户端使用。
### 三、场景编排:把设备变成一条工艺链
1. 进入 **场景编排**,点击 **创建场景**。

2. 填写:
- 场景 ID:`cooling-water-loop`
- 场景名称:`一号车间冷却水回路联调`
- 描述:`验证回水温度与湿度测点在 Modbus TCP 联调中的联动规则`

3. 点击场景行的 **编辑**,进入可视化场景编排器。

4. 点击 **添加设备**,填写设备 ID、设备名称和协议。

5. 点击 **保存布局**,回到场景列表后使用 **启动** / **停止** 控制整组设备。


场景编辑器还可以保存阈值、值变化、定时和脚本规则。
### 四、模板与设备的复用
- **设备模板**:查看 97 个模板的厂商、型号、测点数和描述;可按协议搜索,使用 **实例化** 快速生成设备。

- **模板市场**:按“PLC、传感器、数控机床、IoT 设备、摄像头、楼宇”等标签筛选,再一键创建并启动。

- **创建模板**:在“设备模板”中点击 **创建模板**,填写模板 ID、名称、协议、厂商、型号、描述和标签,再用 **添加测点** 定义数据点。
-

### 五、仿真测试:编排可重复的用例

**仿真测试**页面包含 **可视化编辑、JSON 编辑、用例管理、测试套件、历史报告** 五个区域。正常流程是:
1. 填写测试名称,例如 `一号车间冷却水温湿度联动回归`。

2. 点击 **+ 添加步骤**,为每一步选择操作并填写步骤名称。
3. 使用 **+ 添加检查** 配置断言。

4. 点击 **保存为用例**,再使用 **执行测试**;HTML 报告用于浏览器预览,JSON 适合归档或迁移。


### 六、调试日志与录制回放
#### 调试日志
在 **调试日志** 中可以:
- 按协议筛选,例如只看 `modbus_tcp`;
- 按方向和关键词缩小范围;
- 点击 **暂停** 固定现场,点击 **清空** 开始新一轮联调;
- 点击 **导出** 保存当前日志。

日志详情包含时间、协议、设备 ID、事件类型和说明。
#### 录制回放
1. 打开 **录制回放**,点击 **开始录制**。

2. 名称填写 `一号车间温湿度读写回放`,协议选择 `Modbus TCP`,描述可写“记录回水温度和湿度的 Modbus TCP 读写报文”。

3. 用外部客户端产生真实读写,再点击 **停止录制** 并确认。
示例:在macos终端中输入以下代码测试。注意需要修改自己的懒猫微服名
```
python3 - <<'PY'
import socket
import struct
HOST = "protoforge.你的懒猫微服名.heiyu.space"
PORT = 5020
UNIT_ID = 1
# temperature 测点:从保持寄存器地址 0 开始,占用两个寄存器
ADDRESS = 0
NEW_VALUE = 22.5
def recv_exact(sock, size):
data = b""
while len(data) < size:
chunk = sock.recv(size - len(data))
if not chunk:
raise ConnectionError("连接被服务端关闭")
data += chunk
return data
def request(sock, transaction_id, pdu):
# MBAP Header + Unit ID + PDU
frame = struct.pack(
">HHHB",
transaction_id,
0,
len(pdu) + 1,
UNIT_ID,
) + pdu
sock.sendall(frame)
header = recv_exact(sock, 7)
response_id, protocol_id, length, unit_id = struct.unpack(
">HHHB", header
)
body = recv_exact(sock, length - 1)
if response_id != transaction_id:
raise RuntimeError("事务 ID 不匹配")
if protocol_id != 0:
raise RuntimeError("不是 Modbus TCP 响应")
if unit_id != UNIT_ID:
raise RuntimeError("Unit ID 不匹配")
if body[0] & 0x80:
raise RuntimeError(
f"Modbus 异常:function=0x{body[0]:02x}, code={body[1]}"
)
return body
def read_temperature(sock, transaction_id):
# FC03:读取两个保持寄存器
pdu = struct.pack(">BHH", 0x03, ADDRESS, 2)
body = request(sock, transaction_id, pdu)
if body[0] != 0x03 or body[1] != 4:
raise RuntimeError(f"读取响应格式异常:{body.hex()}")
value = struct.unpack(">f", body[2:6])[0]
registers = struct.unpack(">HH", body[2:6])
return value, registers
with socket.create_connection((HOST, PORT), timeout=5) as sock:
before, registers = read_temperature(sock, 1)
print(
f"写入前:temperature={before:.3f} °C,"
f"registers={registers}"
)
# FC16:把 float32 22.5 写入寄存器 0 和 1
raw_value = struct.pack(">f", NEW_VALUE)
write_pdu = (
struct.pack(">BHHB", 0x10, ADDRESS, 2, 4)
+ raw_value
)
body = request(sock, 2, write_pdu)
expected = struct.pack(">BHH", 0x10, ADDRESS, 2)
if body != expected:
raise RuntimeError(f"写入响应格式异常:{body.hex()}")
print(f"写入成功:temperature={NEW_VALUE} °C")
after, registers = read_temperature(sock, 3)
print(
f"回读结果:temperature={after:.3f} °C,"
f"registers={registers}"
)
PY
```
4. 在列表中使用 **详情** 查看事件,使用 **回放** 重放交互,必要时使用 **导出** 归档。

### 七、备份、恢复、系统设置和审计
#### 备份恢复
在 **备份恢复** 页面:
- **导出备份**:将设备、场景、模板和审计日志导出为 JSON;
- **选择备份文件恢复**:从 JSON 恢复,恢复会覆盖现有数据,执行前先保留当前备份。

#### 系统设置
系统设置分为:
- **通用设置**:服务端口(默认 `8000`)、日志级别、CORS 来源和演示模式;
- **集成配置**:EdgeLite 等外部服务参数;
- **协议端口**:修改各协议的容器内监听端口;
- **用户管理**:添加用户、修改密码、重置密码、管理员开关;
- **演示数据**:按需生成或清理演示数据。

注意:设置页中的 Siemens S7 默认端口为容器内 `1102`,懒猫对外发布端口是 `102`,外部客户端应连接后者。
#### 审计日志
**审计日志** 会记录用户、时间、操作类型、资源类型、资源 ID 和 API 详情。创建设备、启动协议、创建/更新场景、开始/停止录制等操作都可以在这里复核;管理员可以按用户名、操作类型和资源类型搜索。

## 🔌 开放端口访问攻略
管理页面和工业协议端口不是同一条链路。
下表中的 `<应用域名>` 只表示主机名,例如 `protoforge.你的懒猫微服名.heiyu.space`,不要包含 `https://`、路径或中文标点。
| 用途 | 客户端连接方式 | 协议及注意事项 |
| --- | --- | --- |
| 管理页面 | `https://<应用域名>/` | 通过懒猫账号登录;不要添加容器内部端口 `:8000` |
| 仿真 HTTP | `http://<应用域名>:8080/` | 明文 HTTP,不支持 HTTPS;可用浏览器或 `curl` 访问 |
| Modbus TCP | 主机 `<应用域名>`,端口 `5020` | 使用 Modbus TCP 客户端,不要添加 `http://` 或 `https://` |
| OPC UA | `opc.tcp://<应用域名>:4840/protoforge` | 使用 OPC UA 客户端;安全策略和认证方式以协议服务配置为准 |
| MQTT | `mqtt://<应用域名>:1883` | 使用 MQTT 客户端;未配置 TLS 时不要使用 `mqtts://` |
| Siemens S7 | 主机 `<应用域名>`,端口 `102` | 懒猫入口将外部端口 `102` 转发到容器内部端口 `1102` |
| Mitsubishi MC | 主机 `<应用域名>`,端口 `5000` | 使用 Mitsubishi MC TCP 客户端 |
| Omron FINS | 主机 `<应用域名>`,端口 `9600` | 根据服务配置选择 FINS TCP 或 FINS UDP |
| GB28181 | SIP 主机 `<应用域名>`,端口 `5060` | 支持 SIP TCP/UDP;媒体传输还需要 UDP `6000–6999` RTP 端口范围 |
| BACnet/IP | 主机 `<应用域名>`,UDP 端口 `47808` | 使用支持指定远程主机的 BACnet/IP 客户端;跨网段广播发现可能不可用 |
| EtherNet/IP | 主机 `<应用域名>`,端口 `44818` | 使用 EtherNet/IP TCP 客户端 |
| FANUC FOCAS | 主机 `<应用域名>`,端口 `8193` | 使用 FANUC FOCAS TCP 客户端 |
| MTConnect | `http://<应用域名>:7878/` | 通过明文 HTTP 获取 MTConnect XML;不要使用 HTTPS |
| OPC DA | 主机 `<应用域名>`,端口 `51340` | ProtoForge 提供 TCP 桥接仿真入口,不是浏览器页面 |
| Mettler-Toledo | 主机 `<应用域名>`,端口 `1701` | 使用对应的 Mettler-Toledo TCP 客户端 |
| PROFINET IO | 主机 `<应用域名>`,端口 `34964` | 这是 ProtoForge 的 TCP 仿真入口,不等同于真实 PROFINET 二层实时网络 |
| EtherCAT | 主机 `<应用域名>`,端口 `34980` | 这是 ProtoForge 的 TCP 仿真入口,不等同于真实 EtherCAT 二层总线 |
### 最小连通性检查
测试前先在 ProtoForge 的 **协议服务** 页面启动目标协议,再在 **设备管理** 中启动对应设备。
#### 1. 检查仿真 HTTP
```bash
curl --connect-timeout 5 \
http://protoforge.你的懒猫微服名.heiyu.space:8080/
```
正常情况下会返回类似内容:
```json
{"status":"ok","protocol":"http","devices":0}
```
8080 是明文 HTTP 四层入口,不提供 HTTPS、TLS 或 OIDC 登录。不要写成 `https://protoforge.你的懒猫微服名.heiyu.space:8080/`,否则可能出现 TLS 握手失败、连接重置、`broken pipe` 或超时。正确使用 `http://` 仍然出现 `Connection reset` 或 `Connection refused` 时,先回到页面确认 **HTTP RESTful** 协议服务是否已经启动。
#### 2. 检查 Modbus TCP 端口
```bash
nc -vz protoforge.你的懒猫微服名.heiyu.space 5020
```
看到下面的结果,表示 TCP 连接已经建立:
```text
Connection to protoforge.你的懒猫微服名.heiyu.space port 5020 succeeded!
```
`nc` 成功只代表四层入口可以建立连接,不能证明 Modbus 协议已经正常工作。懒猫入口有时会在协议服务尚未启动时接受 TCP 连接,随后重置真正的协议请求。最终还要使用 Modbus TCP 客户端,按照设备实际配置的 Unit ID、寄存器地址和数据类型完成一次真实读写,并在 **调试日志** 中确认对应报文。
#### 3. 判断客户端应该使用 IPv4 还是 IPv6
```bash
dig +short A protoforge.你的懒猫微服名.heiyu.space
dig +short AAAA protoforge.你的懒猫微服名.heiyu.space
```
- `A` 记录表示 IPv4;
- `AAAA` 记录表示 IPv6;
- 两者都有时,双栈客户端通常可以直接使用应用域名;
- `A` 为空而只有 `AAAA` 时,仅支持 IPv4 的客户端不能通过该域名连接;
- 两者都为空时,检查域名是否填写正确,以及应用是否已正常安装。
如果域名没有 A 记录、客户端仅支持 IPv4,或者当前网络无法访问 IPv6,请把连接主机改成懒猫微服的局域网 IPv4,端口保持不变。下面的 `192.168.1.50` 只是示例,必须替换成自己微服的真实地址:
```text
仿真 HTTP:http://192.168.1.50:8080/
Modbus TCP:主机 192.168.1.50,端口 5020
```
## 🧭 日常工作流建议
1. 先启动需要的协议,再启动设备。
2. 用模板创建设备,名称包含车间、产线和用途。
3. 在设备测点窗口确认数值和质量,再从外部客户端读写。
4. 用调试日志确认请求已到达;需要复现时再打开录制。
5. 将多个设备放入场景,保存布局后再运行规则。
6. 联调完成后导出备份,或把日志/场景/录制导出交给项目归档流程。
7. 联调结束后停止协议和场景,减少端口暴露和资源占用。
## 🧩 Conclusion —— 一句话总结
ProtoForge 适合把工业协议联调从“等真实设备到位”提前到“先用虚拟设备验证接口”。
此 App 尚未收到足够的评分或评论,无法显示评论列表。