Sending a reading up is the easy half. The half that trips people up is getting a command back down: HTTP is request/response, so how does the cloud tell a device behind home Wi-Fi to flip a relay or change a setpoint? It doesn’t, directly. The device asks. It fetches any pending control writes, applies them, and acknowledges the ones it handled so they aren’t sent again — a pull, not a push, with no broker, static IP, or inbound connection.
On an ESP32 or ESP8266 the nodrix Arduino library runs that whole loop for you: fetch, apply, ack, reconnect. You write a handler per variable and the library calls it whenever the cloud writes that variable. This guide shows that, then explains what it does underneath — at-least-once delivery, idempotency, and acking.
Two modes, matched to how the device lives
The library connects one of two ways. Both share the same handlers and the same token, so you can start with one and switch later without touching the cloud side.
begin() — WebSocket | beginHTTP() — poll | |
|---|---|---|
| Latency | instant | your poll interval (seconds) |
| Connection | one socket held open | none held; one request per check |
| Best for | always-on controllers | sleepy / periodic devices |
| Battery | poor unless mains-powered | excellent (sleep between polls) |
| Cost when idle | ~zero (Cloudflare hibernates it) | one request per interval |
Handle a control write
A “command” is a control write — a pending instruction to set a variable: relay to on.
Register a handler for the variable and the library runs it on every write, whether it came from a
dashboard toggle, an automation, or the API:
#include <Nodrix.h>
NODRIX_WRITE("relay") {
digitalWrite(RELAY_PIN, value.asBool());
}
void setup() {
pinMode(RELAY_PIN, OUTPUT);
Nodrix.begin(WIFI_SSID, WIFI_PASS, HOST, TOKEN); // always-on WebSocket
}
void loop() {
Nodrix.run(); // control in, telemetry out, acks, reconnect
}
value coerces the wire value for you — asBool(), asInt(), asFloat(), asString() — so a
toggle that sends "on" and a slider that sends 42 both just work.
Battery / deep sleep: poll on each wake
A sleepy device doesn’t hold a socket. Switch to HTTP mode and drain the queue once per wake, right after you report — the board is already connected, so the extra request is nearly free:
#include <esp_sleep.h> // deep-sleep API
void setup() {
Nodrix.beginHTTP(WIFI_SSID, WIFI_PASS, HOST, TOKEN);
Nodrix.send("soil", analogRead(34));
Nodrix.flush(); // POST telemetry
Nodrix.poll(); // fetch + apply queued writes, then ack
esp_sleep_enable_timer_wakeup(15ULL * 60 * 1000000);
esp_deep_sleep_start();
}
Same handlers, same acks — a command simply applies on the next wake instead of instantly.
What the library handles for you
The downlink has a few sharp edges, and they’re the reason to use the library rather than hand-roll it:
- At-least-once delivery. A control write stays queued until it’s acked and re-delivers on the next connect or poll, so nothing is lost across a nap or a Wi-Fi blip. The library acks every write it hands your code.
- Reconnect and catch-up. On the socket it reconnects on its own and flushes anything queued while you were gone.
- One connection, both directions. Telemetry, events, and acks share the socket with control —
Nodrix.send()andNodrix.event()go up the same pipe.
Still your job
- Keep handlers idempotent. At-least-once means you can see the same command twice. Setting a pin is naturally safe; for anything that isn’t, act on the desired end-state rather than a toggle.
- Cap physical actions. Prefer a self-limiting action — a timed pulse over a latch — so a missed “off” can’t leave a pump or heater running.
Notes
- No broker, no inbound connection. The device only makes outbound HTTPS/WSS requests, so it works behind home routers, captive portals, and cellular NAT — port 443 is open everywhere.
- One token, one project. The same project token authorizes telemetry, control, and the socket; treat it as a secret and load it from config for anything real.
- Install it. Arduino Library Manager or PlatformIO; source and the
LedControlexample at github.com/decoded-cipher/nodrix-sdk. - It runs on your account. The control queue and dashboard live in a nodrix instance on your own Cloudflare account — single-tenant, nothing leaving your tenancy.