在工业 4.0 和智能制造浪潮下,一套直观、实时、可交互的 HMI(人机界面)已成为工厂监控系统的“眼睛”。而今天要介绍的这款开源神器—— FUXA ,正以极简的方式,让非程序员也能快速搭建专业的 SCADA 系统。
更令人惊喜的是:它的一切可视化能力,都源于一组灵活强大的 小部件(Widgets) 。
本文将带你深入 FUXA 的五大类小部件,揭秘它们如何通过 SVG + JavaScript 实现动态数据绑定,并手把手教你玩转这些“积木块”,打造属于你的工业数字孪生界面!
FUXA 是一个基于 Web 的开源 SCADA/HMI 平台(GitHub 星标超 5k+),支持连接 Modbus、OPC UA、S7 等多种工业协议。它的核心亮点之一,就是内置了丰富的 可拖拽小部件 。
每个小部件本质上是一个 自包含的 SVG 文件 ,内部嵌入 JavaScript 脚本,能:
接收实时数据(如温度、液位、开关状态)
动态更新图形(颜色、高度、指针角度)
响应用户操作(点击按钮、拖动滑块)
向后端发送控制指令
最重要的是: 无需写一行代码 ,只需在编辑器中绑定数据标签,即可实现联动!
FUXA 官方提供了五大类预置组件,覆盖绝大多数工业场景需求:
用于可视化 连续型物理量 ,如压力、温度、电压、转速、负载率等,以弧形或圆形指针形式呈现。
FUXA 通过 putValue('_pn_value', value) 将新数据推送到组件。
组件内部 JS 计算角度:
const angle = (_pn_value - _pn_min) / (_pn_max - _pn_min) * 180 - 90;使用 SVG <path> 或 <line> 动态绘制弧线和指针。
更新 <text> 元素显示最新数值和单位。
// 绑定数据_pn_value = 75; // 当前压力 75 kPa_pn_min = 0;_pn_max = 100;_ps_unit = "kPa";// 视觉优化_pc_arcColor = "#f0f0f0"; // 背景灰_pc_valueColor = "#ff6b6b"; // 高压用红色警示_pc_knobColor = "#007bff"; // 指针蓝_pc_textColor = "#000000";_pn_textSize = 24;
模拟 液体容器 的液位高度,适用于水箱、油罐、反应釜等场景。
tank-circle.svg(圆形储罐)
tank-rectangle.svg(矩形储罐)
FUXA 通过 putValue('_pn_value', value) 将新数据推送到组件。
组件内部 JS 计算液位高度:
const height = (_pn_value - _pn_min) / (_pn_max - _pn_min) * containerHeight;使用 SVG <rect> 或 <path> 动态绘制液体区域。
更新 <text> 元素显示最新百分比。
// 绑定数据_pn_value = 45; // 当前液位 45%_pn_min = 0;_pn_max = 100;// 视觉优化_pc_borderColor = "#6c757d"; // 灰色边框_pc_waterColor = "#4ecdc4"; // 冷却水常用青色_pc_waterBorderColor = "#007bff"; // 蓝色边缘线_pc_textColor = "#ffffff"; // 白色文字(便于阅读)_pn_textSize = 20;
提供 用户输入与控制能力 ,实现人机交互闭环。
滑块(Slider)
计时器(Timer)
高精度计时器(High-Precision Timer)
一条水平灰色条带,左侧有一个红色三角形手柄。
可拖动调整位置。
用于调节连续型数值参数,例如:
电机转速(0~100%)
温度设定值(20~80°C)
流量控制(0~100 L/min)
💡 特点: 可拖拽 + 实时反馈 + 数据绑定
用户拖动滑块 → 触发 postValue('_pn_value', newValue)。
FUXA 将新值发送到绑定的数据标签(如 Motor_Speed)。
后端设备接收并执行相应动作(如调整PWM信号)。
_pn_currentValue = 60; // 当前转速 60%_pn_initValue = 50; // 启动时设为50%_pn_minVal = 0;_pn_maxVal = 100;_pc_defaultColour = "#dc3545"; // 红色(停机)_pc_clickedColour = "#28a745"; // 绿色(运行)
✅ 适用于需要精细调节的工业参数控制。
显示格式为 00:00:00,右侧带一个时钟图标。
支持启动/暂停/重置操作。
用于显示运行时间或倒计时,常见于:
生产周期计时
设备运行时长统计
安全倒计时(如紧急停机前)
💡 特点: 正计时 + 倒计时 + 控制按钮
点击“开始” → _pb_running = true → 开始计时
点击“暂停” → _pb_running = false
点击“重置” → _pt_time = "00:00:00"
_pn_timeMS = 1800000; // 30分钟_pc_baseColor = "#f8f9fa";_pc_baseStrokeColor = "#6c757d";_pc_textColor = "#000000";
✅ 适合用于流程监控、任务管理等场景。
显示格式为 00:00:00:000,即包含毫秒部分。
右侧同样带有时钟图标。
提供 毫秒级精度的时间记录 ,适用于:
实验测试流程分析
机器人动作响应时间测量
高频事件追踪
💡 特点: 支持 MS 级别 + 更高的时间分辨率
timer-hhmmssms.svg)⚠️ 注意:此组件与普通计时器属性几乎相同,但其内部逻辑处理的是 毫秒级精度 的时间。
🔄 工作机制
内部使用 JavaScript 的 setInterval() 实现每 10ms 更新一次。
时间以毫秒为单位存储在 _pt_time_ms 中。
通过 toLocaleTimeString() 或自定义函数格式化输出。
_pt_time_ms = 123456; // 1分23秒456毫秒_pb_running = true;_ps_format = "HH:MM:SS:MS";
✅ 适合科研、自动化测试、精密控制等对时间敏感的应用。
以 颜色分区 方式表示设备状态等级,强调异常预警。
analogIndicatorExample.svg(垂直条形灯)
timeDisplayHHmmSS.svg(计时器)
timeDisplayHHmmSSsss.svg(高精度计时器)
用途 :实时显示一个过程变量(_pn_value)相对于设定值(_pn_setpoint)的位置,并通过多色分区表示不同运行状态。
典型场景 :
温度监控(正常/高温/超高温)
压力控制(低压/正常/高压)
液位管理(低低/低/正常/高/高高)
💡 它比普通仪表更强大——不仅能显示数值,还能 同时展示安全边界和操作目标 。
整个指示器位于 <g id="analogIndicator" transform="translate(0,16)">
movingGroup 和 setpointGroup 初始 transform="translate(0,-350)",即在可视区上方
通过 JS 动态调整 transform 的 Y 值,使其“滑入”柱体对应位置
const scaledY = -((value - min) / (max - min)) * baseHeight;负号:因为 SVG Y 轴向下为正,而我们希望值越大位置越靠上
baseHeight = 350(由 baseIndicator 决定)
正常区 :从 _pn_normalLow 到 _pn_normalHigh
高区 :从 _pn_high 到 _pn_maxVal(顶部开始绘制)
低区 :从 _pn_lowLow 到 _pn_low(底部向上绘制)
这种设计确保即使阈值顺序变化(如 _pn_low > _pn_normalLow),也能正确渲染。
用途 :以 00:00:00 格式显示时间值(单位:毫秒输入,自动转换)
支持模式 :
正计时(Elapsed Time) :显示 _pn_timeMsET
倒计时(Countdown) :当 _pb_countDown = true 且 _pn_timeMsPT > 0 时,显示 _pn_timeMsPT - _pn_timeMsET
不包含毫秒 :适合对精度要求 ≤1 秒的场景(如周期监控、延时提示)
主要用途 :
正计时(Elapsed Time) :_pn_timeMsET → 显示已过去的时间
倒计时(Countdown) :_pn_timeMsPT(预设总时间) + _pb_countDown = true → 显示剩余时间
显示从 PLC 或脚本传入的 时间值(单位:毫秒)
支持两种模式:
时间格式 :HH:mm:ss:ms(如 01:30:45:123)
💡 它不是简单的时钟,而是 与控制系统深度集成的时间状态显示器 。
⚡ 适用于机器人节拍分析、实验测试等需要毫秒级精度的场景。
function formatTime(ms) {const hours = Math.floor(ms / 3600000);const minutes = Math.floor((ms % 3600000) / 60000);const seconds = Math.floor((ms % 60000) / 1000);const milliseconds = ms % 1000;return { hours, minutes, seconds, milliseconds };}
自动补零(padStart(2, '0'))
毫秒部分保留三位(padStart(3, '0'))
当 _pb_countDown = true 且 _pn_timeMsPT > 0 时:
若 _pn_timeMsET >= _pn_timeMsPT,显示 00:00:00:000
否则显示剩余时间:_pn_timeMsPT - _pn_timeMsET
⚠️ 注意:组件 不主动计时 ,依赖外部(如 PLC 或 FUXA 脚本)更新 _pn_timeMsET。
完全开放的自定义扩展入口 ,允许用户上传任意 SVG 文件并赋予数据驱动能力。
创建 my-widget.svg
在 <script> 中声明变量:
//!export-startlet _pb_alarm = false;let _pn_temperature = 25.0;let _ps_status = "Normal";//!export-end
实现 putValue() 更新逻辑
放入 server/_widgets/ 目录
在 FUXA 编辑器 → dynamicSVG 中选择该文件
必须包含唯一 id(如 <svg id="my-alarm-light">)
变量必须包裹在 //!export-* 注释中
支持 pc, pn, ps, pb 四种类型
可调用 postValue() 发送数据
自定义设备图标(风机、泵、阀门)
报警闪烁灯
流程图节点状态着色
动画效果(如旋转风扇)
FUXA 小部件的魔法,藏在这两行函数里:
// 接收数据(由 FUXA 主动调用)function putValue(id, value) {if (id === '_pn_value') {_pn_value = value;updateDisplay(); // 更新图形}}// 发送数据(用户操作触发)function postValue('_pb_start', true);
putValue :当绑定的数据源更新时,FUXA 自动调用此函数推送新值。
postValue :当你点击按钮或拖动滑块时,主动向后端发送指令。
整个过程 完全无感 ,开发者只需关注业务逻辑!
访问 GitHub:https://github.com/frangoteam/FUXA
克隆项目并运行 npm start
打开浏览器 → http://localhost:1881
拖拽小部件 → 绑定数据标签 → 预览运行!
💡 提示:所有预置小部件源码位于 server/_widgets/ 目录,可直接学习或修改。
FUXA 的小部件,就像工业界的“乐高积木”——简单、标准、可组合。无论你是自动化工程师、运维人员,还是 IoT 创业者,都能用它快速构建专业级监控界面。
真正的工业数字化,不该被复杂的开发门槛阻挡。
🌐开源地址 :https://github.com/frangoteam/FUXA
📚 官方文档 :https://github.com/frangoteam/FUXA/wiki
如果这篇文章对您有帮助,欢迎点赞、在看、转发,或在评论区留下你的应用场景!