工位停机

Odoo 工位被 Blocked 到底意味着什么:productivity loss、停机时间与 OEE 不是三张独立报表

很多人看到工位 Blocked、productive time、OEE,会以为这是三个互不相干的制造功能。但从官方源码看,它们其实都建立在同一套 productivity time log 之上。

制造
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 6 阅读

先说结论

在 Odoo 里,工位的 Blocked、停机时间、productive time、OEE,并不是三套彼此独立的制造功能。

它们大多来自同一个底层对象:

  • mrp.workcenter.productivity

也就是工位时间日志。

一句话记:

Odoo 不是先有 OEE 报表、再有停机分析;而是先记录工位时间,再把这些时间重新解释成 blocked、productive 和 OEE。


工位为什么会变成 Blocked

关键逻辑在 addons/mrp/models/mrp_workcenter.py_compute_working_state()

源码的判断很直接:

  • 先找这个工位有没有“尚未结束”的 productivity line
  • 如果没有,工位状态是 normal
  • 如果有,而且 loss_type 属于 productiveperformance,工位被视为正在使用
  • 否则,工位被视为 blocked

这背后其实很有意思。

Odoo 不会因为你点了某个“停机按钮”就神秘变红,而是因为:

  • 系统发现当前存在一条未关闭的时间日志
  • 这条日志被归类为非 productive / performance
  • 所以它把这段时间解释为“工位被阻塞”

也就是说,Blocked 不是一个孤立状态,它是时间日志分类后的结果。


productivity loss 到底在表达什么

mrp.workcenter.productivity.loss.type 与相关模型里,Odoo把工位时间分成几种 loss type,例如:

  • productive
  • performance
  • availability
  • quality

对很多团队来说,这几个名字容易看成“报表标签”。

但在实现层面,它们其实是在决定:

  • 当前工位显示为正常使用,还是 blocked
  • 这段时间会计入 productive_time 还是 blocked_time
  • OEE 分母和分子怎么累计

所以 loss type 不是事后分析标签,而是运行时状态解释器。


blocked_time 和 productive_time 是怎么来的

在同一个 mrp_workcenter.py 文件里,Odoo 分别计算:

  • _compute_blocked_time()
  • _compute_productive_time()

两者都是去读最近一个月内已结束的 productivity lines,再按 loss_type 汇总时长。

差别在于:

blocked_time

会把 非 productive 的已结束时间都累计进去。

所以 blocked_time 在业务上更接近:

  • 停机
  • 卡住
  • 等待
  • 质量/可用性等非产出时间

productive_time

只统计 loss_type = 'productive' 的时间。

也就是说,Odoo 这里对“真正产出时间”是有一个非常收敛的定义的,不是所有工单占用时间都算 productive。


OEE 为什么不是单独填报出来的

_compute_oee() 的逻辑其实很朴素:

  • 读近一个月的工位时间日志
  • loss_type 分组求和
  • productive 的时长当分子
  • productive + blocked 的总时长当分母
  • 最后算百分比

换成大白话就是:

Odoo 的 OEE 不是另一套报表来源,而是拿同一批工位时间日志重新算出来的结果。

所以如果底层时间日志没记好,OEE 一定不可信;它不是一个能“自动修正原始数据质量”的魔法指标。


为什么很多团队觉得 OEE “不准”

原因通常不在公式,而在记录口径。

最常见的问题有:

1)没有认真维护 productivity loss 原因

如果大家随手记,或者全部都记成同一类,最终 blocked / productive 的边界就会失真。

2)时间日志没有及时关闭

源码里工位当前状态就是看有没有未结束的 line。如果日志长期不关,工位状态和统计都会漂移。

3)把 performance 当 productive 理解

Odoo 在 working_state 判断里把 performance 也当“工位正在被使用”,但在 OEE 聚合时,productive_time 只认 productive。这正是很多人直觉和系统口径不一致的地方。

也就是说:

  • 从运行状态看,performance 不是 blocked
  • 但从 OEE 的 productive_time 口径看,它又不等于真正产出时间

这就是为什么只看字段名很容易误判。


这套设计到底想解决什么问题

Odoo 并不是想把工厂复杂现实全部装进一个指标。

它在做的是一件更务实的事:

  • 先把工位的每段时间记录下来
  • 再按照 loss type 解释“这段时间意味着什么”
  • 最后得出当前状态、停机统计、产出统计和 OEE

这样设计的好处是统一。

不然你会得到三套互相打架的数据:

  • 看板上一个状态
  • 报表里另一个停机时间
  • OEE 再来第三套口径

而 Odoo 尽量让它们共用同一底座。


新手最容易误解的几个点

1)Blocked 不是工位字段手工写死的

它是未结束时间日志 + loss type 共同推导出来的。

2)productive_time 不是“所有工单占用时间”

它是被明确标记成 productive 的那部分时间。

3)OEE 不是独立录入口径

它依赖底层 productivity lines 的质量。


实战里怎么落地

如果你们想让工位状态和 OEE 真有运营价值,建议优先做三件事:

  1. 把 productivity loss 分类定义清楚,不要让车间随意理解
  2. 让开始、暂停、恢复、结束动作尽量形成稳定流程,避免时间日志悬空
  3. 出现 OEE 异常时,先查原始 productivity line,再查报表,不要反过来

这样你会发现很多“指标不准”问题,其实是记录治理问题,不是系统公式问题。


最后总结

Odoo 对工位状态和 OEE 的设计并不花哨,但很扎实:

  • 当前工位是否 blocked,看未结束时间日志怎么分类
  • 最近一个月 blocked_time / productive_time,看已结束时间日志怎么聚合
  • OEE,则是基于同一批日志继续计算出来的比率

所以真正该管理的,不是报表页面上的几个数字,而是:

工位时间到底被怎样记录、怎样分类、怎样结束。

把这个底层逻辑抓住,Blocked、停机分析和 OEE 才会真正连成一套可用的制造语言。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。