📈 中小企业效率提升利器

设备OEE/稼动率分析系统

设备状态采集 + OEE三要素计算(可用率×性能率×合格率)+ 停机原因自动分类 + 瓶颈设备识别 + 实时大屏看板。开源方案替代昂贵MES系统,帮你找到设备效率瓶颈,OEE提升15-25%

📡 ThingsGateway 设备状态采集
💾 TDengine 时序数据存储
📊 Grafana OEE看板与报表
🔀 Node-RED 状态判定与停机分类
🗄️ PostgreSQL 停机原因与班次配置
📊 核心指标:OEE = 可用率 × 性能率 × 合格率 ⏱️ 刷新频率:实时(<1分钟) 🏭 适用:离散制造/机加工/冲压/注塑 💰 单台改造成本:<2000元

01 为什么中小企业最需要OEE分析

没有OEE系统的中小企业,普遍存在这4个问题

🤔
不知道设备真实效率
老板以为设备8小时都在生产,实际可能只有4小时在真正干活,其余时间在待机/调机/待料
🕳️
找不到效率瓶颈
产量上不去,不知道是哪台设备慢、哪个工序卡、哪类停机最多,改善全凭感觉
📋
产量靠人工统计
每天下班班组长手写产量报表,费时费力还不准,数据滞后一天,无法实时响应
💰
MES系统太贵用不起
商业MES系统OEE模块动辄十几万,还要每年服务费,中小企业投入产出比不划算

OEE是什么?为什么它是制造业通用管理语言

OEE(Overall Equipment Effectiveness,设备综合效率)= 可用率 × 性能率 × 合格率,是国际通用的设备效率衡量指标。

  • 可用率(Availability)= 实际运行时间 / 计划生产时间 —— 反映设备有多少时间在"能生产"的状态,损失来自故障停机/换型/待料
  • 性能率(Performance)= 实际产量 / 理论产量 —— 反映设备运行时的速度是否达标,损失来自降速运行/小停机/空转
  • 合格率(Quality)= 合格数量 / 总数量 —— 反映生产的产品有多少是好的,损失来自不良品/返工

OEE的价值不在于"算出一个数字",而在于"通过三要素分解,找到效率损失到底发生在哪一环"——可用率低说明停机多,性能率低说明速度慢,合格率低说明质量差。对症下药,才能真正提升效率。

02 系统架构

五层架构:采集→判定→存储→计算→可视化,全链路开源方案

01
📡
数据采集层
ThingsGateway
从PLC/采集模块获取设备运行信号(运行/待机/故障)、产量计数、报警代码、程序号。支持Modbus/OPC UA/三菱MC/西门子S7等协议,100ms刷新频率
→
02
🔀
状态判定层
Node-RED
把原始信号转换成标准设备状态(运行/待机/故障/离线/换型/保养),自动识别停机原因(故障停机/换型/待料/质量/计划停机),记录每次状态变更的开始/结束时间和持续时长
→
03
💾
数据存储层
TDengine+PG
TDengine存高频时序数据(每秒状态/产量脉冲),PostgreSQL存结构化数据(停机事件记录/班次配置/产品参数/OEE计算结果)。冷热分离:近3个月TDengine,历史数据聚合后存PG
→
04
🧮
OEE计算层
定时任务
按班次/日/周/月自动计算OEE三要素:可用率(实际运行时间/计划生产时间)、性能率(实际产量/理论产量)、合格率(合格数/总产量)。OEE=可用率×性能率×合格率。支持按设备/产线/产品/班次多维度分析
→
05
📊
可视化层
Grafana
实时OEE大屏(当前班次OEE/三要素/设备状态分布)、历史趋势分析(OEE走势/停机原因柏拉图/瓶颈设备排行)、班次报表(自动生成Excel/PDF)、异常报警(OEE低于阈值触发钉钉/企业微信通知)
💡 架构设计要点:
  • 状态判定是核心:OEE计算最关键的不是公式,而是"设备状态判定"——什么算运行、什么算待机、什么算故障。用Node-RED做可配置状态机,不用硬编码
  • 时序+关系双数据库:高频状态数据存TDengine(时序),停机事件/班次配置/OEE结果存PostgreSQL(关系型),各取所长
  • 自动+人工双轨制:停机原因自动分类(故障代码映射)+ 人工补录(操作员选原因),前1个月强制人工补录,1个月后自动分类准确率>80%
  • 数据完整性优先:三级缓存(网关本地+PLC备份+缺失标记),OEE数据不能缺,缺了就要标出来,不能假装完整

03 核心软件选型理由

TDengine 时序数据存储

为什么选它:设备状态数据是典型时序数据(每秒一条,一年3000万条/设备),需要高写入吞吐和快速时间范围查询。TDengine是专为物联网时序数据设计的数据库,写入性能是InfluxDB的2-5倍,查询性能是通用数据库的10-100倍。自带降采样和数据保留策略,自动管理历史数据生命周期。单机就能支撑100台设备的每秒采集,2核4G服务器无压力。

对比过:对比过InfluxDB(写入性能弱,企业版收费)、MySQL(时序查询慢,数据量大了以后查询要几十秒)、MongoDB(不适合时序聚合查询)

Node-RED 状态判定与停机分类

为什么选它:OEE计算最核心的不是公式,而是"状态判定"——什么算运行、什么算待机、什么算故障,不同工厂定义不同。用硬编码写死状态判定逻辑,改一次要重新部署。Node-RED可视化拖拽配置状态机,现场工程师可以根据实际情况调整判定规则(比如有的设备待机电流是2A,有的是5A)。停机原因分类也可以配置规则(故障代码→停机原因映射表),不用改代码。

对比过:对比过硬编码C#/Python逻辑(改一次要编译部署,现场无法快速调整)、规则引擎(太重,学习成本高,小团队用不起来)

Grafana OEE看板与报表

为什么选它:OEE看板需要实时刷新、多维度下钻、历史趋势对比,Grafana是开源可视化领域最成熟的方案。支持TDengine数据源插件,直接查询时序数据。自带报警引擎(OEE低于阈值发钉钉/企业微信)。仪表盘可以导出PDF,报表可以用Data Source API自动生成Excel。社区有大量工业看板模板可以参考。比自己写Web前端开发效率高10倍。

对比过:对比过自研Web前端(开发周期长,维护成本高,图表库要自己调)、商业BI工具(Tableau/Power BI授权贵,和TDengine集成不如Grafana原生)

ThingsGateway 设备状态采集

为什么选它:中小企业设备品牌杂(三菱/西门子/汇川/欧姆龙都有),协议不统一。ThingsGateway支持100+工业协议,一个网关统一采集所有设备。支持断线缓存(网络断了数据存在本地,恢复后补传),这对OEE数据完整性至关重要——OEE计算不能缺数据,缺了就不准。支持数据预处理(在网关端就做状态判定和产量计数,减少上行数据量)。开源免费,比商业网关(如Kepware)省几万授权费。

对比过:对比过Kepware(授权费贵,按驱动套件收费,多协议和高级功能要逐级加钱)、自研采集程序(每个品牌要写一套驱动,维护成本高)、Node-RED直接采集(工业协议支持不如ThingsGateway全,断线缓存弱)

04 部署要点(关键配置)

01

OEE口径对齐与规范制定

和生产经理/老板开"口径对齐会",确认5个关键定义(计划生产时间/运行状态判定/理论节拍/合格率定义/停机原因分类),写进《OEE计算规范文档》。这是最关键的一步,口径不对,后面全白做。建议花1-2天时间,把规范文档写细,包括每个定义的具体计算方法和特殊情况处理规则

02

设备数据点表规划

每台设备需要采集的数据点:运行信号(布尔)、故障信号(布尔+故障代码)、产量脉冲(计数器)、当前程序号/产品号、报警代码。写在Excel里,PLC和采集系统共用同一份表。注意:产量脉冲要用上升沿触发计数,不能用电平状态(否则会重复计数)。故障信号要区分"故障中"和"故障已发生但已复位"两种状态

03

ThingsGateway采集部署

配置ThingsGateway连接每台设备(Modbus TCP/OPC UA/三菱MC/西门子S7),配置采集点表,设置100ms采集频率。配置断线缓存(SQLite本地存储,保留7天数据)。配置数据预处理(在网关端做脉冲计数和状态去抖,减少上行数据量)。测试:断开网络5分钟,恢复后检查数据是否完整补传

04

Node-RED状态判定与停机分类

用Node-RED实现状态机:运行/待机/故障/离线/换型/保养6种状态,状态变更持续超过10秒才确认(去抖)。停机原因自动分类:有故障代码的按映射表分类,无故障代码的根据时间段和上下文推断(午休→计划停机,换型时间段→换型)。配置人工补录接口(REST API,供工位终端/手机调用)。状态变更事件写入PostgreSQL的停机事件表

05

OEE计算引擎与数据库

TDengine建表:设备状态表(每秒一条,设备ID+状态+产量增量)、产量脉冲表。PostgreSQL建表:停机事件表(设备ID+开始时间+结束时间+持续时长+停机原因+是否人工确认)、班次配置表(班次名称+开始时间+结束时间+计划生产时间)、产品参数表(产品号+理论节拍+计数方式)、OEE结果表(设备ID+班次+日期+可用率+性能率+合格率+OEE+数据完整度)。定时任务(每15分钟)计算当前班次OEE,每天下班计算全天OEE

06

Grafana看板与报警

3个核心看板:①实时大屏(当前班次OEE大数字+三要素仪表盘+设备状态分布饼图+当前停机事件列表+今日产量趋势),挂车间65寸大屏;②历史分析(OEE趋势折线图+停机原因柏拉图+瓶颈设备排行+按产品/班次/设备多维度筛选);③班次报表(自动生成Excel,含OEE三要素+停机明细+产量统计+合格率,每天下班自动发邮件)。配置报警:OEE<60%触发钉钉/企业微信通知,设备故障停机>10分钟通知维修班组

05 踩过的坑(真实问题与解决方案)

OEE系统最容易失败的不是技术,而是"数据不被信任"和"系统没人用",这里是真实踩过的6个坑

坑 01 OEE算出来85%,老板说"不可能,我看设备明明一直在转",数据不被信任
原因: OEE计算口径和老板的直觉不一致。老板认为"设备在转=在生产",但OEE的"可用率"只算"有产品产出的时间"。设备在转但在空跑(没有进料)、或者在调机试生产,都不算有效运行时间。且计划生产时间的定义也不同——老板认为是8小时,实际要扣除午休、班前会、计划保养时间
解决: OEE上线前必须先做"口径对齐会",和生产经理/老板一起确认5个关键定义:①计划生产时间怎么算(是否扣除午休/班前会/保养);②"运行"状态怎么判定(有产量脉冲?运行信号?电流阈值?);③"性能率"的理论节拍怎么定(设备标称?历史最佳?工艺标准?);④"合格率"的不良品怎么定义(自检不合格?巡检不合格?客户退货?);⑤"停机原因"分哪几类。把定义写进《OEE计算规范文档》,所有人签字确认,然后系统按这个规范算。前2周每天人工核对1小时,确认系统计算和人工统计一致,数据才被信任
坑 02 设备状态频繁跳变(运行→待机→运行,每次只持续几秒),OEE可用率被拉低
原因: 用PLC的"运行信号"直接判定状态,但运行信号有抖动(设备短暂停顿、接触器抖动、信号干扰),导致状态频繁切换。每次切换都被记录为一次"停机事件",可用率计算时这些短暂停机都被扣掉了
解决: 加"状态去抖"逻辑:状态变更必须持续超过阈值(如10秒)才确认,低于阈值的变更忽略。用Node-RED的trigger节点或自定义函数实现:收到状态变更信号后启动定时器,10秒后状态仍未变才确认变更。同时加"最小停机时间"过滤:持续时间<30秒的停机不计入停机统计(视为运行中的短暂停顿)。关键:去抖阈值要根据设备特性调整,快速设备(如冲床,每分钟几十次)阈值设小一点(3秒),慢速设备(如注塑机,几分钟一个周期)阈值设大一点(30秒)
坑 03 产量计数不准,有时多计有时少计,性能率算出来忽高忽低
原因: 用PLC的产量脉冲信号计数,但脉冲有抖动(一个产品触发多个脉冲)、或者有漏计(产品经过传感器太快没检测到)、或者计数器在PLC断电后重置了。且不同产品的计数方式不同(有的按件数,有的按重量,有的按长度)
解决: 产量计数三重保障:①脉冲去抖(两个脉冲间隔<100ms视为同一个产品,只计一次);②双计数器校验(PLC硬件计数器+软件累加计数器,每班次对比,差异超过1%报警);③产量校准机制(每班次结束时,操作员输入实际产量,系统自动计算校准系数,后续产量自动校准)。不同产品用不同的计数配置(存在产品参数表中),换型时自动切换。关键:产量数据是OEE性能率的基础,必须有"人工校准"机制,不能完全依赖自动计数——因为传感器永远有误差
坑 04 停机原因全是"未知/其他",占了60%以上,分析不出瓶颈在哪
原因: 只靠设备报警代码自动分类停机原因,但很多停机没有报警代码(如待料、换型、质量问题、吃饭休息),系统只能归为"其他"。且报警代码到停机原因的映射表不全,新出现的报警代码没有对应原因
解决: 停机原因"自动+人工"双轨制:①自动分类(有报警代码的,按映射表自动分类;无报警代码但设备在待机状态的,根据时间段和上下文推断——如午休时间归为"计划停机",换型时间段归为"换型");②人工补录(操作员在工位终端/手机上选择当前停机原因,30秒内不选则弹出提醒);③原因自学习(系统统计人工补录的原因分布,更新自动分类规则——如发现每天下午3点左右的"未知"停机,人工都选了"待料",系统自动把这个时间段归为"待料")。关键:停机原因分类是OEE分析最有价值的输出,必须投入精力做,不能全靠自动。建议前1个月强制人工补录,1个月后自动分类准确率能到80%以上
坑 05 网络断了2小时,恢复后OEE数据缺了一段,算出来偏低
原因: 采集网关和服务器之间网络中断,数据没有上传到TDengine。恢复后没有补传机制,缺失的时间段被当作"停机"或"零产量",导致OEE计算偏低
解决: 三级数据完整性保障:①采集网关本地缓存(ThingsGateway支持SQLite本地缓存,网络断了数据存在网关本地,恢复后按时间顺序补传);②PLC端数据备份(关键数据在PLC里也存一份,如班次产量计数器,恢复后可以从PLC读取补全);③缺失数据标记(OEE计算时,如果某时间段数据缺失,不直接当停机,而是标记为"数据缺失",OEE结果标注"数据不完整,仅供参考",并触发报警通知管理员补录)。关键:追溯和OEE系统都不能"静默丢数据",缺了就要标出来,不能假装数据是完整的
坑 06 OEE看板做出来了,但车间没人看,老板也不看,系统成了摆设
原因: 看板放在了办公室,车间看不到;数据每天更新一次,不是实时的;只有OEE一个数字,没有 actionable 的信息(只知道OEE低,不知道为什么低、该怎么改);没有和绩效考核挂钩,大家不关心
解决: OEE系统要"用起来",4个关键:①看板放车间(65寸大屏挂在车间入口,实时刷新,所有人进出都能看到当前班次OEE和设备状态);②数据要实时(刷新频率<1分钟,不是每天更新一次);③输出要可行动(不只显示OEE数字,还要显示"当前最大停机原因是待料,已持续15分钟,请物流部门送料"这种具体行动建议);④和绩效挂钩(把OEE纳入班组绩效考核,OEE高的班组有奖励,大家才会关心)。关键:OEE不是"算出来就完了",而是"用起来才有价值"。系统上线后前2周,每天早会用OEE数据开10分钟,讨论昨天的停机原因和改善措施,形成习惯后系统才真正发挥作用

06 关键代码片段

OEE计算核心逻辑(Node.js定时任务示例)

// 计算某设备某班次的OEE
// OEE = 可用率 × 性能率 × 合格率
async function calculateOEE(deviceId, shiftId, date) {
    const shift = await getShiftConfig(shiftId);  // 班次配置(开始/结束时间/计划生产时间)
    
    // 1. 从PostgreSQL查询该班次内的所有状态变更事件
    const events = await pool.query(
        'SELECT * FROM downtime_events WHERE device_id=$1 AND start_time>=$2 AND end_time<=$3 ORDER BY start_time',
        [deviceId, shift.startTime, shift.endTime]
    );
    
    // 2. 计算实际运行时间(状态为"运行"的总时长,去抖后)
    let runTime = 0;  // 秒
    let downtimeByReason = {};  // 按停机原因分类
    for (const ev of events.rows) {
        const duration = (ev.end_time - ev.start_time) / 1000;
        if (ev.status === 'running') {
            runTime += duration;
        } else if (duration >= 30) {  // 最小停机时间过滤(<30秒不计)
            const reason = ev.reason || 'unknown';
            downtimeByReason[reason] = (downtimeByReason[reason] || 0) + duration;
        }
    }
    
    // 3. 可用率 = 实际运行时间 / 计划生产时间
    const availability = runTime / shift.plannedProductionTime;
    
    // 4. 从TDengine查询该班次产量(合格数+总数)
    const production = await taos.query(
        `SELECT SUM(good_count) as good, SUM(total_count) as total 
         FROM production_data 
         WHERE device_id='${deviceId}' AND ts>=${shift.startTime} AND ts<=${shift.endTime}`
    );
    const goodCount = production[0].good || 0;
    const totalCount = production[0].total || 0;
    
    // 5. 性能率 = 实际产量 / 理论产量(理论产量=运行时间×理论节拍)
    const product = await getCurrentProduct(deviceId, shift.startTime);
    const theoreticalCycle = product.theoreticalCycle;  // 秒/件
    const theoreticalOutput = runTime / theoreticalCycle;
    const performance = totalCount > 0 ? totalCount / theoreticalOutput : 0;
    
    // 6. 合格率 = 合格数 / 总数
    const quality = totalCount > 0 ? goodCount / totalCount : 0;
    
    // 7. OEE = 可用率 × 性能率 × 合格率
    const oee = availability * performance * quality;
    
    // 8. 数据完整度检查(缺失数据超过5%标记为不完整)
    const dataCompleteness = calculateDataCompleteness(deviceId, shift);
    const isComplete = dataCompleteness >= 0.95;
    
    // 9. 写入OEE结果表
    await pool.query(
        `INSERT INTO oee_results (device_id, shift_id, date, availability, performance, quality, oee, 
         run_time, good_count, total_count, downtime_by_reason, data_completeness, is_complete)
         VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13)`,
        [deviceId, shiftId, date, availability, performance, quality, oee,
         runTime, goodCount, totalCount, JSON.stringify(downtimeByReason), dataCompleteness, isComplete]
    );
    
    return { oee, availability, performance, quality, downtimeByReason, isComplete };
}

07 实际效果

15-25%
OEE提升幅度
从平均55%提升到70-80%(3个月)
30%+
停机时间减少
待料/换型/故障停机时间显著下降
<1分钟
数据实时性
车间大屏实时刷新,不是每天更新一次
>95%
状态判定准确率
去抖+人工校准后,状态判定准确
<3个月
投资回报周期
减少停机损失+提升产量,快速回本
<2000元
单台设备改造成本
开源软件0授权费,仅需采集硬件

08 相关软件与工具

需要设备OEE/稼动率分析系统?

丁丁做过多个工厂的设备监控和OEE分析项目,熟悉设备状态采集、OEE计算口径对齐、停机原因分类、Grafana看板开发。可以帮你做方案设计、设备选型、系统开发、现场调试,帮你找到设备效率瓶颈。