背景
FUXA 是一个开源的 Web SCADA/HMI 软件,支持 SVG 组态编辑、MQTT/Modbus/OPC-UA 等数据源、告警、趋势图和历史记录。它既有浏览器 Web 版,也有 Electron 桌面版。
在磨坊项目中,FUXA 作为本地 SCADA 方案,与网页 SCADA(Vue3 + Konva)并行存在,各有侧重:
| 特性 | 网页 SCADA(Vue3) | FUXA 本地 SCADA |
|---|---|---|
| 运行环境 | 浏览器,通过 Nginx 部署 | Windows Electron 桌面 |
| 组态方式 | 自行开发 Konva 元件 | FUXA 内置 SVG 编辑器 |
| 数据来源 | WebSocket 直连后端 | 本地适配器 → 后端 API |
| 告警 | 后端阈值逻辑 | 适配器本地评估 |
| 继电器控制 | 网页按钮 | 适配器位操作命令 |
整体架构
FUXA Electron ──HTTP──▶ 本地适配器 (Node.js) ──API──▶ mill-api.varka.cn
127.0.0.1:1881 127.0.0.1:1882
适配器作为 FUXA 和后端之间的桥梁,承担三个角色:
- 数据源:定期轮询后端
/api/latest和/api/status,将遥测数据转为 FUXA 标签格式 - 命令中转:接收 FUXA 的标签写入请求,转换为后端 API 调用
- 本地告警:根据阈值配置文件评估告警,补充后端告警体系
目录结构
FUXA/
├── adapter/
│ ├── server.js # 本地适配器(Node.js HTTP 服务)
│ ├── .env.example # 环境变量模板
│ ├── .env # 实际配置(不提交 Git)
│ └── alarm-thresholds.json # 本地告警阈值
├── templates/
│ └── stm32-mill.fuxap # 预置组态模板
├── runtime/
│ └── FUXA.exe # FUXA Electron 可执行程序
├── projects/ # FUXA 运行数据目录(不提交)
├── Start-FUXA.bat # 一键启动脚本
└── Import-STM32-Mill-Project.bat # 模板导入脚本
适配器设计
三大端点
| 方法 | 路径 | 说明 |
|---|---|---|
GET | /health | 健康检查:适配器状态 + 后端连接状态 + 凭证状态 |
GET | /tags | 返回全部遥测标签,FUXA 轮询更新 |
POST | /tags | FUXA 写入标签值,处理继电器命令 |
标签体系
适配器将遥测数据展开为 50+ 个 FUXA 标签,覆盖四类信息:
链路状态标签(7 个):
| 标签 ID | 类型 | 说明 |
|---|---|---|
device_id | string | 设备 ID |
adapter_backend_ok | number | 适配器到后端通信正常(0/1) |
adapter_logged_in | number | 已登录后端(0/1) |
device_online | number | 设备在线(0/1) |
mqtt_connected | number | MQTT Broker 连接(0/1) |
db_connected | number | 数据库连接(0/1) |
last_received_at | string | 最后一次收到数据时间 |
last_error | string | 最近一次错误信息 |
遥测数据标签(11 个):
| 标签 ID | 类型 | 说明 |
|---|---|---|
flow | number | 瞬时流量 |
total | number | 累计流量 |
heart_count | number | 心跳计数 |
temp_1~4 | number | 4 路 PT100 温度 |
weight_1~4 | number | 4 路称重传感器 |
继电器标签(48 个):
| 标签 ID | 类型 | 说明 |
|---|---|---|
relay_do_mask | number | DO 输出 16 位位图 |
relay_di_mask | number | DI 反馈输入 16 位位图 |
relay_do_1~16 | number | 各路 DO 状态(0/1) |
relay_di_1~16 | number | 各路 DI 状态(0/1) |
relay_do_1~16_cmd | number | 各路 DO 写命令标签 |
relay_mask_cmd | number | 整图写命令标签 |
告警标签(3 个):
| 标签 ID | 类型 | 说明 |
|---|---|---|
alarm_active_count | number | 当前活跃告警数 |
alarm_highest_level | number | 最高告警级别(0=正常, 1=警告, 2=危险) |
alarm_summary | string | 告警描述文本 |
继电器双模控制
FUXA 提供两种修改继电器的方式:
- 整图模式:设置
relay_mask_cmd标签值为目标位图,适配器直接调用POST /api/commands/relay-set { mask },一次性切换所有通道 - 单路模式:设置
relay_do_N_cmd标签值为 0/1,适配器先读取当前位图,修改对应位后再发送。位图严格限定在 0-65535 范围
两种模式都走同一个后端 API,适配器在发送命令后乐观更新本地位图,下次遥测刷新时会被设备真实状态覆盖。
本地告警评估
适配器在每次数据刷新时,根据 alarm-thresholds.json 本地评估告警:
{
"device": "FM002",
"channels": {
"temp_4": { "label": "T4", "unit": "°C", "dangerHigh": 80, "warningHigh": 70 },
"flow": { "label": "流量", "unit": "L/min", "warningLow": 0.1, "ignoreZero": true },
"weight_3": { "label": "W3", "unit": "kg", "dangerLow": 10, "warningLow": 50 },
"heart_count": { "label": "心跳", "stallSeconds": 30 }
}
}
支持四种阈值类型:dangerHigh、dangerLow、warningHigh、warningLow。ignoreZero: true 的字段在值为 0 时跳过评估(避免传感器未连接时误报)。心跳停滞通过 lastHeartChangedAt 和 stallSeconds 实现。
认证与容错
适配器启动时用 .env 中的用户名密码登录后端,获取 JWT token。token 过期后 401 响应触发自动重登录。refreshSnapshot 使用 Promise 锁防止并发刷新,刷新失败不影响 FUXA 读取标签结构。
一键启动
Start-FUXA.bat 先启动适配器(node adapter/server.js),监听 http://127.0.0.1:1882,再启动 FUXA Electron。首次部署后导入预置组态模板 stm32-mill.fuxap。
适配器环境变量:
MILL_API_BASE=https://mill-api.varka.cn
MILL_API_USERNAME=admin
MILL_API_PASSWORD=<密码>
MILL_DEVICE=FM002
ADAPTER_PORT=1882
POLL_INTERVAL_MS=2000
当前状态
- 适配器已实现全部三大端点,标签体系完整
- 继电器双模控制已验证
- 预置组态模板已导入 FUXA
- 本地告警阈值已配置 T4、流量、W3、心跳四路
- 不修改后端、STM32 或现有网页 SCADA