Skip to content

Connecting devices (MQTT)

Devices talk to Celestian over MQTT. A device needs only an ID, a key, and a broker address.

Item Value
Broker <host>:1883 (MQTT 3.1.1) or <host>:1884 (MQTT 5). The ports may differ in your instance. When TLS is enabled, an MQTTS port (for example 8883) is also available for both versions.
Username The device ID (a UUID from the device page).
Password The device key (shown once when the device is created or its key regenerated).
Client ID In production it must start with the device ID, for example <id> or <id>-2. In development it is free.
Permissions The device needs a publish (send) and/or subscribe (receive) connection to the channel.
Storage The channel must have a storage rule if messages should be stored.

The Credentials tab on the device page generates all the examples below with the ID, topic, and broker already filled in.

m/<workspace>/c/<channel>[/<subtopic>]

<workspace> and <channel> can be a route or a UUID:

m/cold-storage/c/warehouse-telemetry
m/cold-storage/c/warehouse-telemetry/room-a1
m/cold-storage/c/warehouse-telemetry/floor2/room-b1/temperature
  • The sender’s identity is not in the topic. The broker records the authenticated device as the publisher, so it cannot be forged.
  • The subtopic is free-form, can be multi-level with /, and only acts as a label. Forbidden characters: *, >, spaces, and control characters.
  • The wildcards + (one level) and # (many levels) are for subscribe only.
  • The broker matches topics literally: a message to m/<uuid>/c/<uuid>/… does not reach a device subscribed to m/<route>/c/<route>/…. Use the same topic form on both sides.
Terminal window
DEV=<device-id>
mosquitto_pub -h <broker-address> -p 1883 -V mqttv311 -q 1 -i "$DEV" -u "$DEV" -P '<device-key>' \
-t 'm/cold-storage/c/warehouse-telemetry/room-a1' \
-m '[{"n":"temp_inlet","u":"Cel","v":22.4}]'

Give the device a subscribe connection to the channel, then subscribe:

Terminal window
mosquitto_sub -h <broker-address> -p 1883 -V mqttv311 -i "<device-id>-sub" -u "<device-id>" -P '<device-key>' \
-t 'm/cold-storage/c/warehouse-telemetry/#' -v

Commands can come from the API (messages/send), a Switch or Slider widget on a dashboard, the Messages page (Send message), or the Channel Publisher output of a rule.

Situation Result
A valid publish Connected and the message is received. Visible in Messages when a storage rule exists.
A wrong password, unknown device, or disabled device The connection is refused (bad user name or password).
A topic outside the permissions (another workspace or channel, or no publish connection) The broker drops the connection (the client sees connection lost), with no error message.
A client_id that does not start with the device ID Refused in production; accepted in development.
A disabled channel, device, or workspace Authentication or authorization is refused.

Online status, when the device last connected or disconnected, and Last Seen appear on the Devices page. Celestian records connections at authentication and disconnections through the broker webhook, plus periodic reconciliation to close gaps.

Symptom Common cause
Cannot connect A wrong username or password; a client ID that does not start with the device ID (production); a wrong broker or port.
Connected but messages do not appear in Messages There is no storage rule for that channel; the payload is not SenML/SenFlat while the rule uses the SenML output; check Rules → Executions.
The connection drops immediately on publish The device has no publish connection to that channel, or the topic is wrong.
It shows in Last Seen but is not stored The same as above: without a rule, messages are not stored.
The rule runs but rows are empty A SenML record without n or without a value is skipped.
The latest value or chart is empty A free-form JSON payload (not SenML or SenFlat).
quota.*_exceeded when creating a device or channel The workspace owner’s quota has been reached.

A quick test without a device: send one message with mosquitto_pub, then open Messages in Live mode, or use the simulator.