For a long time we built camera analytics as a separate system: its own server, its own panel, its own alert. Once we started working with manufacturing customers the separation stopped making sense. The PLC already knows the machine stopped, the camera knows whether the operator is there; without the two joining, the information "machine stopped, operator absent, 4 minutes gone" never appears. Since then we treat the camera as a sensor. The richest sensor, but a sensor.
The common language: the event
Whatever comes from any source is turned into an event. From the camera "zone intrusion", from the door contact "door opened", from the PLC "line stopped", from the temperature sensor "threshold exceeded". One event schema:
{
"source": "cam-07", // source identifier
"type": "zone.intrusion", // event type, dotted hierarchy
"ts": "2026-04-21T09:14:03Z", // UTC timestamp
"site": "gebze-01",
"zone": "press-line-2",
"confidence": 0.93, // 1.0 for sensors
"rule": "r-118",
"payload": { "duration_s": 12, "object": "person" }
}
Every field in the schema has a reason. Without site and zone there is no filtering for a multi-site customer. confidence exists so that an event from a camera is not weighed the same as one from a sensor. The rule field shows which rule produced the event; when the rule changes, the interpretation of old events changes too, and you need to know that retrospectively.
Transport: MQTT
Inside the site we use MQTT. Reasons: lightweight, sub-10-millisecond latency on the local network, the publish–subscribe model means adding a new consumer does not change the producer, and most industrial devices already speak it. Topic structure:
cx/{site}/{source}/{type}
cx/gebze-01/cam-07/zone.intrusion
cx/gebze-01/plc-line2/machine.stop
cx/gebze-01/env-03/temp.high
Consumers subscribe with wildcards: the shift supervisor's panel listens to cx/gebze-01/+/zone.*, the maintenance team to cx/gebze-01/plc-+/#. The broker is on site, on the same machine as the server or on a separate small box. What goes to the cloud is a set of selected topics bridged from the broker; the video still does not go.
The road outward, to the customer's own systems, is webhooks and REST. ERP and MES teams do not know MQTT, they know HTTP POST. The same event schema goes as JSON; for the BI team that wants CSV an hourly file is dropped as well.
Combination rules
The real value is in events combining. A few real examples:
- Machine stopped + operator absent. The PLC says "line stopped", the camera sees nobody in the operator area for 3 minutes. Result: unattended-stop event, notification to maintenance and shift supervisor. With the PLC alone the reason for the stop is unknown; with the camera alone it is unknown that the machine stopped.
- Door opened + zone intrusion. The electrical-room door contact opened, no authorised vest seen in the zone within 30 seconds. Result: unauthorised access. The contact alone would alarm on every opening; the camera alone would not know the door opened.
- Temperature rose + smoke. Sensor threshold exceeded, camera sees a smoke-like pattern in the same zone. Each alone can produce a false alarm; together they are a pre-fire event.
- Forklift proximity + beacon relay. The camera produces the event, a zone controller pulls the relay over MQTT, light and sound. The reverse direction: camera triggers, IoT acts.
Combination rules live in the rule engine with a time window: "if event B arrives within N seconds after event A, produce C". Window and sources are defined from the interface.
Clocks
The most frequent fault we meet in this architecture is timestamp mismatch. The PLC clock 40 seconds ahead, the camera on local time, the server on UTC. The rule "B within 30 seconds after A" never fires. The rule: every source syncs to NTP, every event is stamped in UTC, conversion to local time happens only in display. We made this the first item on the commissioning checklist.
Querying back in time
Events are stored in a time-series database. "Last month, on line 2, in the first hour after shift change, how many unattended stops" is a single query. The OEE calculation comes from the same data; I will cover that in a separate article. Because no video is stored, this database stays small: a few hundred MB a day for a 60-camera plant.
The lesson
Sold on its own, camera analytics remains "a nice panel". Connected to the same event bus as PLC, door contacts, temperature and POS, it becomes part of operations. The difference is not technical but architectural: fixing the event schema on day one, and designing the camera as one of the sources, not an exception.