1. 项目缘起与整体设计思路
1.1 为什么选择Ricon组态系统做物联网监控平台
先说结论:如果你手头有一堆传感器、PLC、仪表,需要快速搭一个能看、能控、能报警、能存数据的监控界面,又不想从零写前端后端,Ricon组态系统是目前国内工控圈里落地成本最低的方案之一。我自己做过好几个中小型物联网监控项目,从智慧农业大棚到小型污水站,再到车间设备状态看板,Ricon都是主力工具。它的核心价值在于:图形化拖拽组态 + 内置数据采集驱动 + 脚本扩展能力,让你把精力放在业务逻辑上,而不是纠结WebSocket怎么重连、ECharts怎么调样式。
这个项目标题说的是“从零开始构建物联网监控平台”,我理解的需求场景是这样的:现场有若干传感器(温湿度、液位、压力、电表等),通过Modbus RTU/TCP、MQTT或者OPC UA把数据汇聚上来,需要在Ricon里做一个实时监控画面,包含实时数据展示、历史曲线、报警推送、报表导出,最好还能远程控制设备启停。这套东西做下来,如果纯手写代码,前端加后端至少两周起步;用Ricon组态,熟练的话两三天就能出第一版可演示的系统。
适合谁来参考这篇内容?我觉得三类人最合适:一是工控转物联网的工程师,熟悉PLC但不太会写Web;二是做物联网毕业设计的学生,需要快速出成果;三是系统集成商的实施人员,经常要现场快速搭原型。如果你已经有一套成熟的ThingsBoard或ThingsLinks平台,那Ricon可能不是最优解,但如果你追求的是单机部署、离线可用、上手快,Ricon的性价比非常高。
1.2 整体架构分层与数据流向设计
我在动手之前习惯先把架构画清楚,哪怕只是在纸上画个草图。Ricon组态系统的物联网监控平台,我一般分成四层来设计:
第一层是现场设备层。这一层就是各种传感器、执行器、PLC、智能仪表。它们对外提供的接口无非几种:Modbus RTU(RS485/RS232)、Modbus TCP、MQTT、OPC UA、西门子S7协议等。你需要提前确认每个设备的通信协议、寄存器地址表、数据类型(16位整数、32位浮点、大小端顺序)。这一步偷懒,后面调试会让你痛不欲生。
第二层是数据采集与网关层。Ricon本身可以跑在工控机或Windows服务器上,通过串口或网口直接采集设备数据。但如果设备分散、距离远,我建议加一个物联网网关做协议转换和边缘计算。比如用STM32跑FreeRTOS做一个Modbus RTU转MQTT的网关,把485总线上的数据打包成JSON发到Ricon的MQTT Broker。这样做的好处是:Ricon只负责订阅MQTT主题,不用关心底层总线细节,系统解耦更彻底。
第三层是Ricon组态平台层。这是核心。Ricon内部有实时数据库、报警引擎、历史存储、脚本引擎、画面组态几个模块。实时数据库负责缓存当前值,报警引擎根据设定阈值触发报警,历史存储把数据写入内置的SQLite或外部数据库,脚本引擎用来做数据加工和逻辑控制。
第四层是展示与交互层。包括PC端监控画面、移动端适配页面、大屏看板、报表导出。Ricon支持Web发布,也支持客户端运行,看项目需求选择。
数据流向是这样的:设备 → 采集驱动 → 实时数据库 → 画面绑定/报警判断/历史记录 → 用户交互。反向控制则是:用户点击按钮 → 脚本执行 → 写入设备寄存器 → 设备动作。整个链路里,实时数据库是枢纽,所有数据都围绕它转。
1.3 方案选型中的几个关键取舍
在实际项目中,有几个选型决策会直接影响开发效率和后期维护成本,我逐个说一下我的思考。
第一个取舍:Ricon直连设备还是通过网关中转?如果设备数量少于10台、通信距离在50米以内、协议统一是Modbus RTU,我倾向Ricon直连,少一个环节少一个故障点。但如果设备超过20台、分布在不同的车间或楼层、协议五花八门,那必须上网关。网关的好处是边缘侧可以做数据过滤和缓存,网络断了也不丢数据,恢复后自动补传。我吃过亏:早期一个项目Ricon直连30台485设备,轮询周期设了500ms,结果总线冲突严重,数据丢包率超过15%。后来改成网关分片采集,每片10台设备,轮询周期200ms,丢包率降到0.1%以下。
第二个取舍:历史数据存Ricon内置库还是外部数据库?Ricon内置的SQLite适合数据量小、单机运行的场景,部署简单,零配置。但如果你的测点超过500个、存储周期小于10秒、需要保留一年以上,那SQLite会越来越慢,查询历史曲线时明显卡顿。我的经验是:测点少于200个、存储间隔30秒以上,用内置库没问题;超过这个规模,果断上MySQL或PostgreSQL,Ricon支持通过ODBC写入外部库。
第三个取舍:报警推送用Ricon自带还是自己写?Ricon自带的报警窗口和声音提示适合本地监控场景。但如果需要推送到手机、钉钉、企业微信,就得用脚本调用外部API。我一般会在Ricon脚本里写一个HTTP请求函数,报警触发时把消息POST到自己的消息服务,再由消息服务转发到各个渠道。这样灵活度最高,也方便做报警分级和值班排班。
2. 核心细节解析与实操要点
2.1 设备接入前的准备工作:寄存器表与通信参数确认
这一步是很多新手最容易忽略的,也是后期调试最耗时间的环节。我现在的习惯是:拿到设备后,第一件事不是打开Ricon,而是先整理一份设备通信参数表。这份表至少包含以下字段:
| 字段 | 说明 | 示例 |
|---|---|---|
| 设备名称 | 现场标识 | 1号大棚温湿度 |
| 通信协议 | Modbus RTU/TCP等 | Modbus RTU |
| 从站地址 | 站号 | 1 |
| 串口参数 | 波特率/数据位/停止位/校验 | 9600/8/1/None |
| 寄存器地址 | 十进制或十六进制 | 40001 |
| 数据类型 | 16位整数/32位浮点等 | 16位有符号整数 |
| 字节序 | 大小端 | 大端 |
| 缩放因子 | 原始值乘多少得实际值 | 0.1 |
| 单位 | 物理单位 | ℃ |
| 读写权限 | 只读/读写 | 只读 |
这份表看起来繁琐,但有了它,在Ricon里配置驱动就是填表工作,不需要反复翻设备手册。我一般用Excel维护,配置完一个设备就打个勾,避免遗漏。
注意:Modbus寄存器地址有“协议地址”和“PLC地址”两种表示方式。协议地址从0开始,PLC地址从1开始,而且40001这种表示法对应的是保持寄存器。如果你在Ricon里填了40001但读不到数据,先试试填0或者1,大概率是地址偏移问题。
2.2 Ricon驱动配置的实操细节
Ricon支持多种驱动,我以最常用的Modbus RTU和MQTT为例,说一下配置要点。
Modbus RTU驱动配置:在Ricon的设备驱动里新建一个Modbus RTU设备,选择正确的串口号(在Windows设备管理器里确认COM号),设置波特率、数据位、停止位、校验位,这些必须和设备手册完全一致。然后添加变量,每个变量对应一个寄存器地址。这里有个细节:连续地址的变量尽量放在一个采集块里,Ricon会合并请求,减少总线通信次数。比如你要读40001到40010这10个寄存器,就建一个采集块,起始地址40001,长度10,而不是建10个单独的变量。实测下来,合并采集比单独采集效率高3到5倍。
MQTT驱动配置:如果走网关方案,Ricon作为MQTT客户端订阅主题。配置时需要填Broker地址、端口、客户端ID、用户名密码、订阅主题。我一般让网关把数据发到一个统一主题,比如/iot/gateway/001/data,payload是JSON格式。Ricon收到后,用脚本解析JSON,把各个字段映射到实时数据库的变量上。这里的关键是JSON字段名和Ricon变量名要有一一对应的映射表,否则脚本会写得很乱。
// Ricon脚本示例:解析MQTT JSON并写入变量 var payload = JSON.parse(msg); SetTagValue("temp_01", payload.temp); SetTagValue("humi_01", payload.humi); SetTagValue("press_01", payload.press);这段脚本看起来简单,但实际项目中要考虑字段缺失、类型转换、异常捕获。我一般会加一层判断:
try { var payload = JSON.parse(msg); if (payload.temp !== undefined) SetTagValue("temp_01", parseFloat(payload.temp)); if (payload.humi !== undefined) SetTagValue("humi_01", parseFloat(payload.humi)); } catch (e) { LogError("JSON解析失败: " + e.message); }2.3 实时数据库变量命名规范与分组策略
变量命名这件事,项目小的时候无所谓,项目一大就是灾难。我见过一个项目,变量名从tag1一直排到tag800,后期维护的人完全不知道哪个是哪个。我的建议是采用分层命名法:区域_设备类型_设备编号_参数名。比如A1_TH_01_TEMP表示A1区域1号温湿度传感器的温度值。这样一看名字就知道是什么,排序也整齐。
分组策略上,我一般按画面和功能两个维度来分。按画面分,就是每个监控画面用到的变量放一组,方便画面绑定时快速查找。按功能分,就是报警变量一组、历史存储变量一组、控制变量一组。Ricon支持变量分组,我通常两个维度都建,用不同的分组前缀区分。
实操心得:变量建好后,先导出一次变量列表备份。后期如果误删或者改乱了,可以直接对照恢复。这个习惯帮我省过好几次事。
3. 实操过程与核心环节实现
3.1 从零搭建:Ricon工程创建与画面规划
打开Ricon,新建工程,第一步是设置工程属性:工程名称、分辨率、背景色、启动画面。分辨率我一般设1920×1080,适配大多数工控机和显示器。如果要做大屏,可以设3840×2160,但画面元素要相应放大。
画面规划我遵循三级导航原则:一级是总览画面,展示整个系统的关键指标和状态;二级是分区域画面,比如1号车间、2号车间;三级是设备详情画面,展示单台设备的全部参数和控制按钮。这样用户从总览点进去,逐层深入,不会迷路。
总览画面我一般放这几个元素:系统标题、当前时间、关键测点数值(用大字号)、设备状态指示灯(绿色运行、红色故障、灰色离线)、报警滚动条、导航按钮。关键测点的选择标准是:老板一眼想看的和值班人员必须盯的。比如污水站项目,总览上就是进水COD、出水COD、pH值、流量、液位,这几个参数直接反映系统运行状态。
3.2 数据绑定与动态效果实现
画面画好后,下一步是把变量绑定到画面元素上。Ricon的绑定方式很直观:选中一个文本显示框,在属性里找到“变量”一栏,填入变量名或者从变量选择器里选。数值显示可以设置格式,比如保留两位小数、加单位、超限变色。
超限变色这个功能特别实用。我一般这样配置:温度正常范围是15到30度,低于15度显示蓝色,高于30度显示红色,正常显示绿色。实现方式是在文本的属性里设置“颜色动画”,绑定变量,设置不同数值区间的颜色。这样值班人员不用看数字,看颜色就知道有没有异常。
动态效果方面,Ricon支持旋转、移动、闪烁、填充等动画。比如风机运行的时候,画一个风扇图标,绑定风机的运行状态变量,运行时旋转,停止时静止。液位用填充动画,绑定液位变量,填充高度随液位变化。这些效果不需要写代码,配置一下就行,但视觉效果提升很大。
// 按钮点击脚本示例:控制设备启停 if (GetTagValue("device_status") == 0) { SetTagValue("device_cmd", 1); // 下发启动命令 ShowMessage("设备启动命令已下发"); } else { SetTagValue("device_cmd", 0); // 下发停止命令 ShowMessage("设备停止命令已下发"); }注意:控制类操作一定要加二次确认。我见过太多误触导致设备意外停机的案例。Ricon有确认对话框组件,拖一个出来,把控制脚本放在确认之后执行。
3.3 报警配置与历史存储设置
报警配置是监控平台的核心功能之一。Ricon的报警配置分两步:先定义报警变量和报警条件,再配置报警显示和推送。
报警条件我一般设四级:低低报、低报、高报、高高报。比如温度:低于5度低低报,5到10度低报,30到35度高报,高于35度高高度。每级报警可以设置不同的颜色和声音。低低报和低报用黄色,高报和高高报用红色,声音也可以区分,高报用急促的蜂鸣,低报用缓慢的提示音。
历史存储配置要注意几个参数:存储间隔、存储时长、死区。存储间隔根据参数变化速度来定,温度变化慢,30秒存一次够了;压力变化快,5秒存一次。存储时长看需求,一般保留3个月到1年。死区是指数值变化超过多少才存储,比如温度死区设0.5度,变化小于0.5度就不存,这样可以大幅减少数据量。
| 参数类型 | 存储间隔 | 死区 | 存储时长 |
|---|---|---|---|
| 温度 | 30秒 | 0.5℃ | 1年 |
| 湿度 | 30秒 | 1% | 1年 |
| 压力 | 5秒 | 0.01MPa | 6个月 |
| 流量 | 10秒 | 0.1m³/h | 6个月 |
| 电参量 | 1分钟 | 0.5kW | 1年 |
这张表是我根据多个项目经验总结的,可以直接参考。当然具体项目要具体调整,原则是:变化快的参数存密一点,变化慢的存疏一点;重要的参数存久一点,次要的存短一点。
3.4 脚本扩展:数据加工与逻辑控制
Ricon的脚本引擎是基于JavaScript的,支持定时脚本、事件脚本、画面脚本。我常用的场景有三个:数据加工、逻辑联动、外部通信。
数据加工比如把原始值转换成实际值、计算累计量、做滑动平均滤波。逻辑联动比如当温度超过30度自动开启风机,当液位低于20%自动关闭水泵。外部通信比如把报警推送到消息服务、定时从天气API获取数据。
// 定时脚本示例:每5秒执行一次,计算滑动平均温度 var temp = GetTagValue("temp_01"); var avg = GetTagValue("temp_01_avg"); if (avg == null) avg = temp; var newAvg = avg * 0.8 + temp * 0.2; // 一阶滤波 SetTagValue("temp_01_avg", newAvg);这个一阶滤波算法简单但有效,能平滑掉传感器跳变。系数0.8和0.2可以根据需要调整,系数越大越平滑但响应越慢。
实操心得:脚本里尽量少用循环和复杂计算,Ricon的脚本引擎性能有限,复杂的逻辑建议放到网关或外部服务里做。我试过在Ricon脚本里做100个变量的批量处理,执行时间超过500ms,导致画面卡顿。后来改成网关预处理,Ricon只负责展示,流畅多了。
4. 常见问题与排查技巧实录
4.1 通信类问题排查速查表
通信问题是物联网监控平台最常见的故障,我整理了一份速查表,覆盖80%以上的场景。
| 现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| 所有设备离线 | 串口被占用/网线断开 | 检查设备管理器/ping网关 | 关闭占用程序/更换网线 |
| 部分设备离线 | 从站地址冲突/线路接触不良 | 逐个ping/检查接线端子 | 修改地址/重新压接 |
| 数据时有时无 | 轮询周期太短/总线干扰 | 延长周期观察/检查屏蔽线 | 调整周期/加磁环 |
| 数据值不对 | 寄存器地址错/数据类型错 | 用Modbus调试工具验证 | 修正地址/类型 |
| 数据不变化 | 死区设置过大/采集未启用 | 检查死区和采集配置 | 调整死区/启用采集 |
| MQTT断连 | 网络波动/心跳超时 | 查看Broker日志 | 调整心跳/加断线重连 |
这张表我打印出来贴在工位上,遇到问题先对照排查,效率很高。
4.2 画面卡顿与性能优化
画面卡顿是Ricon项目做大了之后常见的问题。原因无非几个:变量太多、刷新太快、动画太复杂、历史查询太重。
我的优化顺序是这样的:先降刷新频率。Ricon默认画面刷新是1秒,如果变量多,改成2秒或3秒,肉眼几乎看不出差别,但CPU占用能降一半。再减动画效果。闪烁、旋转这些动画很吃资源,非必要的去掉,必要的降低帧率。然后优化历史查询。历史曲线一次不要查太多点,比如查一天的数据,先降采样到1000个点再显示,不要直接查原始数据。最后考虑分画面加载。把不重要的画面做成弹窗或子画面,需要时才加载,减少主画面的变量数量。
我做过一个项目,主画面绑了800多个变量,刷新周期1秒,CPU占用常年70%以上。后来把刷新改成3秒,动画减掉一半,变量分组按需加载,CPU降到20%以下,画面流畅多了。
4.3 数据丢失与补传机制
网络不稳定的时候,数据丢失是难免的。我的做法是在网关侧做本地缓存+断点续传。网关采集到数据后,先写入本地环形缓冲区,然后尝试发送到Ricon。如果发送失败,数据留在缓冲区,等网络恢复后按时间顺序补传。缓冲区大小根据网络中断的最长时间来定,一般存1小时的数据就够了。
Ricon侧也要做处理:收到补传数据时,按时间戳写入历史库,而不是按当前时间。这样历史曲线不会出现断档。Ricon的脚本里可以用SetTagValueWithTime函数指定时间戳写入。
注意:补传数据可能会重复,Ricon侧要做去重。我一般在历史库表上建唯一索引,时间戳+变量名唯一,重复数据自动忽略。
4.4 报警泛滥与分级处理
报警泛滥是另一个常见问题。一个传感器故障,可能触发几十条报警,值班人员根本看不过来。我的解决方案是报警分级+报警抑制。
报警分级就是前面说的四级报警,不同级别走不同的推送渠道。低报只记录不推送,高报推送到值班群,高高报推送到负责人并打电话。报警抑制是指:同一个设备的多个报警,只推最高级别的那条;关联设备的报警,合并成一条综合报警。
Ricon的脚本里可以实现报警抑制逻辑:维护一个报警状态表,新报警来时先查表,如果已有更高级别的报警,就忽略;否则更新表并推送。
// 报警抑制脚本示例 var deviceId = "A1_TH_01"; var newLevel = 3; // 高报 var currentLevel = GetTagValue(deviceId + "_alarm_level"); if (newLevel > currentLevel) { SetTagValue(deviceId + "_alarm_level", newLevel); SendAlarm(deviceId, newLevel); }这套逻辑跑下来,报警数量能减少70%以上,值班人员也能抓住重点。
4.5 项目交付前的检查清单
项目做完准备交付的时候,我一般会过一遍检查清单,避免现场翻车。
- 所有设备的通信状态是否正常,有没有离线设备
- 所有变量的实时值是否合理,有没有明显异常
- 报警阈值是否按客户要求设置,报警测试是否通过
- 历史存储是否正常写入,历史曲线能否正常查询
- 控制功能是否正常,二次确认是否生效
- 画面导航是否顺畅,有没有死链接
- 用户权限是否配置,不同角色能否看到对应画面
- 系统日志是否开启,方便后期排查
- 工程文件是否备份,版本号是否记录
- 客户培训是否完成,操作手册是否交付
这份清单我每次交付前都过一遍,虽然花半小时,但能避免90%的现场问题。
5. 从原型到生产:部署与运维经验
5.1 工控机选型与系统部署
Ricon一般跑在Windows工控机上。工控机选型我关注几个点:CPU性能、内存、硬盘、串口数量、网口数量、电源。CPU至少i3,推荐i5;内存至少8G,推荐16G;硬盘用SSD,至少256G;串口根据设备数量选,不够就用USB转串口;网口至少两个,一个接设备网,一个接办公网;电源要宽压输入,工业现场电压波动大。
系统部署我一般这样做:先装Windows 10 LTSC版,稳定不自动更新;然后装Ricon,装驱动,装数据库;接着配置开机自启动,Ricon和数据库都要设成服务;最后做系统备份,用Ghost或者DiskGenius做个镜像,出问题了直接恢复。
实操心得:工控机一定要设自动登录和断电重启。现场经常停电,来电后要能自动恢复运行,不能等人去按开机键。BIOS里设置“AC Power Loss”为“Power On”,Windows里设置自动登录,Ricon设置开机自启,这三步做完,基本可以无人值守。
5.2 远程维护与版本更新
项目交付后,远程维护是常态。我一般用两种方式:远程桌面和Web发布。远程桌面用Windows自带的RDP或者TeamViewer,方便操作Ricon工程。Web发布让客户用浏览器就能看画面,不用装客户端。
版本更新要谨慎。我的流程是:先在测试环境改好,导出工程文件;然后远程到现场,备份当前工程;接着导入新工程,重启Ricon;最后验证功能,没问题就保留,有问题就回滚。整个过程一般15分钟,但一定要在非生产时段做,避免影响客户使用。
5.3 数据安全与权限管理
数据安全方面,我关注三点:备份、权限、审计。备份就是定期导出历史数据和工程文件,存到不同的地方。权限就是Ricon的用户管理,不同角色分配不同权限,操作工只能看不能改,工程师可以改配置,管理员可以改所有。审计就是操作日志,谁在什么时候做了什么操作,都要记录,方便追溯。
Ricon的用户管理支持角色和用户两级,我一般设三个角色:观察者、操作员、管理员。观察者只能看画面,操作员可以控制设备但不能改配置,管理员什么都能做。密码策略要求至少8位,含大小写和数字,定期更换。
6. 扩展方向:从单机监控到物联网平台
6.1 对接第三方物联网平台
Ricon做单机监控很强,但如果要接入更大的物联网平台,比如ThingsBoard、ThingsLinks或者自研平台,就需要做数据转发。我的做法是在Ricon脚本里写一个MQTT发布函数,把实时数据转发到平台的主题上。平台侧再做存储、分析、展示。
// 数据转发脚本示例 var data = { deviceId: "A1_TH_01", temp: GetTagValue("temp_01"), humi: GetTagValue("humi_01"), timestamp: new Date().getTime() }; MQTTPublish("/iot/upload/A1_TH_01", JSON.stringify(data));这样Ricon就变成了一个边缘网关,既做本地监控,又做数据上传。两边互不干扰,本地断网了平台数据会断,但本地监控不受影响。
6.2 移动端适配与消息推送
移动端我一般不做原生App,而是用Ricon的Web发布功能,做一个响应式页面,手机浏览器直接访问。关键指标用大字号,控制按钮做大一点,方便触摸操作。消息推送用企业微信或者钉钉的机器人,Ricon脚本里调用Webhook接口,把报警消息发到群里。
6.3 数据分析与报表自动化
Ricon自带报表功能,可以配置日报、月报,自动生成Excel或PDF。我一般会配置几个固定报表:日报表展示当天关键参数的最大值、最小值、平均值;月报表展示每月的累计量和报警统计;自定义报表让用户选时间段和参数,按需生成。报表可以定时生成,自动发送到指定邮箱。
这套东西做下来,Ricon就不只是一个监控画面工具,而是一个完整的物联网监控平台。从零开始到交付,熟练的话两周左右,新手一个月也能搞定。关键是要把架构想清楚,把变量规划好,把报警和存储配置对,剩下的就是拖拽和调试的体力活了。