简介:pvbrowser是一款源自德国的开源SCADA组态软件,基于QT库开发,跨平台运行于Windows、Linux和macOS,面向工业自动化、能源管理、楼宇自控等领域的工程师与研究者,解决远程设备监控、数据采集与过程控制需求。资源系统讲解了SCADA核心组件,包括数据采集、过程控制、人机界面、报警事件管理及历史数据记录,并具体介绍QT界面开发、OPC/MODBUS/TCP/IP等通信协议、实时数据处理、脚本扩展与数据库存储机制。通过阅读可掌握从图形化组态、设备配置到报警联动、历史查询的完整工作流,适合有一定C++或组态基础的技术人员做二次开发,也可用于教学演示。压缩包大小约27.65MB,文件总数与类型明细暂未提供;目前已有2663人学习下载,具有一定参考价值。
1. pvbrowser:基于QT的SCADA组态软件,为什么值得花一个周末去试
pvbrowser 是少有的把“QT 技术栈”和“组态软件思维”结合得比较自然的一个开源 SCADA 系统。很多人在选监控软件时先想到商业套件,授权贵、绑定重,想把几十个点位的画面快速跑起来,反而被工具本身拖住。pvbrowser 走的是服务器-客户端架构:服务器负责驱动、变量管理和场景服务,客户端负责显示画面,两者通过网络连接,实际部署时可以把服务器丢在现场一台工控机上,客户端放在办公室里远程查看。如果你有 Qt 基础、又不想进商业组态那套封闭生态,这个资源非常适合拿来改造成自己的监控框架。我这次拆解会从编译环境一直讲到驱动接入和避坑经验,力求你照着能跑起来。
2. 编译与初跑:搭建 Qt 环境、构建核心组件和首个示例工程
2.1 快速看懂 pvbrowser 的架构:pvserver 不是普通服务器
pvbrowser 的整个运行模型分为三层:组态编辑环境、运行时服务器、客户端显示。组态编辑环境是绘制画面和定义变量的地方;运行时服务器是核心,它负责加载组态文件、连接设备驱动、维护变量实时值;客户端显示则负责把服务器的画面呈现给操作员。
我第一次看到 pvbrowser 时容易和普通的 Web SCADA 混在一起。它本质上不走浏览器那套渲染,而是通过 Qt 的绘图机制在客户端画界面。一个典型的部署流程是:在开发机上用编辑环境画好界面,生成描述画面的 XML 文件和关联的变量表;把这一整套文件放到运行服务器的目录里;服务器启动后监听网络端口,客户端连上来就能看到画面。
2.2 环境准备与 Qt 版本选型
pvbrowser 依赖 Qt 的 core、gui、network、xml 等基础模块,官方长期使用的版本以 Qt 4 和 Qt 5 为主。我个人建议直接选 Qt 5.12 以上的环境,因为某些新版 PVE 工程里用到了高版本 Qt 才稳定支持的字符串处理接口,Qt 4 上编译会有大量兼容性工作要做。
以 Ubuntu 系统为例,需要安装的依赖包大致包括编译器和 Qt 开发库。安装命令如下:
# Ubuntu 下安装基础编译工具 sudo apt-get install build-essential git # 安装 Qt5 基础开发库 sudo apt-get install qtbase5-dev libqt5xmlpatterns5-dev libqt5svg5-dev # 安装网络相关依赖 sudo apt-get install libssl-dev这里的libqt5svg5-dev不是每次都必需,但当你后续导入 SVG 图元做管道、阀门图块时就会发现缺它不行。libssl-dev是给某些加密通信扩展用的,如果你只做内网 Modbus 采集,可以暂时不装,但装好能省很多反复排查依赖的时间。
2.3 从源码编译到第一个 Demo 工程跑通
拿到源码后,我建议先看一下根目录的组织结构:pvserver、pvclient、pvedesigner 这几个目录分别对应运行时服务器、客户端和编辑环境。编译入口是一个总的工程文件,直接用 qmake 加 make 就能构建全部组件。常见操作如下:
# 进入源码根目录 cd pvbrowser # 生成 Makefile,这里用 qt5 的 qmake qmake pvbrowser.pro # 多核编译,大概需要几分钟 make -j4编译完成后,可执行文件会分散在不同的子目录中,常用的三个是pvedesigner、pvserver和pvclient。先跑最简单的例子,通常是源码里自带的一个示例画面,启动方式一般是先起服务器,再起客户端连接。
# 先启动服务器,默认监听 28099 端口 ./pvserver -demo # 另开一个终端,启动客户端连接本地服务器 ./pvclient localhost如果你看到客户端窗口出现一个带几个按钮和仪表盘的画面,并且点击按钮能切换颜色,说明整条链路已经通了。这里有几个参数值得注意:-demo参数表示加载内置示例数据,不需要外部设备;localhost指定服务器地址,实际部署时改成现场工控机的 IP 即可。默认端口是 28099,在防火墙上要放行这个 TCP 端口,否则远程客户端会一直卡在连接界面。
3. 组态开发:从画图、绑定变量到输出真实可用的监控画面
3.1 面板编辑器:拖拽控件与 XML 画布之间的换算逻辑
pvedesigner 是 pvbrowser 用来绘制监控画面的工具,它的操作方式和常见组态软件类似,左侧是一排基本图元,中间是画布,右侧是属性面板。画布上的每个图元最终都会序列化成一段 XML 描述,服务器运行时就是在解析这段 XML 来决定把什么控件画在什么位置。
一个典型的模拟量显示控件在 XML 里长这样:
<io name="AI_Pressure" variable="PV_AI1" format="0.00" unit="MPa"> <geometry x="120" y="80" width="160" height="40"/> <color fg="#000000" bg="#dcdcdc"/> </io>xml 说明:variable绑定到运行时变量名,format定义显示小数位,geometry里的四个数字分别对应控件左上角坐标和宽高。实际拖拽时,编辑器会自动生成这一段,不需要手写;但如果要批量生成几十个相似的控件,直接改 XML 再导入比逐个拖拽高效得多。
3.2 变量类型映射:从 PLC 寄存器到界面控件的完整链路
pvbrowser 中的变量围绕“标签(tag)”组织,每个标签绑定一个驱动通道。驱动读取到的原始值(整数、短整型、布尔、浮点)会先归一化到运行时内部表示,再分发到画面控件上。绑定工作大部分在驱动配置界面完成,少部分在 XML 里直接指定。
以 Modbus 保持寄存器为例,一个地址绑定的核心参数包括:设备地址(单元号)、寄存器地址、数据类型、字节序、缩放系数和工程单位。这套参数在选择 Modbus 驱动后逐项填入即可。配置完成后可以在 pvserver 里启动一个调试通道,输出实时变量的值,用来确认链路是否通畅。
# 启动服务器时增加调试输出 ./pvserver -v -logvar PV_AI1-v表示打开详细日志,-logvar PV_AI1表示只输出名为 PV_AI1 的变量变化情况。这个技巧排查驱动采集问题时非常实用,你不需要在画面里反复刷新,直接看终端就能判断是设备没有回复,还是数据类型解析错了。
3.3 用样式表做工业配色与场景切换
pvbrowser 的控件外观除了在编辑器里指定,还支持一种类似 CSS 的样式描述,用它可以快速实现统一配色和报警变色。常见的应用是让正常状态显示绿色,越限报警变成红色闪烁。样式定义的格式通常写在场景配置里,例如:
value_ok { color: #00cc00; background-color: #1e1e1e; } value_over { color: #ff0000; background-color: #1e1e1e; }配合变量绑定的报警上下限,一旦采集值超过阈值,控件会自动切换到value_over的样式。这套做法在项目交付阶段很有用:你可以把整个画面的配色方案集中管理,业主说“颜色太刺眼”,改一个地方就能全画面生效。
4. 驱动接入:Modbus、OPC UA 与自写协议驱动的扩展路径
4.1 内置驱动盘点与选用原则
pvbrowser 自带了一批常见工业协议驱动,覆盖了大多数低成本采集场景。我在实际项目中用的较多的是 Modbus TCP、Modbus RTU 和 OPC UA 这三类。选用原则很简单:设备支持网络通信优先用 TCP,只有串口就选 RTU,上位机对接有现成 OPC 服务器时用 OPC UA。
Protocol 选型对照表:
| 协议 | 适用场景 | 建议参数 | 备注 |
|---|---|---|---|
| Modbus TCP | PLC、远程 IO、电表 | Port 502,Unit ID 区分设备 | 排查最快,先 ping 通再谈协议 |
| Modbus RTU | 串口仪表、老式控制器 | Baudrate 9600/19200,Parity 常用 Even | 注意串口被占用 |
| OPC UA | 连接其他组态软件或数据库 | Endpoint URL 设置 | 证书管理是最容易踩坑的地方 |
4.2 手写一个模拟驱动:从零接入自定义协议
内置驱动覆盖不了非标设备,类似某些温控器用的是厂家自定义 ASCII 协议。pvbrowser 支持自定义驱动扩展,通常是编写一个独立的动态库,实现指定的回调接口。一个最简单的模拟驱动模型如下:
// 模拟驱动,读取一个内存数组作为变量来源 class SimulatedDriver { public: void init() { // 初始化变量表,给 PV_AI1 赋初值 25.0 } bool readValue(const std::string& varName, double& out) { // 按变量名从内存数组取值 if (varName == "PV_AI1") { out = 25.0; return true; } return false; } void writeValue(const std::string& varName, double value) { // 写入回调,例如设置 PV_SP1 } };代码逻辑不复杂:init()在服务器启动时被调用一次,用来注册变量和分配资源;readValue()是周期性采集的入口,返回对应的实时值;writeValue()处理画面下发的指令。实际编写时,需要注意两点:读函数要执行得足够快,不要在回调里做耗时操作;数据源是串口时,需要自己处理互斥锁,避免同时读写同一个串口句柄。
4.3 告警联动与脚本控制:让画面动起来
多数监控场景不止是显示数字,还需要在异常时弹提示、闪光、联动输出。pvbrowser 的告警机制通常围绕变量上下限展开,配置好阈值后服务器会维护告警状态。联动控制通常靠脚本逻辑,常见做法是在服务器侧运行一个周期任务,扫描指定变量的告警位,然后向其他变量写入控制指令。例如某个温度变量越限后,把阀门开度变量写成 0:
# 示意:告警触发后关闭阀门 if alarm(AI_TEMP_1) then writeVar(DI_VALVE_1, 0) endif这里不纠结具体语法,重点是让你理解数据流向:告警状态是布尔量,控制输出是模拟量或开关量,整个联动是通过变量读写来完成的,不需要在画面层做逻辑。这样做的优势是,后期更换画面对逻辑没有任何影响。
5. 避坑排查:编译、运行、中文显示和通信的常见问题
5.1 编译中断:找不到 Qt 头文件或私有类报错
现象:qmake 成功但 make 报错,提示缺少QtGui/QApplication或某些私有头文件。
原因:多数情况是系统安装了多个 Qt 版本,qmake 指向了 Qt4,导致头文件路径不匹配。
解决:用which qmake检查路径,确认是 Qt5 版本;如果不对,手动指定 qmake 路径再重新生成 Makefile。
# 强制使用 Qt5 的 qmake /usr/lib/qt5/bin/qmake pvbrowser.pro make clean && make -j45.2 运行时客户端卡在“正在连接”
现象:服务端已启动,但客户端一直连接不上,局域网内其他机器也连不上。
原因:最常见是防火墙挡掉了 28099 端口;其次是服务器只监听了本机回环地址。
解决:先在本机用pvclient localhost验证服务是否正常,再用netstat -an | grep 28099查看监听地址。如果只监听 127.0.0.1,需要在启动参数里指定对外网卡地址。
5.3 中文字体显示成方块或乱码
现象:画面中的中文标签在开发机上正常,部署到现场工控机后变成方块。
原因:工控机上没有安装相应的中文字体,Qt 回退到默认字体失败。
解决:把常用中文字体文件随工程一起分发,并在启动脚本中通过环境变量指定字体路径。做法是把.ttf放到字体目录,再执行fc-cache刷新字体缓存,之后重启 pvserver 即可。
5.4 Modbus 采集值忽大忽小
现象:同一个寄存器读出来的温度,画面显示有时翻倍或变成负数。原因是 Modbus 协议对 16 位寄存器的字节序在不同设备上不一致,常见的 A/B 字节排列都会遇到。解决方法是把驱动配置里的字节序从“A-B”改成“B-A”,并设置数据类型为无符号短整型,确认后数据就稳定了。
6. 进阶玩法:用 WebSocket 把桌面组态画面搬到浏览器
6.1 启用 WebSocket 扩展支持
桌面客户端适合操作站,但很多管理层大屏和领导查看场景需要浏览器直接看到画面。pvbrowser 的较新版本里集成了 WebSocket 接口能力,启用方式是在启动服务器时增加一个扩展参数,并确保 Qt 的 network 模块被编译进去。启用后,浏览器可以直接连接到转换后的 Web 端口,不需要再额外装插件。我一般在服务器启动脚本里加一段判断,动态决定是否加载 WebSocket 模块。
6.2 性能边界与混合部署经验
WebSocket 方式在画面简单、刷新频率超过 500ms 时表现尚可,但单页面图元超过 200 个、变量刷新低于 200ms 时,浏览器的渲染瓶颈会比较明显。我的做法是:操作员站仍用 pvclient 桌面端,大屏展示单独做一个精简画面走浏览器。带 DCS 系统对接时,很多厂家只允许单向数据流,正好用浏览器客户端做只读展示,不向服务器下发指令,这样既满足了展示需求,又控制住了安全边界。从那以后我每次做远程查看需求,都强制先走一遍“分清可写与只读回路”的设计,再动配置,少踩了许多后来的大坑。希望帮到你。
本文还有配套的精品资源,点击获取