ERP-MES vertical slice

Как ERP-заказ проходит линию без потери владельцев данных

Этот учебный кейс показывает вертикальный срез между ERP, MES и SCADA. Odoo остаётся владельцем производственного заказа и финального подтверждения. MES добавляет admission, execution identity и outbox. Ignition выполняет SFC и остаётся источником фактов линии.

Я провёл один заказ через весь контур: оператор запускает его из Odoo, Node-RED забирает release, MES допускает один execution, а Ignition получает команду через OPC UA. Завершение возвращается обратно в ERP как проверенный результат.

Главная задача была не просто отправить команду. Важно сохранить границы ответственности: ERP не пишет теги линии, Node-RED не вычисляет производственные факты, а заказ нельзя закрыть в Odoo раньше, чем MES вернул результат.

ERP -> MES -> SFC

один заказ, execution и result
Ignition
Node-RED
PostgreSQL
JavaScript
Manufacturing Order Handoff Summary
Задача

Сначала разделить ответственность

ERP, MES и SCADA решают разные задачи. Odoo знает заказ, продукт, BoM и финальное подтверждение. MES знает, какой execution был принят и какой результат ещё нужно вернуть. Ignition знает состояние линии, SFC и runtime-теги. Node-RED связывает эти системы, но не становится владельцем производственных фактов.

Manufacturing Order Handoff Overview
Odoo — бизнес-заказ

Odoo хранит Manufacturing Order, BoM, количество, компоненты и финальное ERP-подтверждение. Он не пишет теги линии и не решает, что произошло в SFC.

MES PostgreSQL — admission и outbox

MES DB создаёт durable execution, защищает линию от второго активного заказа и хранит completion до доставки в ERP.

Ignition — факты линии

Ignition SFC выполняет Line01 runtime и записывает состояние, good/reject counters и material consumption. Эти факты не вычисляются в Node-RED.

Manufacturing Order Handoff Step
Контур заказа

Один заказ получает один execution

После Start в Odoo заказ становится queued для MES. Node-RED забирает следующий release и строит стабильный request identity. MES DB допускает только один активный execution для линии, поэтому повторный poll не превращается во второй производственный заказ.

Manufacturing Order Handoff Overview
Operator clicks Start

Заказ WH/MO/00032 переходит в In Progress. В MES-блоке видно, что он поставлен в очередь на release.

Node-RED polls Odoo

Flow 10 забирает следующий queued order из Odoo и строит canonical MES request с устойчивой identity.

MES admits one execution

MES принимает execution, проверяет, свободна ли линия, и публикует Start command только для принятого заказа.

Manufacturing Order Handoff Step
OPC UA и SFC

Команда принимается только целиком

Node-RED пишет командные поля в Ignition только после MES admission. RequestSequence записывается последним, поэтому Gateway script видит уже полный payload. Ignition проверяет заказ, execution, продукт, количество и текущее состояние линии. Только после этого SFC запускает runtime.

Manufacturing Order Handoff Overview
Write command payload

Node-RED пишет CommandId, WorkOrderId, MesExecutionId, ProductCode и TargetGoodQty в командные теги Ignition.

Commit with RequestSequence

RequestSequence пишется последним. Это граница, по которой Ignition понимает, что команда готова к проверке.

SFC owns runtime

Ignition SFC пишет STARTING, RUNNING, COMPLETED, good count, reject count и consumption facts. Node-RED только наблюдает.

Manufacturing Order Handoff Step
Completion

Результат возвращается через outbox

Ignition публикует completion после изменения CompletionSequence. MES сохраняет факты производства и создаёт запись для ERP outbox. Отдельный Node-RED flow доставляет pending result в Odoo и помечает его как delivered только после успешного ответа ERP.

Manufacturing Order Handoff Overview
Observe completion sequence

Flow 30 видит новый CompletionSequence через OPC UA и публикует production-completed event.

Record MES completion

MES DB сохраняет completion и создаёт erp_outbox row. Повторный resultId не создаёт второй ERP posting.

Deliver ERP result

Flow 40 отправляет pending outbox обратно в Odoo и помечает запись как delivered только после успешного ответа ERP.

Manufacturing Order Handoff Step
ERP confirmation

ERP закрывает заказ только после MES

Раннее подтверждение в Odoo скрыто, пока MES не вернул результат. После receipt оператор получает финальное действие Produce All. Odoo остаётся владельцем ERP posting, но уже не может закрыть заказ раньше линии.

Manufacturing Order Handoff Overview
MO 32 released to MES

WH/MO/00032 находится в In Progress: продукт PKG-A, целевое количество 10.00 и MES release в очереди.

Facts returned

В Odoo вернулись good quantity 10.00 и расход компонентов MAT-BASE-A, MAT-LABEL-A и MAT-PACK-A.

ERP remains final owner

После MES result заказ WH/MO/00032 закрыт в Odoo. MES release подтверждён в ERP, а execution ID сохранён в карточке заказа.

Что показывает кейс:

  1. ERP может управлять запуском, не обходя MES и SCADA
  2. MES admission и outbox сохраняют идемпотентность и traceability
  3. Node-RED остаётся адаптером, а не владельцем производственных фактов
  4. Ignition SFC остаётся источником runtime state и material consumption
  5. Финальный ERP posting выполняется только после подтверждённого MES result
Manufacturing Order Handoff Step

Другие проекты

Part Production Cell — MES & OEE Project

Part Production Cell — MES & OEE

OpenPLC, Ignition Perspective и SQLite: порядок в событиях, KPI и причинах простоев.

Смотреть кейс Arrow
Pump Station Simulator Project

Pump Station Simulator

OPC UA, SQLite и Ignition: от live-состояния насоса до сохранённой истории и проверки сценария.

Смотреть кейс Arrow
Tank Level Control Project

Tank Level Control

OpenPLC, Modbus TCP и Ignition: от ladder-логики до проверяемого операторского сценария.

Смотреть кейс Arrow