MQTT
The MQTT screen is an MQTT client for looking at a broker and changing what is in it. Connect, and by default it subscribes to #: every topic the broker holds builds up as a tree with its latest value. From there you publish, clear a retained value, save a topic as a signal or turn it into an experiment step.
Signal Lab speaks MQTT 3.1.1 over plain TCP, with QoS 0, 1 and 2 for subscribing, publishing and the last will. There is no MQTT 5 and no TLS: a broker that only accepts mqtts:// or MQTT 5 clients cannot be reached.
Connecting
- Open MQTT.
- Enter Broker host and Port.
- Leave Client id as it is unless the broker expects a particular one. Add User and Password only if the broker asks.
- Press Connect.
Connecting opens the TCP connection and completes the MQTT handshake before anything else, so a wrong password or a closed port is reported right there. The connection fields lock while connected; Disconnect closes it. The connection is a job in the console strip and can be stopped there too.
| Field | What | Default |
|---|---|---|
| Broker host | The broker's IP address or host name | 127.0.0.1 |
| Port | The broker's port | 1883 |
| Client id | Your client's name at the broker. It must not be empty, and must be unique there: a second client with the same id knocks the first one off. | signal-lab- and six random hex digits, new at every start of the app |
| User, Password | Sent only if the broker needs them — in plain text, since there is no TLS. A password without a user name is not sent at all: MQTT 3.1.1 cannot carry one. | empty |
| Keepalive (s) | Seconds the connection may stay silent. Signal Lab pings the broker every half of it; a broker drops a client that is silent for 1.5 times this. 0 turns pinging off. | 60 |
| clean session | On: every connection starts with no stored subscriptions and no queued messages. Off asks the broker to keep them for this client id between connections. | on |
| Scan on connect and its QoS | A filter subscribed to as soon as the connection is up; # is every topic. Empty: none. | #, QoS 0 |
| publish a message for me if I drop | Give the broker a last will (below) | off |
The broker has 6 seconds to accept the TCP connection and 6 more to answer the handshake.
The last will
A last will is a message the broker keeps for you and publishes itself if your connection dies without a proper goodbye. Presence is usually built this way: a device publishes online to its status topic, and its will sets the same topic to off.
With publish a message for me if I drop ticked, set Publish where and Publish what (off by default). The will is published at QoS 2 and retained. Without a topic, no will is sent.
Subscribing
The scan filter is subscribed at connect. For more:
- In Add a filter, type a topic filter.
- Choose its QoS.
- Press Subscribe or Enter.
A filter is a topic with wildcards:
| Wildcard | Stands for | Example |
|---|---|---|
+ | exactly one level | sensors/+/state matches sensors/door/state |
# | every level below, the last character only | sensors/# matches sensors/door/state and sensors |
Subscriptions lists each filter with what the broker granted: qos0, qos1 or qos2 — the broker may grant less than you asked — or refused. drop unsubscribes from one.
| QoS | Delivery |
|---|---|
| 0 | At most once: sent and forgotten |
| 1 | At least once: acknowledged, may arrive twice |
| 2 | Exactly once: a two-step handshake; a redelivery is not shown twice |
The topic tree
Every message that arrives goes into Topics, a tree of the topic levels. A topic shows its latest value, an R when that value is retained, and how many messages it has had when more than one. Click a level to open or close it.
- Type in the field above the tree to list only the topics whose path or latest value contains the text.
- Above the tree are the number of topics, how many hold a retained value and, while connected, the broker you are listening on.
- Payloads are shown as text; bytes that are not UTF-8 show as replacement characters.
- Clear empties the tree. Nothing else does: it stays as it is when you switch screens or disconnect, until the app closes.
Messages reach the screen in batches, ten times a second. When a broker sends more than 4000 messages in a tenth of a second, the oldest of that batch are left out of the tree and counted as "not shown" above it.
A topic's panel
Pick a topic with a value to see it below the tree: Value, QoS, retain, Bytes, Messages and Last seen. Its buttons:
| Button | Does |
|---|---|
| Load into publish | Copies the topic, value, QoS and retain flag into Publish |
| Wait for this | Adds a Wait for MQTT step on this topic, at this broker, any payload, 2000 ms timeout, to the open experiment |
| Clear retained | Removes the retained value (below) |
| Save as signal | Keeps the topic and its latest value as a signal in the Captured folder |
Publishing
- Connect.
- Under Publish, enter the Topic and the Payload.
- Choose the QoS, and tick retain if the broker should keep the message as the topic's value for every client that subscribes later.
- Press Publish.
The console confirms each publish: at once for QoS 0, when the broker has acknowledged it for QoS 1 and 2. A topic for publishing has no wildcards and is not empty: a topic with + or # is refused before anything is sent, with the same message a signal, a step and signallab send mqtt give, and the connection stays as it was. Only a subscription takes filters with wildcards.
Clearing a retained value
A retained value stays on the broker until it is replaced, and every client that subscribes gets it first — a stale one is a classic reason a device boots into the wrong state. The only way to remove it is to publish an empty payload with retain set.
Clear retained in a topic's panel does that: press it, then Clear it?. It publishes the empty retained payload at QoS 1 on your connection. It is available only while connected and when the topic's latest value is retained. You can do the same by hand: an empty Payload with retain ticked.
WARNING
Clearing changes the broker for every client at once.
In the Inspector
With capture armed, MQTT traffic appears with the protocol mqtt:
| Source | What | How many |
|---|---|---|
mqtt | What the screen's connection publishes; an empty retained publish has the verdict clears retained | every one |
mqtt | Messages the connection receives | at most one every 200 ms |
mqtt-send | A publish that brought its own connection: a signal fired while the screen is not connected to the signal's broker, a step, signallab send mqtt (verdict one-shot) | every one |
experiment-wait | Messages a Wait for MQTT step's subscription receives, retained replays aside | every one |
The summary reads topic = payload, with the QoS and retained when they apply. See Inspector.
Saving and reusing
- Save as a signal. Save… under Publish keeps the broker (the connection's Broker host and Port), topic, payload, QoS and retain flag in the signal library; Ctrl+S in the publish panel does the same, and updates the signal once the panel is tied to it. See Signals.
- Firing an MQTT signal. While this screen is connected to the broker the signal names (same host, ignoring case, and same port;
1883when the signal gives none), a signal fired from the library goes out over that connection, with its client id and credentials. Otherwise — not connected, or connected to another broker — it opens a connection of its own to its own broker — a fresh client id, no user name — publishes, waits for the acknowledgement its QoS calls for, and disconnects. Names are not looked up, solocalhostand127.0.0.1count as different brokers. The library stores no password. - In an experiment. A saved MQTT signal can be picked under Saved signals in the experiment's Add node menu, which makes it an MQTT publish step.
In experiments
| Step | What it does |
|---|---|
| MQTT publish | Connects, publishes one message and disconnects — no user name or password, a clean session, within 15 seconds. Details |
| Wait for MQTT | Subscribes when the run starts and waits for a message on a topic filter whose payload matches; retained values replayed on subscribing are ignored. Details |
| Emulator | An MQTT broker of the run's own. Details |
Neither step logs in, so they need a broker that accepts clients without a user name.
The broker emulator
Signal Lab can also be the broker: an MQTT broker emulator routes what clients publish to whoever subscribed — 3.1.1, plain TCP, QoS 0, 1 and 2, retained messages, wills, an optional login — and answers by rules, like a device. Point your gear and this screen at it to test without a real broker. See Emulators.
From the command line
signallab send mqtt publishes one message with a connection of its own:
signallab send mqtt 127.0.0.1:1883 lab/light/1/set on --qos 1
signallab send mqtt 127.0.0.1:1883 lab/light/1/state "" --retain✔ lab/light/1/set → 127.0.0.1:1883 · 2 B · qos1The second line clears a retained value. Without a port, the broker is on 1883. It uses no credentials. It exits with 0 when the broker took the message, 1 when it could not be reached or refused it. See Command line.
Problems
| What you see | Usual cause |
|---|---|
… refused the connection — nothing is listening on that port | No broker on that address and port. |
… accepted the connection but did not answer in time — is it an MQTT broker? | Something listens there, but does not speak MQTT, or speaks it over TLS. |
… answered with something other than MQTT 3.1.1 | Not an MQTT broker, or a broker that sent something Signal Lab cannot read. |
… does not accept MQTT 3.1.1 clients | The broker only takes MQTT 5. |
… rejected the client ID — choose another one | The id is too long or has characters the broker does not accept. |
… rejected the username or password | Wrong credentials, or a password without a user name. |
… did not authorize this client — check its access rules | The broker's access rules refuse this client. |
… is unavailable right now — try again later | The broker is up but not taking clients. |
Enter a client ID — brokers refuse an empty one | Client id is empty. |
A publish topic cannot contain the wildcards + or # | The topic to publish to has a + or #. Those are for subscribing; publish to one topic at a time. |
| A filter shows refused | The broker's access rules forbid it, or the filter is malformed (# not last, + sharing a level with other characters). |
| The connection drops a moment after connecting | Another client connected with the same Client id. |
| Nothing appears in the tree | The scan filter is empty, or the broker lets this client see nothing. |
Every error message is listed in Error messages.