首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >振动温度入库:采集频率与数据清洗

振动温度入库:采集频率与数据清洗

原创
作者头像
节点恒存
发布于 2026-10-20 10:55:18
发布于 2026-10-20 10:55:18
30
举报

给设备加装振动和温度传感器,头一年我们踩的坑几乎全在数据侧:采得太密存不下,采得太稀看不出问题,存进去的数还夹着毛刺、死值、乱序和断点。后来把采集频率按物理量分开定,入库前加了一道清洗管道,才把这件事稳定下来。结论先放这里:振动和温度是两种节奏的数据,频率不该统一;清洗不是可选项,它的作用是把"能看"变成"能算"。

一、采集频率定错,后面全错

1.1 两种物理量,两种节奏

温度变化慢,一分钟一个点完全够用,一天下来一台设备一千四百多个点。振动不一样,轴承的早期故障特征在几百赫兹到几千赫兹的频段,采样率低于两千赫兹基本看不出来,一秒一个点只是底线要求。按统一频率采集,要么振动不够密、要么温度冗余十倍,两头都不合适。所以从网关侧就把两路数据分开配置。

1.2 存储量与查询成本的账

按一秒一个点算,一台设备的振动数据一天八万六千四百条,十台设备一年三百多万条,再加上温度,表很快就上亿。这个量级下,不分区、不降采样,任何趋势查询都会超时。我们定下的策略是:原始高频数据只保留三十天,用于故障回溯;超过三十天的按分钟聚合存一份,聚合值包括均值、峰值、峰峰值。这样历史查询始终在千万行以内。

1.3 频率选择的判断依据

三个依据,按优先级排。设备的关键程度:关键设备采得密,辅助设备放宽。故障特征频段:滚动轴承看高频,齿轮看啮合频率,只看温升趋势的场合低频就够。分析目的:只做趋势预警,一分钟一个点足够;要做频谱诊断,采样率必须够。把这三点写在配置表里,不要靠口头约定,新加设备照表配,就不会各自发挥。

二、入库前的四道清洗

2.1 时间戳对齐与去重

网关补传是常见的乱序来源:断网期间数据在本地缓存,恢复后一次性上传,时间戳是旧的,到达顺序是新的。入库前统一按时间戳排序,同一设备同一时间戳出现多条时保留后到的一条。这一步必须在写入前做,写完再改的成本高得多。

2.2 毛刺剔除

传感器偶发跳变很常见,比如线路干扰导致某个点突然跳到量程上限。用一个滑动窗口中位数替换明显离群的点:窗口取相邻九个点,当前点偏离中位数超过窗口标准差的三倍就判为毛刺,用中位数替代并打标记。注意是打标记而不是删除,原始值留在旁路表里,事后排查还需要它。

2.3 死值与缓慢漂移

死值指连续多个采样点完全相同,通常是传感器卡死或通讯缓存重复发送。规则是连续二十个点数值不变即判为死值,后续点标记为无效,不再参与统计。缓慢漂移更难发现:传感器半年内零点偏移了几个单位,趋势图上看不出来,但同比对比会失真。做法是每季度做一次停机校准,校准前后各留一段对照数据。

2.4 缺数与补点策略

断点不能靠插值硬补。我们的处理是把缺口标出来:连续缺失超过五个采样点的区间记为一个断点事件,写入断点表;统计时按实际有效点数算均值,不把断点当零。这样设备效率类指标不会被断点稀释,也避免出现"信号正常"的假象。

三、清洗管道的实现

3.1 一条流式清洗函数

清洗逻辑做成纯函数,输入一批采样点,输出清洗后的点和标记,便于单元测试,也便于换语言重写:

代码语言:javascript
复制
// 输入:[{ts, value}],按 ts 升序
function cleanSeries(points, opt = {}) {
  const win = opt.window || 9;          // 滑动窗口
  const zLimit = opt.zLimit || 3;       // 离群倍数
  const flatRun = opt.flatRun || 20;    // 死值连续长度
  const out = [];
  let same = 1;

  for (let i = 0; i < points.length; i++) {
    const p = points[i];
    const s = Math.max(0, i - Math.floor(win / 2));
    const e = Math.min(points.length, i + Math.ceil(win / 2));
    const arr = points.slice(s, e).map(x => x.value).sort((a, b) => a - b);
    const median = arr[Math.floor(arr.length / 2)];
    const sd = stddev(arr) || 1e-6;

    same = (i > 0 && p.value === points[i - 1].value) ? same + 1 : 1;
    let flag = 'ok';
    let value = p.value;

    if (same >= flatRun) {
      flag = 'stuck';                       // 死值
    } else if (Math.abs(p.value - median) > zLimit * sd) {
      flag = 'spike';                       // 毛刺,用中位数替代
      value = median;
    }
    out.push({ ts: p.ts, value, raw: p.value, flag });
  }
  return out;
}

这段的关键是"替代但保留原值"。直接删除毛刺点会让时间序列出现空洞,下游聚合要处理两种缺口;保留 raw 字段,则既能让趋势干净,又能回溯原始信号。死值标记为 stuck 之后,聚合时按无效点处理,不算进均值,也不算进有效点数。

3.2 降采样与聚合入库

清洗完的数据不直接全量入库。按设备、按分钟做一次聚合:均值、峰值、峰峰值、有效点数、异常点计数五个指标写进分钟表。原始点只在标记为异常时单独写入事件表。这样分钟表一天一台设备一千四百多行,查询秒回;异常事件表数据量小,专门用于报警回溯。调度这块我放在搭贝的定时任务里跑,配置简单,出错能看到日志,不需要专门维护一台服务器。

3.3 阈值判断要放在清洗前

有个细节差点出事故:早期报警是基于清洗后的数据判的,结果一次真实的剧烈振动被中位数滤波抹平,报警没触发。之后把规则改清楚:超限报警一律用原始值判断,清洗只服务于趋势和统计。这个顺序反了,等于用滤镜做安全监测。

四、现场才发现的问题

4.1 网关闭环补传把表写乱

有段时间趋势图出现"回勾",曲线走到一半又倒回去。原因是网关补传,旧时间戳的数据写在了新数据后面。解法是写入前做一次排序合并,并且给入库接口加幂等键:设备号加时间戳,重复的直接忽略。幂等键这个设计后来救过好几次,网关重发、脚本重跑都不会产生重复行。

4.2 时钟不同步导致对不齐

不同网关的时钟差了几十秒,同一时刻的振动和温度对不上,做相关性分析时结论完全相反。之后所有网关统一走时间同步服务,误差控制在两百毫秒以内,入库时再记录一个上报时间,两个时间都留着,排查时能看出是采集延迟还是时钟偏差。

4.3 传感器装错位置

数据清洗得再干净,也救不了装错位置。有一台减速机的振动传感器贴在薄板护罩上,测到的全是护罩共振,数值比同类设备高两倍,天天误报。这类问题只能靠现场巡检发现,之后我们把安装位置画进点位图,新装必须按图验收。

五、跑了一年之后

十台关键设备稳定运行一年,数据可用率在九成七以上,原来那种"信号正常但设备坏了"的情况没有再出现。直接的收益是故障回溯:轴承故障前两周,分钟表的峰值指标已经连续上升,只是当时没有设这条规则。现在这类趋势被做成固定看板,设备管理从"坏了再修"往前挪了一步。回头看,真正花时间的不是写清洗代码,而是把每个规则的口径和现场对齐:什么样的跳变算干扰、断多久算断点、死值连续多少个才算卡死,这些数值定下来之后,代码只是照着执行。

六、总结

这类数据工程的要点,可以收成四句话:频率跟着物理量走,别一刀切;原始数据短期保留,长期只留聚合;清洗要打标记不要删点,超限判断要用原始值;写入必须幂等,时间必须同步。四条都不难,难的是把它们写进配置和流程里,而不是留在某个人的经验里。

常见问题

问:采样率到底该多高,有没有可执行的判断方法?

答:按要分析的特征频率倒推。想做轴承早期故障,采样率至少覆盖特征频段的五倍以上,常用两千到五千赫兹;只看温升和整机振动趋势,一百赫兹以内足够。拿不准时先按高采样率试采两周,做一次频谱看能量集中在哪个频段,再往下调,比凭经验拍一个数稳妥。

问:分钟聚合之后,还能做故障诊断吗?

答:分钟聚合适合趋势预警和统计,不适合频谱诊断。诊断需要连续的原始波形,所以原始高频数据要保留一段窗口期,常用三十天,故障回溯时从窗口里取。两级并存的成本可控:原始数据按分区滚动删除,聚合数据长期保留。

问:断点很多,是补数还是留空?

答:留空并记录断点事件,不要插值。插值会让数据看起来连续,但会把断点期间的真实状态掩盖掉,统计也失真。如果业务上必须连续序列,可以做插值但必须单独标记为推算值,并且在报表上明确区分实测和推算。

问:清洗规则会不会把真实异常洗掉?

答:会,所以规则要分场景。趋势统计用清洗后的数据,安全报警用原始数据加独立阈值;清洗规则里的窗口和倍数不要设得太激进,窗口越大越容易抹平短时冲击;上线前拿历史故障数据回放一遍,看清洗后还能不能识别出已知的异常段,这是必要的一步。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、采集频率定错,后面全错
    • 1.1 两种物理量,两种节奏
    • 1.2 存储量与查询成本的账
    • 1.3 频率选择的判断依据
  • 二、入库前的四道清洗
    • 2.1 时间戳对齐与去重
    • 2.2 毛刺剔除
    • 2.3 死值与缓慢漂移
    • 2.4 缺数与补点策略
  • 三、清洗管道的实现
    • 3.1 一条流式清洗函数
    • 3.2 降采样与聚合入库
    • 3.3 阈值判断要放在清洗前
  • 四、现场才发现的问题
    • 4.1 网关闭环补传把表写乱
    • 4.2 时钟不同步导致对不齐
    • 4.3 传感器装错位置
  • 五、跑了一年之后
  • 六、总结
  • 常见问题
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档