Skip to content

Signals ​

A signal is a message you have named and kept: an OSC message, a raw UDP datagram, an HTTP request or an MQTT publish, with its target. You build it once — on the Signals screen, or by saving what you just sent from another screen — and send it again whenever you need it, byte for byte the same.

The library is a JSON file you can read, edit by hand, copy to another machine or commit next to a project. The Signals screen shows it as a tree of folders on the left and the selected signal's fields on the right.

What a signal can send ​

Pick the kind in Transport. Each kind has its own fields:

TransportFieldsWhat goes out
OSCTarget host:port, OSC address, ArgumentsOne OSC message to one IP:port or host:port, from a fresh UDP port. See OSC for the argument types.
UDP (raw)Target host:port, Kind (Text or Hex bytes), PayloadOne datagram with exactly these bytes. Text goes as written, without a terminator; hex is pairs of digits such as de ad be ef (spaces and a 0x prefix are allowed).
HTTPMethod, URL, Timeout (ms), Headers, Authentication, BodyOne HTTP request. See HTTP.
MQTTBroker host:port, Topic, QoS, retain, PayloadOne publish. See MQTT.

Every signal also has a Name, a Folder and a Note — what it should make happen and what has to match on the far end.

The targets of OSC and UDP signals are IP:port or host:port (for example 127.0.0.1:9000); a host name is looked up each time the signal is sent. The broker of an MQTT signal is host:port; without a port it is 1883.

When you change the kind of a signal, its message starts again from that kind's defaults. Only the target is kept, and only between OSC and UDP (raw), where the target means the same thing.

Sending a signal ​

To send a signal from the Signals screen, do any of these:

  • Select it and press Send.
  • Press Ctrl+Enter while you work in its fields.
  • Double-click it in the tree.

Each send writes a line to the console: what went where, the bytes sent, or for HTTP the status and the time it took. A failure (a refused connection, a host that cannot be reached) is a red line with the reason. The time of the last send shows beside the buttons.

A signal goes out through the same commands as the screens of its protocol, so the Inspector lists it under the tool that sent it, and the far end cannot tell it from one you typed.

How each kind is sent:

KindHow it goes out
OSCAs the OSC screen sends a message.
UDP (raw)One datagram to the target.
HTTPAs the HTTP screen sends a request, with its cookie jar while Keep cookies is on there. A refused connection or a timeout counts as a failure, not as a status.
MQTTWhile the MQTT screen is connected to the signal's broker, on that connection, with its client id and credentials. Otherwise — not connected, or connected to another broker — Signal Lab connects to the signal's broker for this one publish, with a client id of its own, no user name and a clean session, then disconnects.

A connection is to the signal's broker when the host is the same, ignoring case, and the port is the same, 1883 standing for a broker written without a port. Names are not looked up: localhost and 127.0.0.1 are two different brokers here, so a signal that names one is not sent over a connection made to the other.

TIP

An MQTT signal stores no password. To publish to a broker that asks for one, connect to that broker on the MQTT screen first; the signal then rides that connection.

Sending from any screen ​

Press Ctrl+K on any screen to open the palette, type a few letters of a signal's name, folder, target or message, and press Enter. The palette closes and the signal is sent; you stay on the screen you were watching.

KeyWhat it does
Ctrl+KOpens the palette, or closes it.
↑ ↓Moves the choice.
EnterSends the chosen signal.
EscCloses the palette without sending.

The palette lists at most 12 signals: the first 12 of the library while you have typed nothing, then the first 12 that match. A click on a row sends it; a click outside closes the palette.

Making signals ​

On the Signals screen ​

  1. Pick the folder the signal belongs in (see current folder).
  2. Press New signal. A new OSC signal to 127.0.0.1:9000, address /hello, appears in that folder, selected.
  3. Change Name, Transport and the fields of the message.

Every change is saved on its own; there is no save button on this screen. While the library file cannot be read, nothing is saved and the fields are read only (see The library file).

Duplicate puts a copy right after the selected signal, its name followed by ·. Delete asks once more (Delete?): the second click removes it from the file. Its folder stays, even when it is now empty.

From the HTTP, OSC and MQTT screens ​

The sending part of three screens — Request on HTTP, Sender on OSC, Publish on MQTT — can keep what it would send as a signal.

  1. Set up the message and send it until it does what you want.
  2. Press Save… (or Ctrl+S in that part of the screen). The Save to the library dialog opens.
  3. Check Name: it is suggested from what is being sent.
  4. Pick or type a Folder. The folder you used last time is filled in; a path such as Venue/Stage that does not exist yet is made.
  5. Press Save.

From then on the screen is tied to that signal. A chip beside the buttons says where it lives (❖ Folder / Name); click it to see the signal on the Signals screen.

You seeIt meansWhat you can do
✓ Saved (greyed)The library holds exactly what the screen would send.Nothing to save.
Save, and changed on the chipThe screen's message differs from the signal.Save or Ctrl+S writes the screen's message into that signal; its name, folder and note stay.
Save as…—Opens the dialog again, filled with the signal's name and folder, and saves a new signal. The screen is then tied to the new one.

The comparison looks at the message, not at how it is written: the order of JSON keys and the last digits of an OSC float beyond 32-bit precision do not count as a change.

The HTTP and OSC screens keep the tie when Signal Lab restarts; the MQTT screen keeps it until you close the app.

WARNING

An HTTP signal keeps its Authentication — user name and password, or token — in the library file as plain text. Anyone who can read the file can read them.

Opening a signal in its screen ​

A selected HTTP, OSC or MQTT signal has a button that opens it in the screen of its protocol (HTTP, OSC or MQTT). The screen's fields are filled from the signal and the screen is tied to it, as above: edit there, send, then Save. A raw UDP signal has no screen of its own.

From a frame or a topic ​

  • In the Inspector, select a frame and press Save as signal. A datagram becomes a raw UDP signal with that frame's exact bytes; an MQTT publish becomes an MQTT signal with the same broker, topic, QoS, retain flag and payload. Other frames cannot be saved.
  • On the MQTT screen, select a topic and press Save as signal. You get an MQTT signal that publishes the topic's last value, with its QoS and retain flag, to the broker you are connected to.

Both go into the folder Captured and are named after what was captured.

In an experiment ​

When you add a node to an experiment, the Add node menu also lists your signals under Saved signals. Picking one adds an OSC, HTTP, MQTT or UDP node with the same message. A raw UDP signal with a hex payload is not offered: the UDP node sends text. See Nodes.

Folders ​

A folder is a path of names joined by /: API/Auth is the folder Auth inside API. A signal's Folder field holds the path of its folder; empty means the top level (top level). Names are trimmed and empty parts dropped when you leave the field, so API / Auth/ becomes API/Auth.

Folders are sorted by name, numbers in numeric order (Cue 2 before Cue 10); signals stay in the order of the file. Each folder shows how many signals it holds, its sub-folders included. An empty folder is kept until you remove it.

The current folder ​

The folder you clicked last, or the folder of the signal you selected, is the current one: New signal and New folder put things there. A chip above the tree names it; click the chip to go back to the top level.

Working with folders ​

ToDo this
Make a folderPress + New folder. It is made inside the current folder, named New folder (with a number after it when that name is taken), and you rename it straight away.
Open or close a folderClick it, or press → / ← while it has focus. Signal Lab remembers which folders are closed.
Open or close them allThe ⊞ and ⊟ buttons above the tree (Open every folder, Close every folder).
Rename a folderPress ✎ (Rename folder) or F2 on it, type, then Enter; Esc cancels.
Move a signal or a folderDrag it onto a folder, or onto empty space in the tree for the top level.
Move a signal by typingChange its Folder field.
Remove a folderPress × (Remove folder) and then Remove?, or press Delete twice on it.

A rename never merges two folders: a name with / in it, or one a sibling folder already has, is refused, and the console says so. A folder cannot be dragged into itself or into a folder inside it. Dragging a folder into a folder that already holds one of the same name merges the two.

Removing a folder removes the folder only: its signals and sub-folders move up one level. Nothing is deleted.

Finding a signal ​

Type in Filter by name, folder or target above the tree. It matches the name, the folder, the note, the target and the message. While you filter, every folder with a match is open and the others are hidden.

The starter set ​

The first time Signal Lab finds no library file, it writes nine examples, each about something that is easy to get wrong. Their names and notes are written in the language of the interface at that moment; after that they are yours to change. All of them point at this computer.

FolderSignalSends
OSCFader value/fader/1 with the float 0.75 to 127.0.0.1:9000
OSCEvery argument type/types with int -7, float 1.5, string hi, bool true, int64 4294967296, double 0.125 and nil
OSCIdentifier and value/tag with the strings reader-1 and 04a1b2c3
OSCTrigger with no arguments/cue/go with no arguments
MQTTPublish a value1 to lab/example/value on 127.0.0.1:1883, QoS 0
MQTTSet a retained valuenight to lab/example/config, QoS 1, retained
MQTTClear a retained valueAn empty retained payload to lab/example/config, QoS 1
HTTPIs the service up?GET http://127.0.0.1:8080/, timeout 4000 ms
RawRaw UDP bytesThe bytes de ad be ef to 127.0.0.1:9000

To get the starter set back, move or rename signals.json and press Reload file: with no file there, it is written again.

The library file ​

The library is signals.json in the data folder: Documents/SignalLab in your home folder on a desktop, or the server's data folder (see Files). Hover the signal count under the tree to see the full path.

  • Saved on its own. Every change is written 0.7 s after the last one, the whole file at once, through a temporary file in the same folder that then takes the file's place — a write cut short leaves the previous file. While a write waits, the foot of the tree says saving…; then saved. A write still waiting is made before an update restarts the app.
  • Edited by hand. Signal Lab does not notice when the file changes under it. After editing it, or replacing it with one from another machine, press Reload file. Reloading reads the file again and drops a change that was still waiting to be written.
  • Never replaced while it is broken. If the file is not valid JSON, or not a signal library, the tree shows the error with the file's path, line and column, and the console says the same. The file is left as it is, and nothing writes the library until it reads again: New signal, renaming, moving and removing signals and folders, dragging, the fields of a signal, Save…, Save and Save as… on the HTTP, OSC and MQTT screens, and Save as signal in the Inspector and on the MQTT screen are all off, and their tip says what is wrong. Fix the file, or remove it, and press Reload file: once it reads, everything works again.
  • A file that breaks while the app runs. If you edit the file into something unreadable and the app then saves a change, the save is refused with the same error, the file is left as you made it, and the app stops writing until you fix it and press Reload file. A file you edited and left valid is replaced by the app's list at its next save, as above: reload first.

A short example of the file:

json
{
  "version": 2,
  "signals": [
    {
      "id": "fader-value",
      "name": "Fader value",
      "group": "Venue/Stage",
      "note": "Main fader of desk A.",
      "body": {
        "transport": "osc",
        "target": "127.0.0.1:9000",
        "address": "/fader/1",
        "args": [{ "type": "float", "value": 0.75 }]
      }
    }
  ],
  "folders": ["Venue/Stage", "Venue/Empty for now"]
}
KeyWhat
version2. A version 1 file (before folders) reads the same, without empty folders.
signals[].idMade from the name when the signal is made (fader-value, fader-value-2, …) and never changed by a rename. signallab fire finds a signal by it.
signals[].groupThe folder path; "" is the top level.
signals[].bodyThe message. transport is osc, udp, http or mqtt; the other keys are that kind's fields.
foldersEvery folder, so an empty one is kept. Left out when there are none. A group no entry lists is a folder too.

From the command line ​

signallab fire sends a signal of a library, through the same commands as the app:

bash
signallab fire "Fader value"
signallab fire fader-value --library ./show/signals.json

It finds the signal by its id first, then by its name, ignoring case. When several signals have that name, it names their ids and sends nothing. Without --library it reads the app's own signals.json; it never writes the file. See The command line.