
Part Production Cell — MES & OEE
OpenPLC, Ignition Perspective и SQLite: порядок в событиях, KPI и причинах простоев.
Этот учебный кейс показывает вертикальный срез между 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 и SCADA решают разные задачи. Odoo знает заказ, продукт, BoM и финальное подтверждение. MES знает, какой execution был принят и какой результат ещё нужно вернуть. Ignition знает состояние линии, SFC и runtime-теги. Node-RED связывает эти системы, но не становится владельцем производственных фактов.
Odoo хранит Manufacturing Order, BoM, количество, компоненты и финальное ERP-подтверждение. Он не пишет теги линии и не решает, что произошло в SFC.
MES DB создаёт durable execution, защищает линию от второго активного заказа и хранит completion до доставки в ERP.
Ignition SFC выполняет Line01 runtime и записывает состояние, good/reject counters и material consumption. Эти факты не вычисляются в Node-RED.
После Start в Odoo заказ становится queued для MES. Node-RED забирает следующий release и строит стабильный request identity. MES DB допускает только один активный execution для линии, поэтому повторный poll не превращается во второй производственный заказ.
Заказ WH/MO/00032 переходит в In Progress. В MES-блоке видно, что он поставлен в очередь на release.
Flow 10 забирает следующий queued order из Odoo и строит canonical MES request с устойчивой identity.
MES принимает execution, проверяет, свободна ли линия, и публикует Start command только для принятого заказа.
Node-RED пишет командные поля в Ignition только после MES admission. RequestSequence записывается последним, поэтому Gateway script видит уже полный payload. Ignition проверяет заказ, execution, продукт, количество и текущее состояние линии. Только после этого SFC запускает runtime.
Node-RED пишет CommandId, WorkOrderId, MesExecutionId, ProductCode и TargetGoodQty в командные теги Ignition.
RequestSequence пишется последним. Это граница, по которой Ignition понимает, что команда готова к проверке.
Ignition SFC пишет STARTING, RUNNING, COMPLETED, good count, reject count и consumption facts. Node-RED только наблюдает.
cmdPaths = [
"[default]Line01/Cmd/Start/CommandId",
"[default]Line01/Cmd/Start/WorkOrderId",
"[default]Line01/Cmd/Start/MesExecutionId",
"[default]Line01/Cmd/Start/ProductCode",
"[default]Line01/Cmd/Start/TargetGoodQty",
]
values = system.tag.readBlocking(cmdPaths)
# RequestSequence is the commit boundary.
# When it changes, the full command payload is already written.
if requestSequence <= previousAckSequence:
return
chartInstanceId = system.sfc.startChart(
"Line01_DemoExecution",
chartParameters,
)
Ignition публикует completion после изменения CompletionSequence. MES сохраняет факты производства и создаёт запись для ERP outbox. Отдельный Node-RED flow доставляет pending result в Odoo и помечает его как delivered только после успешного ответа ERP.
Flow 30 видит новый CompletionSequence через OPC UA и публикует production-completed event.
MES DB сохраняет completion и создаёт erp_outbox row. Повторный resultId не создаёт второй ERP posting.
Flow 40 отправляет pending outbox обратно в Odoo и помечает запись как delivered только после успешного ответа ERP.
Раннее подтверждение в Odoo скрыто, пока MES не вернул результат. После receipt оператор получает финальное действие Produce All. Odoo остаётся владельцем ERP posting, но уже не может закрыть заказ раньше линии.
WH/MO/00032 находится в In Progress: продукт PKG-A, целевое количество 10.00 и MES release в очереди.
В Odoo вернулись good quantity 10.00 и расход компонентов MAT-BASE-A, MAT-LABEL-A и MAT-PACK-A.
После MES result заказ WH/MO/00032 закрыт в Odoo. MES release подтверждён в ERP, а execution ID сохранён в карточке заказа.
Что показывает кейс:

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

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

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