DIY SCADA with Node-RED: A Field Technician’s Guide to Modbus and Refrigeration Monitoring
The cost problem commercial SCADA vendors don’t like to discuss
Commercial SCADA licensing is expensive. Platforms like Inductive Automation’s Ignition price their module bundles from a few thousand dollars for a basic configuration up to $35,000 or more at the enterprise end. That’s before integration work, hardware, or annual maintenance fees. Refrigeration-focused packages aren’t cheaper on a per-feature basis — they’re just smaller. Most were designed by software companies who’ve never crouched behind a compressor rack to swap a controller board.
The pricing structure exists because the market is thin and sales cycles are long. Not much competition pushes costs down. For a technician who wants proper monitoring across a handful of customer sites, the math rarely works out in favor of buying commercial software. So people either go without, or they build something.
Why Node-RED makes sense as a foundation
Node-RED is a flow-based visual programming environment built on Node.js, originally developed at IBM and now an OpenJS Foundation project. It runs on anything from a Raspberry Pi to a Linux server. It’s free. The industrial protocol ecosystem around it is broad — community nodes cover Modbus, OPC-UA, MQTT, Siemens S7, BACnet, and more.
For Modbus specifically, node-red-contrib-modbus handles both RTU (serial) and TCP variants and supports all the standard function codes. Polling intervals, read grouping, and basic error recovery are configurable through the visual UI rather than written in code. That matters when the goal is to focus on refrigeration logic, not TCP socket management.
The Dashboard 2.0 node gives you browser-based UI components — gauges, charts, tables, indicator lights — wired together visually. Not as polished as a dedicated HMI product out of the box, but flexible enough to build system overview pages and controller detail views with sufficient time invested.
The hard part: auto-discovery and device profiling
Standard Modbus has no native auto-discovery. Every device on a Modbus network has a manually assigned slave address between 1 and 247, and the protocol has no broadcast mechanism for querying which devices are present. It dates to 1979, built for simple serial networks where the engineer already knew the topology.
Building auto-discovery on top means scanning the address space — sending a read request to each candidate address and treating a valid response as device present. This is slow on RS-485 networks because timeouts accumulate fast. It also stresses older controllers that weren’t designed for interrogation at that rate. The smarter approach is to narrow the scan to a known address range for a given site, cache confirmed responses, and build a profile per device: register map, polling interval, alarm thresholds, display labels. That profile library grows naturally as new controller models appear in the field.
Commercial SCADA systems handle this through proprietary device drivers sold as add-on licenses. Build it yourself and you own the full profile store, tailored to the exact controller variants your customers actually use.
Polling strategy: the gotcha most tutorials skip
Older refrigeration controllers — and plenty of new cheap ones — don’t handle rapid back-to-back Modbus requests well. Some lock up. Some drop connections silently, which means polling stops and you don’t notice until an alarm goes missing hours later.
The fix is grouping consecutive holding registers into single read requests wherever possible. If you need registers 1 through 20, one call reads them all. node-red-contrib-modbus supports this, but it won’t automatically merge reads across separate flow paths. You configure it deliberately. Getting the grouping right early — before the register map grows across a dozen device types — saves real pain later.
Poll rate deserves the same attention. Temperature readings every 10 seconds, alarm status every 2, setpoints every 60 — that kind of tiered schedule cuts bus load and extends the life of older controllers not built for constant interrogation.
What the full stack looks like
A working Node-RED SCADA setup for refrigeration typically involves four layers:
- A polling layer that reads Modbus registers on a schedule, with flows organized per device type or per site
- A processing layer that converts raw register values to engineering units, applies scaling factors, and evaluates alarm conditions against thresholds
- A storage layer — InfluxDB for time-series data works well, with something lightweight like SQLite or a JSON file store for device profiles and site configuration
- A dashboard layer, either Node-RED Dashboard 2.0 or a standalone tool like FUXA, an open-source web-based SCADA front-end that supports Modbus, OPC-UA, MQTT, and Siemens S7
FUXA is worth knowing about for the HMI side. It can sit alongside Node-RED — Node-RED handles data collection and transformation, FUXA handles visualization on a separate port, with the two talking over MQTT. That separation keeps concerns clean as the system grows.
Where this approach has real limits
Node-RED is not a safety-rated control system. For refrigeration monitoring and alerting — reading temperatures, pressures, and alarm states — that distinction matters less than it would for direct process control. But it is worth being clear-eyed about what you’re building and what it isn’t.
Reliability needs deliberate engineering. Node-RED has no built-in redundancy, and a crashed flow stops polling with no automatic notification. Running Node-RED as a systemd service on Linux with automatic restarts covers the basic failure case. Anything more critical needs watchdog processes and alerting on the monitoring system itself going offline.
The time cost is also real. Building a full SCADA-style system from scratch — even with Node-RED doing the heavy lifting — is a months-long project. It only makes sense if the commercial alternative is genuinely too expensive or too inflexible for your actual situation.
