Helios

Sources and universes

How output is addressed and how handles work.

A source owns scheduling, persistence, and transport for one or more outputs. A universe handle is a typed view over one output address.

Addresses

Each output is identified by (universe, priority):

FieldRangeDefault
universe1..63999
priority0..200100

Receivers merge competing sources by priority. Pick priorities deliberately so you do not override a console by accident.

Creating a source

On Node, prefer the composition helper:

import { createSacnSource } from "@helioslx/core/node";

const source = createSacnSource({
  name: "My lighting app",
  transportOptions: { iface: "192.168.10.20" },
});

That creates and owns a NodeSacnTransport. From the root module you inject a transport yourself:

import { createSacnSource } from "@helioslx/core";
import { NodeSacnTransport } from "@helioslx/core/node";

const source = createSacnSource({
  transport: new NodeSacnTransport({ iface: "192.168.10.20" }),
  ownsTransport: true,
});

Construction does not open the send loop. The first output mutation (or an explicit start()) restores stored targets and starts scheduling.

Universe handles

const universe = source.universe(1, {
  priority: 100,
  sourceName: "Dimmers",
  // cid: "...",
  // idleFps: 2,
});

Handles for the same (universe, priority) are cached. The first call wins for priority, cid, sourceName, and idleFps defaults on that address.

Useful source methods:

  • listUniverses() — immutable snapshots, ordered by universe then priority. Does not auto-start.
  • getTelemetry() — synchronous engine counters
  • subscribe(listener)started, stopped, output-updated, output-cleared, closed

Channels vs frames

Public channel maps use one-based keys (1..512). Full frames are always 512 values; slot 0 is channel 1 on the wire.

await universe.setChannels({ 1: 255 }); // channel 1

const frame = new Uint8Array(512);
frame[0] = 255; // also channel 1
await universe.write(frame);

What this package is not

Fixture patching, attribute resolution, scenes, and show playback are out of scope. Resolve those into channel maps or frames, then call a universe handle.

On this page