Skip to content

NetworkSendDriver

Source: NetworkSendDriver.h

NetworkSendDriver

class NetworkSendDriver
src/light/drivers/NetworkSendDriver.h:34

Inherits: DriverBase

Output driver: streams the buffer over UDP, one driver carrying three industry protocols selected by a control.

Byte layouts live beside the receiver, so the two sides cannot drift.

One driver feeds many receivers, each taking a contiguous run of the window under its own address. A wall of tubes is one driver, the twin of one LED driver fanning out to several lanes, and unicast is the default.

Prior art: MoonLight's D_NetworkOut, and the Art-Net 4, E1.31 and DDP specifications.

Public Attributes

char ips = {} : Receiver addresses, comma-separated; the list order is the fan-out order.

char lightsPerIp = {} : Lights per destination; blank splits the window evenly, as an LED driver's list does.

uint8_t protocol = 0 : The wire protocol, which selects both the packet layout and the chunking.

uint16_t universeStart = 0 : The first universe the slice maps onto.

uint8_t fps = 50 : Send-rate ceiling (Hz); [tick()] rate-limits to this so a fast render tick doesn't flood the LAN.

Public Methods

inline NetworkSendDriver() : Default to the RGB preset: network fixtures are RGB by convention, unlike the strips.

virtual inline void defineDriverControls() override : Bind the protocol, the destinations, the universe offset, the window and the rate cap.

virtual inline bool affectsPrepare(const char * name) const override : Which controls route through the prepare sweep, so the corrected buffer is re-sized.

virtual inline void setup() override : Derive the stable component id from the MAC, which needs no UUID machinery.

virtual inline void release() override : Close the socket on release, then chain to the base to clear any status this driver set.

virtual inline void setSourceBuffer(Buffer * buf) override : Take the shared source buffer and re-size the corrected buffer for it, off the hot path.

virtual inline void prepare() override : Open the socket, resolve the destinations and their window slices, and size the buffer.

virtual inline void onCorrectionChanged() override : Re-size the corrected buffer when the preset changes the output channel count.

virtual inline void tick() override : Correct the window into the staging buffer, then chunk it into packets and send.

inline const Buffer & correctedBuffer() const : Test-only accessor for the corrected buffer, pinning the no-allocation contract.

inline uint8_t destinationCount() const : How many receivers the parse derived, for a test pinning the fan-out arithmetic.

inline const uint8_t * destinationAt(uint8_t i) const : The address of destination i.

inline nrOfLightsType lightsAt(uint8_t i) const : How many lights of the window destination i owns.

Public Static Attributes

constexpr const char * kProtocolOptions = {"ArtNet", "E1.31", "DDP", "E1.31 multicast"} : The protocol names, index-aligned with the constants the send switch uses.

constexpr uint8_t kProtocolCount = 4 : How many protocols the selector offers.

constexpr uint8_t kProtoE131Multicast = 3 : The protocol index that sends E1.31 to its native multicast group.

constexpr uint8_t kMaxDestinations = 32 : How many receivers one driver can feed: a wall of tubes, not a subnet scan.

Public Static Methods

static inline void e131MulticastAddr(uint16_t universe, uint8_t out) : The sACN multicast group for a universe.

More info

Why unicast is the default

Art-Net 4 requires unicast; broadcast survives here as legacy compatibility. A universe number lives in the payload rather than a header, so a receiver parses every packet before discarding the universes it lacks. Broadcast makes each host pay for all of them. The practical ceiling is near fifteen universes, measured on the bench where a large grid starved an ESP32's network stack.

Unicast duplicates nothing when each node owns a different slice, which is the normal case. The sender emits as many packets as a broadcast stream would, each reaching only its owner.

Liveness

UDP is fire and forget, so a dead receiver is invisible. The send loop tolerates one rather than pretending to detect it. A failed send drops that packet, so one dark tube stalls nothing.

NetworkSendDriver card