Full stack a live path from field sensor to phone — and back one naming chain across six layers a panel drawn from BOM to wiring Ignition SCADA over OPC UA a Unified Namespace on Sparkplug B a bounded AI optimizer — prototype, advisory-only
A real industrial bench — Allen-Bradley PLC, PowerFlex VFD, Opto 22 edge I/O, Ignition SCADA and a Unified Namespace — wired and commissioned by one engineer, carrying live data up to the Atomate app, a React Native Industry 5.0 IIoT companion that reads the bench live and commands it back down — every layer speaking the same names.
Field I/O rises through a CompactLogix PLC, an Opto 22 groov RIO running Node-RED, and a Sparkplug B Unified Namespace on HiveMQ — into Ignition SCADA, a cloud worker, and the app. Commands take the one path back down, clamped at every step, to where the PLC has the last word.
Follow SpeedCmdPct down the stack — nothing renamed, nothing abbreviated. It's generated from one spec and re-checked on every commit, so the field and the phone can never drift apart. That discipline is what makes the round trip safe.
speedcmdpctspBv1.0/Bench01Lab/…/Drive01Drive01.SpeedCmdPct → Sparkplug BBench01/Drive01/SpeedCmdPctDrive01.SpeedCmdPctphysical originOne engineer took this from a parts list to a live bench: BOM → KiCad schematic → wired panel → commissioned. The electrical drawings are generated from bench-spec.yaml too — the net labels on the sheet are the same names that reach the app.
Every screen reads straight from the bench and is keyed by the exact same tag names as the PLC — live sparkline charts, per-device control, AI troubleshooting grounded in the equipment manuals, and a tap-to-apply optimizer.
Every device card carries a live sparkline chart, streaming straight from the bench — and anything not wired yet says OFFLINE, honestly.
Start, stop and set speed for any device — every command clamped to the limits the spec declares.
Ask what a fault means in plain English — the answer is grounded in the actual equipment manuals, with the pages cited.
The optimizer (prototype) frames energy it could hand back as a percentage and waits. You tap Apply — it never touches the controls on its own.
Still a prototype: a cloud worker reads the live snapshot and proposes an energy trim on the affinity law — advisory-only, clamped to limits the spec declares, with the PLC as the last word. And because the power meter isn't wired yet, the savings are a modeled estimate, not a measured result. The interesting part isn't the AI — it's the rails around it.
It surfaces a %-framed energy opportunity and waits. You tap Apply — a human stays in the loop.
Every setpoint it can touch is clamped to a min/max declared in the spec. It physically cannot exceed them.
One advisor, never a second hand on the controls. The physical E-Stop and local override always win.
Exactly one path issues a drive command. The optimizer can never fork into a competing hand on the machine.
The PLC always has the last word. The AI only ever asks.
I'm Adam Ramirez — I build industrial automation across the whole stack: the control panel (PLC, VFD, and the electrical design from BOM → schematic → wiring → commissioning), the IIoT architecture that carries it field-to-cloud, and the React Native app that connects live to the bench.
One naming chain, held identical across six layers from a single canonical spec — the discipline that keeps a phone and a PLC in lockstep, and makes it safe to put a bounded AI optimizer (a prototype, for now) anywhere near a control system.
Repository is private — happy to walk through the architecture on request.