MQTT remote commands turn a one-way telemetry node into a device you can actually operate. Each ESP32 PLC subscribes to esp32/{id}/comands and answers on esp32/{id}/comands_response: ask for system info, list the SD card, trigger a file upload — all from a Node-RED console, no ladder, no laptop at the machine. This is the management channel of a real textile machine monitoring deployment spanning two plants.
Paired topics per device
The PLC ID is baked into both topic names, so a command always addresses exactly one device, while a supervision dashboard can subscribe to the wildcard esp32/+/comands_response and watch the whole fleet answer in real time. Every reply carries the PLC's identity so responses are attributable even when aggregated. An unknown command does not vanish into the void either — it returns an explicit error naming the supported commands, because silence is the worst possible diagnostic.
Keep the MQTT callback thin
PubSubClient's callback executes inside mqtt.loop(), and doing heavy work there — walking the SD directory, building long response strings — risks dropped MQTT packets and even watchdog resets. The callback in this example does the bare minimum, copying the command into a buffer and raising a flag, and the main loop picks it up and executes it on the very next pass. It is the same discipline you apply to an interrupt service routine — receive fast, process later.
Commands that earn their keep
Three commands cover the bulk of day-to-day fleet operations. The info command returns uptime, free heap, IP address and WiFi RSSI for remote health checks; list inventories the buffered .json files sitting on the SD card with their sizes; and upload hands a chosen file off to the HTTP POST module to recover a full day of data. Re-subscription happens after every MQTT reconnect, so the command channel transparently survives broker restarts and network drops.
A snippet from the implementation
Straight from the example as deployed on the ESP32 PLC — copy it freely:
The full example is a complete program — wiring header, setup and main loop — ready to adapt to your application.
Frequently asked questions
Why not put commands and responses on the same topic?
The PLC would receive its own replies and loop, and consoles could not filter requests from answers. Paired topics give clean routing and let you set different ACLs on each direction in the broker.
What stops an unauthorized client from sending commands?
The broker connection uses credentials, and broker ACLs can restrict who may publish to the command topics. Keep the broker on the plant network and give consoles their own accounts.
Can I add actuation commands, like stopping a machine?
Technically yes — subscribe and drive an output — but in this monitoring deployment commands are deliberately read-only plus file operations. If you actuate, add payload validation, idempotency and an interlock on the machine side.