Skip to content

DCN bus vs serial port: Node-RED and the ISR client

This note explains why the ISR client disables Node-RED by default when proxying a Station Controller, and how that relates to the DCN protocol’s multi-master design on the RS-485 bus.

Two different layers

These are often conflated, but they are not the same problem.

DCN protocol layer (RS-485 bus)

At the DCN protocol level, the Station Controller design is largely correct: RS-485 is a shared bus, multiple masters can exist, and collisions are a normal concern on the wire.

The ISR client handles some of that when it alone owns the serial port:

  • Topology scan does not assume response[i] matches PING[i]. It parses every chunk and uses FromAddr to identify who responded. Unsolicited UPDATE responses from other modules on the bus are expected during discovery.
  • The bridge deliberately does not flush the input buffer on normal topology/readings commands, so it can hear cross-talk from other modules on the same bus.
  • SET commands do flush, because stale bytes in the OS serial buffer would corrupt request/response pairing for relay and coax operations.

That is “anti-collision / shared-bus” handling within one serial reader — one process reading one byte stream and interpreting DCN packets.

Linux serial port layer (/dev/ttyS0, etc.)

At the OS level, the picture is different. Only one process should hold the serial device open at a time for reliable ISR client operation. That is what blocks coexistence with Node-RED on the same port.

Why Node-RED and the ISR client conflict

Node-RED’s serial/DCN flow typically opens the port and keeps it open. The ISR client does the same via isr_dcn_bridge.py, which takes an exclusive file lock on the port:

# isr_dcn_bridge.py — exclusive lock; second opener exits immediately
fcntl.flock(ser.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)

When Node-RED is running on the same port:

  1. Port open fails or is delayed — the bridge retries for a few seconds, then gives up.
  2. Overlapping traffic breaks the ISR model — the client assumes a clean write → read → parse cycle per command. Two independent writers on the same device interleave bytes in the kernel buffer; the Go side cannot reliably match “this response belongs to my PING/STATE”.
  3. Health checks — the ISR client periodically runs lsof on managed ports; if more than one application holds the port, it kills stale bridge processes and logs a warning.

Typical symptom under contention: Pi (host) readings appear, but topology finds zero DCN modules — not a hub routing failure, but incomplete discovery because the serial path is busy or traffic is mixed.

Can multiple DCN masters share?

Layer Station Controller design ISR client today
RS-485 DCN bus Multiple masters OK; collisions handled in protocol Partially supported inside one bridge (FromAddr, unsolicited UPDATEs)
Serial port Not the same as bus sharing One owner — exclusive flock, one bridge per port, serialized command queue
Node-RED + ISR client Sometimes described as two masters on one bus Not coordinated — two separate port drivers, not one shared DCN scheduler

The ISR client is not a multi-master DCN coordinator that time-slices the bus between Node-RED and itself. It implements:

  • One process owns the serial port
  • One command queue (normal + priority for SET)
  • Strict request/response semantics per command

What disable_nodered is for

The hub setting Disable Node-RED (default: on) is not “DCN forbids multi-master.” It means stop the other serial port consumer so the ISR client can own the port reliably.

The hub sends disable_nodered: true in the S_SC_SSH WebSocket payload when scanning starts. The ISR client should run on the Pi (over SSH):

sudo systemctl stop nodered
sudo systemctl disable nodered

before opening the DCN bridge.

Unchecking Disable Node-RED in the UI tells the client to leave Node-RED running. That is only appropriate when:

  • Modules used by the hub are on a different serial port than Node-RED, or
  • You accept degraded or unreliable DCN discovery and readings on a contested port.

Product documentation for advanced setups: Station Controller install — iSR Client and Node-RED.

Supported coexistence pattern

Documented advanced scenario: split by serial port, not by sharing one port.

Example:

  • Node-RED on /dev/ttyUSB0 for local flows
  • ISR client / isr_dcn_bridge.py on /dev/ttyS0 for hub-managed modules

Per-module DCN port overrides can be configured on the hub so the client probes the correct port per module during topology and readings.

What would true same-port multi-master require?

If hardware design requires Node-RED and the ISR client as peer masters on the same /dev/ttyS0, that would need new architecture, for example:

  • A single on-Pi DCN daemon that multiplexes all masters onto one serial opener, or
  • A Node-RED integration that sends commands through the ISR bridge queue instead of opening the port itself

That coordination layer does not exist in the current ISR client or hub stack.

Summary

  • Designer view (DCN bus): Multiple masters on RS-485 with protocol-level collision handling is a valid bus design.
  • ISR client view (serial port): One opener, one bridge queue, strict command/response — anti-collision logic applies to one reader, not to two independent masters on the same device node.
  • Default product behavior: Disable Node-RED when the hub proxies the SC so DCN topology and readings can run reliably on the configured serial port.