Before an AI reads your factory data, make the machines stop lying
An AI tool reads whatever your machines send and believes it. If breakdowns never end and clocks are not synced, fix the payload contract before the pilot.

An AI tool pointed at your factory will read what the machines send, and it will believe it. If a breakdown starts and never ends, or a timestamp comes from a clock that never synced, the model gives you a confident wrong answer. Before the AI pilot, fix what the machines say. We learned this on a live OEE project, when a firmware review found that most breakdowns in one table had no end time.
Most of the breakdowns never ended
In July 2026 we were building OEE dashboards for a die-casting manufacturer. Controllers on the machines published events over MQTT, and a server turned them into downtime and OEE.
The breakdown table attached to the review showed the problem. Two days, four machines, 18 breakdown rows. Eleven had a start time and nothing else. No end time, no duration. The seven that did close lasted roughly 12 to 24 minutes each.
An open row can mean three things. The machine is still down. Someone fixed it and the end message never arrived. Or the controller lost power or its connection. The table could not tell them apart, and neither could we.
The firmware review came down to three notes:
- Many breakdown events were not reporting end times.
- No data should be sent before the clock finishes syncing.
- The
Idlestate had to come out of the heartbeat messages.
The notes do not record a single cause for the missing ends, so we will not invent one. One detail of the code at the time is worth knowing, though. When the MQTT connection was down, the publish function simply returned. Whatever happened during that window was never sent, and nothing told the server it had missed something.
The payloads had drifted too. Each message type carried its own fields: a site, a device, a nested block with a pin number or a relay state. One version worked out the breakdown duration on the device and sent it along.
Why this matters more now
AI tools are arriving on the plant floor. Vendors now let AI agents query machine data directly, often through MCP, the open standard for connecting agents to data and tools. HighByte puts the requirement plainly: agents need access to contextualized and standardized data (opens in a new tab).
Kai Waehner’s Industrial IoT Landscape for Q4 2026 (opens in a new tab) makes the same point from the other side. Raw values dumped onto a broker are a message bus, not a foundation, and plants without that foundation “will run agent pilots that never leave the lab.”
Picture an agent reading our July table. Asked how much downtime the plant had, it would either count eleven stops as still running or quietly leave them out. Both answers sound reasonable, and both are wrong.
Connected devices misbehave without a contract. This month a smart coffee maker was found to have generated about 1TB of traffic in 10 days (opens in a new tab) on a home network. Its owner put it down to a bug and unplugged it. You cannot unplug a press in the middle of a shift.
The contract we wrote instead
We replaced the ad hoc messages with a fixed contract. Every message is small JSON on one of four topics, carries the registered machine id, and has an ISO-8601 timestamp in UTC.
/eventscarriescycle_start,cycle_end,estop_startandestop_end. A cycle starts before it ends, and an e-stop interrupts any open cycle./breakdowncarries the start and end of a stop, with a reason code from a configured list such astool_changeormaterial_shortage. The end repeats the reason, and the reason on the start wins./heartbeatcarries the machine’s current state, about every 30 seconds./statussaysonlineas soon as the machine connects, andofflinewhen it drops.

A breakdown start looks like this:
{
"plant_id": "1",
"machine_id": "Machine-01",
"event_type": "breakdown_start",
"reason": "tool_change",
"timestamp": "2026-08-27T08:35:00.000Z"
}
There is nothing clever here. The value is that every machine says the same thing the same way, so the server, a dashboard or an AI agent can read it without a translation layer for each controller.
Heartbeat and Last Will explain the silence
An event stream only tells you what happened. It cannot tell you that nothing is arriving because the device is gone. Two parts of the contract cover that.
The heartbeat repeats the current state about every 30 seconds. During a breakdown, that state is the breakdown’s reason code, so the server keeps hearing that the stop is real. The Idle state is gone. The heartbeat now only carries states the contract defines, and it never says offline. Connectivity lives in /status and nowhere else.
The second part is MQTT’s Last Will. When the controller connects, it hands the broker an offline message for /status. If the controller disappears without disconnecting cleanly, the broker publishes that message for it. On our server, that creates an automatic Offline incident, which counts in OEE like any other breakdown.

Nothing goes out before the clock is right
Every duration is an end time minus a start time, and every stop is assigned to a shift by its timestamp. A controller that has just booted may not know the time yet. Anything it publishes in that window carries a wrong timestamp, and every duration and shift total built on it is wrong too.
So the rule is blunt: no data goes out until time sync has finished, and every timestamp is UTC. A few seconds of silence after a reboot cost far less than a breakdown filed under the wrong day.
The device reports, the server calculates
The contract also lists what the hardware must not send: duration_seconds, part, operator and supervisor ids, and OEE values. The ingestion service works these out.
The device-side duration had already been dropped from the firmware. A duration computed in firmware is only as good as the firmware that computed it, and once it is stored you cannot recompute it. A timestamp can be recomputed whenever the rules change. The server also knows things the controller does not: the shift calendar, the part on the machine, the standard cycle time. That is where stops get clipped to shifts and hours get summed before anything is divided, as we described in why your OEE is probably averaged wrong.

Is your machine data ready for AI?
Before an AI pilot touches your machine data, check these against a day you already have:
- Count the breakdowns with a start and no end. If the count is more than a handful, fix that before anything else.
- Ask what the device does when its connection drops. If it silently skips events, you will get gaps nobody can explain.
- Check that a disconnect shows up as its own record, through a Last Will or something like it, and not just as silence.
- Look for a heartbeat. Without one, a quiet machine and a dead one look the same.
- Confirm devices wait for time sync before sending, and that every timestamp is UTC.
- Check that every message type has a fixed, written schema and that reasons come from a fixed list.
- Make sure durations and OEE are computed on the server from raw timestamps, not sent by the device.
- Pick one day and rebuild its downtime by hand from the raw events. If you cannot, an AI cannot either.
If you are planning an AI pilot on machine data and want a second pair of eyes on the payloads first, tell us.