我做自动化监控和工业数据采集这些年,见了不少钻机、修井机、勘探设备,最头疼的永远是数据不通:PLC牌子杂、协议乱、厂家数据接口要么收费要么根本不开放。后来我们一个项目用上了openrig,算是把这摊子事理顺了。简单说,openrig是一个开放式的钻机与勘探设备数据采集监控平台,核心就是把不同设备、不同协议的数据统一收上来,再通过一套轻量云服务存起来、展示出来,还能自己加告警规则。它特别适合钻井队信息化改造、设备厂商做远程售后、以及想快速搭一套设备数据中台的团队。这篇就把我怎么从零搭起一套openrig、踩了哪些坑、参数怎么调,一次性说清楚。
1. 项目全貌与设计思路拆解
1.1 openrig到底解决什么问题
很多现场设备的监控现状是“看得见但摸不着”:仪表盘在司钻房里,数据只能在本地看。想远程监控?有的设备支持Modbus,有的走CAN总线,有的干脆是干接点信号。不同厂家用不同协议,甚至同厂不同批次都不一样。openrig的思路不是做一套万能协议转换器,而是把“采集、传输、存储、展示”这条链路的骨架搭好,协议适配的部分用插件和规则引擎去填。也就是说,它给你一个框架,适配工作自己做,反而比全封闭商业系统灵活得多。
1.2 为什么选择开放式架构
封闭系统的核心问题是“改不动”。比如想加一个传感器点位,商业平台上往往要联系原厂,一个点几百上千是常态。openrig这种开放架构,点位配置就是个配置文件,新增传感器把信号采集上来、映射成统一数据模型、看板里挂上去,半天就能搞定。对于钻井队这种“今天加个泥浆泵压力,明天补个井深编码器”的高频变化场景,开放架构的边际成本优势非常明显。
在方案选型时我们也在“自己从零写一套采集系统”和“用openrig改改”之间犹豫过。从零写的问题是工作量全在边缘侧,而且数据模型容易越写越乱。openrig自带标准数据模型和一批现成驱动,省掉的其实是架构设计这层功夫。哪怕只用到它一半功能,也比从空白文件开始强。
1.3 核心组件与整体链路
openrig在逻辑上分成四块:
- 采集终端:跑在现场的网关盒子,负责接传感器和设备信号。硬件可以是工控机、树莓派或者支持Debian的ARM板子。
- 协议解析层:把Modbus RTU、Modbus TCP、DLT645、OPC UA乃至自定义报文统一解析成内部标准格式(后面细讲)。
- 数据服务层:用MQTT接收边缘网关的数据,写入时序数据库,再通过API供前端读取。告警规则也在这层跑。
- 可视化看板:显示器上能看到实时参数、历史趋势和告警列表,这是跟甲方汇报和日常监管用的主界面。
链路关系上,采集终端是根,数据服务是腰,看板是脸。很多人上来先做看板,这事我反对。得先把数据链路从设备端一路打通到数据库,确认数据落地了,再做看板也就一两个小时的活。
2. 硬件选型与传感接入的实战分析
2.1 采集网关怎么选
openrig对硬件没有依赖关系,我试过几类,这里按性价比和稳定性排序:
- 工业无风扇工控机:双网口、带串口、支持宽温,是现场首选。价格八百到两千之间,性能完全够。建议选带隔离串口的型号,现场雷击和变频干扰下稳很多。
- 树莓派/ARM开发板:适合实验室开发验证,极限温度环境不建议上井。无风扇或用好一点的散热片,勉强能扛。
- 旧笔记本:临时调试很好用,键盘鼠标显示器都现成,但别当长期方案,震动和供电稳定性不行。
我们现场用的是一款赛扬J4125的工控机,8G内存,128G SSD,两个千兆网口,四个隔离串口,露天实测零下二十度到正午四十多度都没出过问题。选它的理由很简单:被动散热(没风扇),支持12V/24V宽压输入,可以直接从钻机蓄电池取电。
2.2 传感器点位的规划
钻井现场要采的参数,早期的经验就九个字:压、温、流、速、位、重、扭、率、浆。
举例来说:
- 泵压和立压:通常是4-20mA变送器。
- 泥浆池液位:静压式液位计,也是4-20mA。
- 转盘转速:接近开关测脉冲,转一圈两个脉冲。
- 大钩高度:编码器脉冲或SSI信号。
- 柴油机转速:不少老设备是频率信号,要算周期。
布点之前最重要的是画一张I/O表。用Excel列就行:点位名称、信号类型、量程、接入的采集模块通道号、转换公式、告警阈值。这个表不只是规划,后面做配置文件时要逐项照着填。最怕的是现场边接边改,结果写配置文件时对上不上。
2.3 模拟量采集与信号隔离
4-20mA信号抗干扰能力比0-10V好,能传得远。openrig采集终端里模拟量输入模块选的是八通道4-20mA采集,带24位ADC和光电隔离。带隔离的模块比不带的贵一两百块,但这个钱不能省。现场变频器一启动,不隔离的模拟量通道会有很大波动,看起来就是参数乱跳。光电隔离能切断共地回路,大幅减少这种干扰。
接线时要注意:
- 屏蔽层单端接地,通常是靠近采集模块那一端接。两端都接地容易形成地环路,反而引入更多干扰。
- 4-20mA的24V供电尽量不要和变频器主回路共用开关电源。
- 信号电缆和动力电缆分开走线槽,实在要交叉就垂直交叉,别做长距离平行走线。
2.4 数字量与脉冲信号处理
转速传感器这类脉冲信号,要进高速计数通道。普通数字量输入模块扫描周期可能只有几十毫秒,频率高了根本数不对。我踩过一个坑:现场转盘转速测量用的是每圈2个脉冲的霍尔传感器,在转速只有60rpm的时候也就是每秒2个脉冲,普通通道勉强能读。可一旦转速提到120rpm,每秒4个脉冲也还行。真正出问题的是大钩下落,速度快的时候脉冲频率会飙到几百赫兹,这时候普通通道丢脉冲丢得厉害。
openrig的采集配置里可以声明某个通道是高速计数模式,硬件层面走单独的计数器引脚。接线时还要注意加个下拉电阻,不然在传感器不输出的状态下,引脚悬空会因为干扰乱跳,导致转速非零。
3. 软件栈与数据链路搭建详解
3.1 边缘网关的操作系统与运行时
openrig边缘端跑在Debian 11上,装了Docker。用Docker不是为了炫技,而是让部署可以重复、可回滚。现场改坏了系统,直接重新拉容器镜像比手动排障快得多。
Docker镜像按功能拆了几个容器:
- 采集容器:负责读Modbus、串口、数字量模块,把数据推给内部MQTT。
- 规则引擎容器:做数据清洗、换算、非法值剔除,也负责本地缓存。
- 对云端关系容器:管理MQTT连接、断线重连、安全认证。
Debian装好后,系统层面只做两件事:设静态IP、开SSH。其余一切跑Docker。系统盘剩余空间给Docker的数据卷挂载,防止日志把盘撑满。
3.2 Modbus RTU和TCP的接入配置
现场设备最常见的通信协议是Modbus RTU。openrig配置里要指定:
- 串口号、波特率、数据位、校验位、停止位。
- 设备地址(站号)。
- 寄存器起始地址和长度。
- 数据类型:16位无符号、32位浮点、32位整型、字序大小端。
举例:泥浆泵压力变送器挂在站号1,地址30001,32位浮点,小端模式。配置文件里写成:
devices: - name: mudpump_pressure protocol: modbus_rtu port: /dev/ttyS0 baudrate: 9600 databits: 8 parity: none stopbits: 1 unit_id: 1 registers: - name: pump_pressure address: 0 type: float32 endian: little scale: 0.001 unit: MPa坑点主要在寄存器的地址映射上。有的设备说明书写的寄存器地址是30001,实际访问时要从0开始偏移,即访问地址0。有的设备是32位浮点低字节在前,有的是高字节在前,读出来数据完全不对。调试方法很简单,先用Modbus Poll这类工具读一遍,确认数值和预期一致再写配置。
3.3 数据怎么到数据库
边缘采集的数据先发到本地MQTT,规则引擎消费后换算好,再推给服务端的MQTT。服务端从MQTT消费写入时序数据库。我们用的是TDengine,原因是在同等数据量下查询性能好,而且SQL在线,甲方的信息化同事接手时上手快。
数据链路里的关键参数是数据入库的频率。钻井现场大部分参数变化不快,每秒一条足够。高速计数通道可以单独加倍率到每秒5条,但没必要全通道高频。时序数据库按天算数据量,一个井队一百个点位,5秒一条,一天就是一百七十万行,存储上完全没压力,但如果全点位1秒一条,单日就是一千万行,查询变慢且磁盘无谓消耗。
3.4 断线续传与本地缓存
现场网络总会断,openrig边缘端的规则引擎容器里内置了一个本地SQLite缓存,没连上服务端时数据先落本机,网络恢复后按时间戳批量补发。
这里有个经验:补发时一定要按原始时间戳入库,不能用补发时刻的时间。
如果用了不合理的本地时间覆盖远端时间,看趋势图时会看到一条条的断崖,因为断网期间的数据全部堆积在恢复的时刻。配置了原始时间戳之后,断网和恢复是自然衔接的,历史趋势曲线看不出断痕。
缓存阈值也要设。老项目里出现过断网一个月缓存文件撑爆磁盘的案例。合理的做法是按时间或条数限制,比如最多缓存7天数据,超了就丢弃最老的数据。后续有需要可以加回补接口,单独去现场拷贝。
4. 从零搭建一套openrig的完整实操
4.1 硬件准备清单
一台工控机(或树莓派4B/8G),四个隔离串口(如没有就加USB转串口模块),一个八通道4-20mA采集模块,一个四通道高速计数模块,一个24V开关电源,若干工业级网线、信号线、端子排。预算充足的话加一个工业交换机,把网关、采集模块、工程师电脑隔离在一个局域网里。
4.2 网关系统安装
把Debian 11写入固态硬盘或TF卡。工控机默认U盘启动,配置好静态IP后安装Docker:
apt update && apt install -y ca-certificates curl gnupg install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg chmod a+r /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null apt update && apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin装完验证docker version能正常输出版本号。
4.3 编排docker-compose
在/opt/openrig下写docker-compose.yml。一个实用的小型编排:
version: "3.8" services: mqtt: image: eclipse-mosquitto:2 container_name: openrig-mqtt ports: - "1883:1883" volumes: - ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf restart: unless-stopped collector: image: openrig/collector:latest container_name: openrig-collector devices: - /dev/ttyS0:/dev/ttyS0 - /dev/ttyUSB0:/dev/ttyUSB0 volumes: - ./config:/openrig/config depends_on: - mqtt restart: unless-stopped rule_engine: image: openrig/rule-engine:latest container_name: openrig-rule-engine volumes: - ./rules:/openrig/rules - ./cache:/var/lib/openrig/cache depends_on: - mqtt restart: unless-stopped uploader: image: openrig/uploader:latest container_name: openrig-uploader environment: - CLOUD_MQTT_HOST=your-server-ip - CLOUD_MQTT_TOPIC=wellsite/001/data volumes: - ./cache:/var/lib/openrig/cache depends_on: - mqtt restart: unless-stopped注意要把宿主机串口设备映射进采集容器,不映射容器内部读不到串口。
4.4 配置点位文件和规则引擎
点位配置文件config/devices.yaml中,每个点位都需写明信号源、数据类型、量程和单位转换。举一个实际的例子:
points: # 泵压,4-20mA,量程0-40MPa。电流4mA对应0MPa,20mA对应40MPa - name: pump_pressure module: ai1 channel: 0 signal: 4_20ma raw_low: 4 raw_high: 20 eng_low: 0 eng_high: 40 unit: MPa filter: median window: 5换算逻辑是线性比例:当前工程值 = (当前电流 - raw_low)/(raw_high - raw_low) * (eng_high - eng_low) + eng_low。规则引擎会定期拉一次该通道电流,算完把结果存成float。
这个例子中我开了中值滤波,窗口5。意思是每来5个原始样值,取中位数作为输出。它能有效滤掉高幅值毛刺,但对真实值的响应会慢一拍。实时变化极快的参数,用滑动平均更合适,也可以不滤波直接采。
4.5 接入看板并配置第一块实时视图
服务端装好TDengine后,在openrig-web中配置数据源连接,选择井队和设备,然后拖拽图表组件。我通常会先放三块内容:
- 实时数字表:泵压、立压、转速、大钩高度、泥浆池液位。
- 历史趋势:任意选两个点位拉24小时曲线。
- 告警列表:显示最近触发的报警,方便倒查原因。
看板里最容易忽略的是单位。现场习惯用兆帕、转/分钟、吨。数据库中虽然存的是统一换算后的值,但展示时还是要按现场习惯格式化。所以在点位配置里把unit字段写好,看板组件读取这个字段生成单位标签和刻度。
5. 现场实测的调参心得与避坑记录
5.1 采样频率和滤波的平衡
采样过快会带来大量无用数据和CPU开销,采样过慢则抓不住快速变化。钻井场景下,泵压突变可能就在一两秒内,建议采集周期1秒起步。泥浆液位这种大惯性参数,5秒一次足矣。转速信号高速计数不受扫描周期限制,它是事件触发计数的,只要硬件引脚支持就行。
滤波参数也讲究。用中值滤波窗口过大会把真实峰值拍平。井涌井漏监测里,液位和压力的预警本来就靠快速突变,过度滤波会产生假阴性。这里的建议是告警用的判据全部取原始值或轻滤波值,看板展示的曲线才用重滤波值。
5.2 单位换算和量程校准是重灾区
4-20mA传感器的实际零点和满量程会有误差。现场校准不能只看铭牌。我的做法是:先用万用表测恒流源的电流,确认变送器在零位时输出接近4mA;再测满量程输出接近20mA。如果偏差大于0.2mA,在配置里用raw_low和raw_high手动校正。
压力变送器安装位置高度不同,也可能引入静压偏差。比如泵压变送器装在泵出口高两米的地方,仪表就会读到约0.02MPa的静压。这不是故障,是安装位差。配置里用一个补偿值offset减掉即可,别去仪器上调零,现场调零容易越调越乱。
5.3 告警阈值设置与误报抑制
告警规则在规则引擎里配置。关键是避免同一个参数频繁触发和恢复,形成告警风暴。方法有两个:
- 迟滞区间:比如泵压上限设35MPa,恢复阈值设32MPa。完整规则就是:触发条件大于35MPa,清除条件小于32MPa。这样参数在33到35之间晃就不会反复告警。
- 持续时间确认:连续三秒都超阈值才真正报警。现场瞬时抖动经常只有一两秒,用持续时间能滤掉。
我见过最离谱的误报是泥浆泵压力传感器线缆松动,接触电阻时大时小,一小时内报了四十多条。后来排查发现是接线端子没有压紧,拧紧后问题彻底消失。设备侧的物理连接稳定性永远比软件滤波可靠。
5.4 断电恢复和程序自愈配置
井场供电不稳定是常态。openrig的容器要设restart: unless-stopped,主机又要配置开机自启动Docker服务。整体策略很简单:工控机一上电,Docker自动起来,容器自动拉起,应用序列自动挂载串口。
不过有一个易错的点:部分USB转串口模块上电后设备名会变化,插错口或系统枚举顺序变了,/dev/ttyUSB0可能变成/dev/ttyUSB1。重启后docker-compose里的设备映射就失效了。解决办法是用by-id固定设备路径。查看方式:
ls -l /dev/serial/by-id/把这个稳定路径写进compose配置:
devices: - /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A50285BI-if00-port0:/dev/ttyUSB0这样不管系统怎么枚举,映射始终是同一个物理设备。
6. 常见故障排查与问题实录
6.1 Modbus 通信超时与设备无响应
现象:采集点位上所有数据都是N/A,日志里刷Recv timeout。排查路径:先ping不通就查网线;设备TCP端口通不通用nc测试;串口就用串口调试助手发Modbus请求,看看有没有响应。
如果是多设备共一条总线,排查有几个可能性:站号冲突、波特率不一致、终端电阻缺失。Modbus RTU总线两端要并联120欧终端电阻,少一个电阻,通讯不稳定但又不是完全不通,这种最容易被忽略。
6.2 数据入库全部为0
先看规则引擎日志,确认原始值是否为0。如果原始值正常,都是换算后为0,就是量程配置错误,比如raw_high成了0。如果原始值也是0,那就去采集模块看指示灯和信号。
现场有个哭笑不得的案例:采集模块通道选择拨码开关拨错了,8个通道全部映射成了通道1。原始值永远跟泵压一致。后来逐个通道手动加信号测试才定位到。所以上电后第一件事就是通道自检:每个通道给固定电流,看界面是不是对应数值。
6.3 告警不触发或触发太频繁
先分析告警规则里的参数名是否和点位名称完全一致。规则引擎是按点位的name字段匹配的,大小写或多了空格都会导致规则永不触发。再就是“持续时间确认”过短,比如设了0秒确认,等于没设,误报自然多。
6.4 看板图表出现阶梯状跳跃
这几乎总是时间戳问题。打开数据库查原始数据,如果恢复段数据的时间戳全部重叠在一个时间点,就是断点续传时忘记用原始时间戳了。在数据库层面补数据时用insert with timestamp指定时间,通常TDengine是支持指定主键时间戳的。
一个经验速查表,直接收藏:
| 现象 | 可能原因 | 排查手段 | 处理办法 |
|---|---|---|---|
| 所有点位无数据 | 边缘网关掉线/串口未映射 | 登录网关看docker ps | 重启容器,检查设备映射 |
| 单个点位无数据 | 信号线松动/断线 | 万用表测信号电流 | 重接线,紧固端子 |
| 数值整体偏大/偏小 | 量程配置错误/hold信号偏置 | 对比万用表实际电流 | 校准raw_low和raw_high |
| 数据间歇性跳动 | 干扰/屏蔽层未接地 | 看日志毛刺、查接线 | 屏蔽层单端接地,加滤波 |
| 断网补传后曲线重叠 | 时间戳用的是入库时刻 | 查数据库最新时间戳 | 改成原始时间戳回补 |
| 告警风暴 | 阈值无迟滞/持续确认过短 | 看告警明细频率 | 设置回差和延时确认 |
| 重启后设备消失 | USB枚举顺序变化 | 查看/dev/serial/by-id | 用by-id路径映射设备 |
| 数据库磁盘膨胀 | 缓存数据过多/日志轮转未配 | 查看数据卷体积 | 限制缓存大小,配logrotate |
排查原则我总结成一句话:先查物理层,再查协议层,最后查配置层。不要一上来就怀疑软件有bug。
写在最后的一点个人体会
openrig真正让我觉得值的地方不是它某个功能多惊艳,而是它把最枯燥的设备数据链条拉通了。以前跟甲方谈信息化改造,最怕的就是“各种设备数据都能接进来”,这句话听着简单,落地全是协议适配和调试的脏活。openrig的团队把这个过程做成了配置化的,确实省了不少事。另一个体会是:这套东西在不同井队之间复制,项目周期能从两周压到三四天。新站点无非是换点位表、调整告警阈值、改MQTT主题,架构都不用动。如果你也正要搭设备数据平台,建议先从边缘侧打通一个关键参数的全链路,再逐步扩点位,这种蚕食推进比一次性铺开要稳得多。最后一个小技巧:给每台网关机器命名时用井队编号加角色后缀,比如ZJ5012-edge-01,后期对接监控平台时能省下大量确认的时间。