Smart Manufacturing

MES MQTT Integration: Event-Driven Orders, Counts and Quality

Replace brittle point-to-point MES interfaces with an event-driven MQTT namespace. Learn the topic layout, payload contracts and a working adapter for orders, counts and quality results.

MES MQTT integration diagram with machines, an MQTT broker and a manufacturing execution system exchanging work orders and counts
Run this on your own MQTT brokerGet a private, managed MQTT broker on the Free plan and start from ready-made code samples.
Try it free Code samples No card required

MES MQTT integration replaces the tangle of custom interfaces between a manufacturing execution system and the shop floor with one event-driven namespace. This guide shows how to structure topics for work orders, production counts and quality results, what the payloads should contain and how to write a small adapter that connects an MES to an MQTT broker.

Why MES Integration Is Usually the Hardest Part

A manufacturing execution system tracks what is being produced, on which equipment, by whom and with what result. To do that it needs data from machines and must send instructions back. Traditionally this happens through point-to-point links: an OPC connection here, a database table polled every minute there, a CSV file dropped on a share by a line PLC.

Each link works in isolation, but together they create problems that every plant engineer recognizes:

  • Adding a second consumer (an OEE dashboard, a maintenance system) means building another interface to the same machine.
  • Polling introduces delay and load; a count is only as fresh as the last query.
  • When the MES is upgraded or replaced, every interface breaks at once.
  • Nobody has a single place to see what data actually flows.

An event-driven approach turns this around. Machines and gateways publish what happens as it happens. The MES subscribes to the events it needs and publishes its own decisions, such as a released work order. Other systems subscribe to the same events without touching the MES. If you are unsure where the MES sits relative to ERP and SCADA, read MES vs ERP vs SCADA first.

How MES MQTT Integration Works

The central piece is an MQTT broker that every participant connects to as a client. Nobody connects directly to anybody else. Three flows cover most MES needs:

Flow Direction Example topic Typical QoS
Work order dispatch MES to line acme/plant1/assembly/line2/mes/order/current 1, retained
Production counts Machine to MES acme/plant1/assembly/line2/cell3/count 1
Machine state Machine to MES acme/plant1/assembly/line2/cell3/state 1, retained
Quality results Test station to MES acme/plant1/assembly/line2/qc1/result 1
Order acknowledgement Line to MES acme/plant1/assembly/line2/mes/order/ack 1

The topic path follows the ISA-95 equipment hierarchy (enterprise, site, area, line, cell), which is the backbone of a Unified Namespace. The details of that naming are covered in how to build a Unified Namespace.

Two MQTT features matter especially for MES traffic:

  • Retained messages. The current work order and the current machine state are retained, so an HMI that reboots instantly knows what to build without asking the MES.
  • QoS 1. Counts and quality results must not be lost, so they are published with at-least-once delivery. The MES must therefore handle duplicates, usually by keeping a sequence number per publisher.

Payload Contracts That Survive Change

Topics tell you where an event came from; payloads tell you what happened. Agree on a contract per event type and version it. A count event that an MES can trust looks like this:

{
  "schema": "count/v1",
  "ts": "2026-10-16T08:42:13.512Z",
  "seq": 18233,
  "orderId": "WO-2026-04417",
  "material": "HSG-220-B",
  "good": 1,
  "scrap": 0,
  "source": "cell3-plc"
}

A few rules keep these contracts robust:

  1. Send increments or totals, not both. Increments with a sequence number are easy to deduplicate; totals are easy to recover after a gap. Pick one per signal and document it.
  2. Carry the order ID. The line already knows the active order from the retained order topic, so stamping it on each event saves the MES a lookup and avoids misattributed counts at order changeover.
  3. Timestamp at the source in UTC with milliseconds.
  4. Include a schema field so consumers can handle count/v2 without breaking.

A Working MES Adapter in Python

Most MES products expose a REST API or a database interface rather than MQTT. A small adapter bridges the two: it subscribes to shop floor events and calls the MES, and it publishes MES decisions back to the namespace. The example below uses paho-mqtt 2.x and a placeholder post_to_mes function you replace with your MES API call.

import json
import uuid

import paho.mqtt.client as mqtt

LINE = "connectmq/demo/mes-5c21/line2"   # use the full ISA-95 path in production
last_seq = {}

def post_to_mes(kind, event):
    # Replace with a call to your MES API, e.g. requests.post(...)
    print(f"MES <- {kind}: {event}")

def release_order(client, order_id, material, quantity):
    order = {"schema": "order/v1", "orderId": order_id,
             "material": material, "quantity": quantity, "status": "RELEASED"}
    client.publish(f"{LINE}/mes/order/current", json.dumps(order), qos=1, retain=True)

def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    client.subscribe(f"{LINE}/+/count", qos=1)
    client.subscribe(f"{LINE}/+/state", qos=1)
    client.subscribe(f"{LINE}/+/result", qos=1)
    client.subscribe(f"{LINE}/mes/order/ack", qos=1)
    release_order(client, "WO-2026-04417", "HSG-220-B", 500)

def on_message(client, userdata, msg):
    event = json.loads(msg.payload)
    kind = msg.topic.rsplit("/", 1)[-1]
    source = msg.topic.split("/")[-2]
    seq = event.get("seq")
    if seq is not None:
        key = (source, kind)
        if seq <= last_seq.get(key, -1):
            return  # duplicate from a QoS 1 redelivery
        last_seq[key] = seq
    post_to_mes(kind, {"source": source, **event})

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id=f"mes-adapter-{uuid.uuid4().hex[:8]}")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=30)
client.loop_forever()

Test it against the public MQTT test broker by publishing a count from the command line:

mosquitto_pub -h broker.connectmq.com -p 1883 -i cell3-test-5c21 -q 1 \
  -t "connectmq/demo/mes-5c21/line2/cell3/count" \
  -m '{"schema":"count/v1","seq":1,"orderId":"WO-2026-04417","good":1,"scrap":0}'

Publish the same message twice and the adapter forwards it only once. Remember that the public broker is readable by everyone, so use invented order numbers only.

In production, keep the dedupe state (last_seq) somewhere durable, run the adapter with a persistent session so it receives events queued while it restarts, and give it its own credentials.

Integration Patterns and Pitfalls

Commands need acknowledgements. When the MES releases an order, the line should publish an acknowledgement with the order ID and status (accepted, rejected, started). Without it, the MES cannot tell whether the order arrived. MQTT 5 request/response with a response topic and correlation data formalizes this pattern.

Keep the MES out of the machine loop. Interlocks and safety logic stay in the PLC. MQTT carries events and instructions, not hard real-time control.

Do not let the MES become the namespace. If every consumer reads data through the MES, you are back to point-to-point integration. Publish raw events to the broker and let the MES be one subscriber among many, next to shop floor data collection tools, OEE dashboards and historians.

Plan for changeovers. Most count misattributions happen in the seconds around an order change. Have the line stamp the order ID on every count, and have the MES close an order only after it receives an explicit end event.

Pitfall Effect Prevention
No sequence numbers Double counts after reconnects seq per publisher, dedupe in adapter
Order not retained HMI shows nothing after reboot Publish current order with retain
Shared client IDs Adapters kick each other off Unique ID per instance
Broker on a single plant PC Integration stops when PC stops Use a managed broker

Running the Namespace on a Managed Broker

Once the MES, gateways and dashboards depend on the broker, its availability and security become your integration's availability and security. A fully managed MQTT service removes the burden of patching, certificates and monitoring a broker yourself. ConnectMQ provides MQTT 3.1.1 and 5.0 over TLS (8883) and secure WebSocket (8084), credentials bound to client IDs, and a portal with a live topic explorer and a devices view organized by ISA-95 levels, which makes it easy to verify that counts and states arrive under the right line and cell.

If your machines speak Sparkplug B, ConnectMQ can decode it and republish the data into readable ISA-95 topics, so the MES adapter subscribes to plain JSON paths rather than Protobuf. For the bigger architectural picture, see the smart manufacturing guide and the overview of what a cloud MQTT broker offers.

Connect Your MES to ConnectMQ

Sign up at app.connectmq.com, create a broker on the free Serverless plan with no credit card, and point the adapter above at it with YOUR_USERNAME, YOUR_PASSWORD and YOUR_CLIENT_ID from the portal.

Frequently Asked Questions

Does my MES need native MQTT support?

No. Many integrations use a small adapter that speaks MQTT on one side and the MES API or database on the other. Native support simply removes the adapter.

Should the MES publish work orders as retained messages?

Yes, the current order per line is a state, not an event, so retaining it lets any client that connects later know what is running. Order history belongs in the MES database.

How do I avoid double counting with QoS 1?

Add a per-publisher sequence number to each count event and discard any sequence the adapter has already processed. Alternatively publish running totals and compute deltas on the MES side.

Is MQTT secure enough for MES traffic?

With TLS, unique credentials per client and a broker that enforces client ID binding, MQTT is suitable for plant-to-cloud MES traffic. Keep safety and interlock logic in the PLC.

Related articles

OEE vs TEEP vs OOE: Which Metric Should You Use?

OEE, OOE and TEEP share the same performance and quality factors but measure against different time bases. This comparison works through one example and lists the MQTT signals each metric needs.

7 min read

All articles →

Your private MQTT broker is a few clicks away

Create an account, get your broker credentials and connect your first device — no servers to install, patch or scale.