前言
MES(Manufacturing Execution System,制造执行系统)是制造业数字化转型的核心系统。本文介绍如何基于Odoo 19开发一套完整的MES系统,涵盖生产管理、设备管理、质量管理等核心模块。
一、MES系统架构
系统模块:
- 生产管理:生产计划、工单管理、在制品跟踪、报产修正
- 设备管理:设备台账、预防性维护、点检任务、维修工单
- 质量管理:来料检验、过程检验、成品检验、8D报告
- 数据采集:Node-RED + PLC,70工位,1秒刷新
二、Odoo模块开发
2.1 模块结构
mes_automotive/
├── __init__.py
├── __manifest__.py
├── models/
│ ├── __init__.py
│ ├── mes_production.py # 生产管理
│ ├── mes_equipment.py # 设备管理
│ ├── mes_quality.py # 质量管理
│ └── mes_traceability.py # 追溯管理
├── views/
│ ├── mes_production_views.xml
│ ├── mes_equipment_views.xml
│ ├── mes_quality_views.xml
│ └── mes_views_menus.xml
├── security/
│ └── ir.model.access.csv
└── data/
└── mes_data.xml
2.2 生产计划模型
# models/mes_production.py
from odoo import models, fields, api
from datetime import datetime, timedelta
class MesProductionPlan(models.Model):
_name = 'mes.production.plan'
_description = '生产计划'
_order = 'date_start desc'
name = fields.Char(string='计划编号', required=True, copy=False, default='New')
product_id = fields.Many2one('product.product', string='产品', required=True)
quantity = fields.Float(string='计划数量', required=True)
date_start = fields.Date(string='开始日期', required=True)
date_end = fields.Date(string='结束日期', required=True)
state = fields.Selection([
('draft', '草稿'),
('scheduled', '预排'),
('released', '下发'),
('in_progress', '进行中'),
('done', '已完成'),
('cancel', '已作废')
], string='状态', default='draft')
workcenter_id = fields.Many2one('mrp.workcenter', string='工作中心')
workorder_ids = fields.One2many('mes.production.workorder', 'plan_id', string='工单')
workorder_count = fields.Integer(string='工单数', compute='_compute_workorder_count')
@api.depends('workorder_ids')
def _compute_workorder_count(self):
for record in self:
record.workorder_count = len(record.workorder_ids)
def action_release(self):
"""下发生产计划,自动生成工单"""
self.ensure_one()
if self.state != 'scheduled':
raise UserError('只能下发预排状态的计划')
# 自动生成工单
self._create_workorders()
self.state = 'released'
def _create_workorders(self):
"""根据BOM自动生成工单"""
bom = self.env['mrp.bom']._bom_find(product=self.product_id)
if bom:
for line in bom.bom_line_ids:
self.env['mes.production.workorder'].create({
'plan_id': self.id,
'product_id': line.product_id.id,
'quantity': self.quantity * line.product_qty,
'workcenter_id': self.workcenter_id.id,
})
class MesProductionWorkorder(models.Model):
_name = 'mes.production.workorder'
_description = '生产工单'
name = fields.Char(string='工单号', required=True, copy=False, default='New')
plan_id = fields.Many2one('mes.production.plan', string='生产计划', required=True)
product_id = fields.Many2one('product.product', string='产品', required=True)
quantity = fields.Float(string='数量', required=True)
workcenter_id = fields.Many2one('mrp.workcenter', string='工作中心')
state = fields.Selection([
('draft', '待下发'),
('in_progress', '进行中'),
('done', '已完成'),
('cancel', '已取消')
], string='状态', default='draft')
# 扫码上料
material_loading_ids = fields.One2many('mes.material.loading', 'workorder_id', string='上料记录')
# 异常工单
exception_ids = fields.One2many('mes.exception.workorder', 'workorder_id', string='异常记录')
2.3 设备管理模型
# models/mes_equipment.py
class MesEquipment(models.Model):
_name = 'mes.equipment'
_description = '设备'
name = fields.Char(string='设备名称', required=True)
code = fields.Char(string='设备编号', required=True)
equipment_type = fields.Selection([
('cnc', '数控机床'),
('robot', '机器人'),
('conveyor', '输送线'),
('agv', 'AGV'),
('other', '其他')
], string='设备类型')
workcenter_id = fields.Many2one('mrp.workcenter', string='所属工作中心')
state = fields.Selection([
('normal', '正常'),
('maintenance', '维护中'),
('fault', '故障'),
('standby', '待机')
], string='状态', default='normal')
# 预防性维护
pm_plan_ids = fields.One2many('mes.pm.plan', 'equipment_id', string='预修计划')
# 点检记录
inspection_ids = fields.One2many('mes.equipment.inspection', 'equipment_id', string='点检记录')
# 运行时间
runtime_hours = fields.Float(string='运行小时数')
2.4 质量管理模型
# models/mes_quality.py
class MesQualityInspection(models.Model):
_name = 'mes.quality.inspection'
_description = '质量检验'
name = fields.Char(string='检验单号', required=True)
inspection_type = fields.Selection([
('incoming', '来料检验'),
('process', '过程检验'),
('final', '成品检验')
], string='检验类型', required=True)
product_id = fields.Many2one('product.product', string='产品')
quantity = fields.Float(string='检验数量')
qualified_qty = fields.Float(string='合格数量')
unqualified_qty = fields.Float(string='不合格数量')
state = fields.Selection([
('draft', '待检'),
('inspecting', '检验中'),
('passed', '合格'),
('failed', '不合格')
], string='状态', default='draft')
# 8D报告
report_8d_ids = fields.One2many('mes.quality.8d.report', 'inspection_id', string='8D报告')
三、8D报告工作流
8D报告是质量管理的核心流程:
- D1:组建团队 - 确定问题解决团队成员
- D2:问题描述 - 详细描述问题现象
- D3:临时措施 - 制定并执行临时解决方案
- D4:根本原因 - 分析问题根本原因
- D5:纠正措施 - 制定并验证永久解决方案
- D6:预防再发 - 实施预防措施
- D7:表彰团队 - 认可团队贡献
- D8:关闭报告 - 总结经验教训
四、数据采集集成
使用Node-RED连接PLC,实现70个工位的实时数据采集:
// Node-RED数据流示例
// 1. Modbus TCP读取PLC数据
// 2. 数据清洗和转换
// 3. 通过MQTT发送到MES系统
// 4. 断点续传机制
// MQTT消息格式
{
"equipment_id": "CNC-001",
"timestamp": "2026-06-18T10:30:00Z",
"metrics": {
"spindle_speed": 3000,
"feed_rate": 200,
"temperature": 45.2,
"vibration": 0.02
}
}
五、部署方案
生产环境部署:
- PostgreSQL一主多从,读写分离
- Nginx反向代理 + SSL证书
- Redis缓存热点数据
- Node-RED数据采集服务
- 数据保存3年+,支持分库分表
总结
基于Odoo开发MES系统,可以快速构建制造业数字化解决方案。本文介绍了核心模块的设计和实现,如果需要专业的MES系统开发服务,欢迎联系17老师。
关于17老师:AI应用·数字化管理·全栈开发·网络安全全栈专家。联系邮箱:j.d88888888@qq.com,微信:AFIST17