An MQTT sensor on a dashboard
This guide takes a sensor that publishes over MQTT from a Mosquitto broker to a tag and a screen. It is for the engineer who has a broker and wants the first topic in the gateway. The MQTT driver has run against Mosquitto; nothing else has been tried.
Prerequisites
-
A gateway with the MQTT driver module (
io.scadex.driver.mqtt) running; see Modules. -
A Mosquitto broker the gateway can reach, for example on
mqtt://broker:1883. A local one for trying things out:docker run -d --name mosquitto -p 1883:1883 eclipse-mosquitto:2 \sh -c "printf 'listener 1883\nallow_anonymous true\n' > /mosquitto/config/mosquitto.conf && /usr/sbin/mosquitto -c /mosquitto/config/mosquitto.conf" -
The
mosquitto_pubandmosquitto_subcommand line tools (packagemosquitto-clientson Debian and Ubuntu). -
The engineer role for the connection and tag, the operator role to write.
Steps
1. Add the broker
- Open Connections, then MQTT brokers.
- Press Add a broker. A panel opens beside the list.
- Fill in Name (
Plant_broker; letters, digits, dots, hyphens or underscores) and Address (mqtt://broker:1883; the address starts with its protocol). Leave Enabled on. - Under Sign-in, leave User name and Password empty if the broker lets anyone connect. Client ID is optional; left empty, the gateway picks one.
- Under Delivery, set Default QoS: At most once (0), At least once (1) or Exactly once (2). The gateway publishes with this QoS.
- Press Add broker.
The same over the API:
curl -b cookies.txt -H "Origin: https://app.scadex.io" -H "Content-Type: application/json" \
https://app.scadex.io/api/v1/modules/io.scadex.driver.mqtt/connections \
-d '{"name":"Plant_broker","enabled":true,"configuration":{"url":"mqtt://broker:1883","qos":"1"}}'
The configuration keys are url, username, password, clientId and qos. Test it with Test connection on the broker's detail page, or POST .../connections/<id>/test.
2. Publish something to subscribe to
From any machine that reaches the broker:
mosquitto_pub -h broker -t plant/line1/temperature -m 21.5 -r
-r asks the broker to retain the message, so a late subscriber gets the last value at once.
3. Find the topic and make it a tag
- Select the broker in the list and open its Browse tab (or press Browse topics on the empty tags tab).
- The browser lists topics the gateway has seen. Type a filter in Listen on, e.g. plant/# and confirm it to make the gateway subscribe to that filter while you browse;
plant/#covers everything underplant/. A pin marks a topic the broker retains; the row shows its last payload. - On
plant/line1/temperaturepress the Create a tag from ... action. A New tag panel opens, bound to the topic. - Give the tag its path (
Line1.Temperature), choose how the payload is read, and save.
The binding of an MQTT tag has two keys:
| Key | Values |
|---|---|
topic | The topic, or a filter with + or #. A tag on a filter receives every matching message and can't be written. |
payloadFormat | number, boolean, json, or left empty for text |
How a payload is decoded:
payloadFormat | Payload | Tag value |
|---|---|---|
number | 21.5 | 21.5. Anything that is not a finite number gives a bad quality with the reason '...' is not a number. |
boolean | true, 1, on, false, 0, off | true or false |
json | {"t":21.5,"h":40} | The parsed document as one JSON value. Read a field from it with a derived tag whose property is the field name (t), see Tags. |
| empty | anything | The text as it is |
Over the API:
curl -b cookies.txt -H "Origin: https://app.scadex.io" -H "Content-Type: application/json" \
https://app.scadex.io/api/v1/tags \
-d '{"path":"Line1.Temperature","kind":"external","producerModuleId":"io.scadex.driver.mqtt","producerInstanceId":"<connection id>","binding":{"topic":"plant/line1/temperature","payloadFormat":"number"},"engUnit":"°C"}'
4. See values arrive
Open Tags and types and select Line1.Temperature. Then publish a few values:
for v in 21.7 22.0 22.4 21.9; do mosquitto_pub -h broker -t plant/line1/temperature -m $v; sleep 2; done
Each one shows up with good quality and the time the gateway received it. Publish abc and the quality turns bad with 'abc' is not a number.; the next good value clears it.
The broker's detail page shows Tags subscribed, Topics seen and Last message in its Driver section, and the status tags are under @gateway.connection.mqtt.Plant_broker (state, connected, tags, error, since). Values are published to the tag runtime in batches, and a Dropped samples figure appears when values arrived faster than they could be stored.
5. Show it on a screen
- Open Screens, create a screen and open it in the designer (Designer).
- Add a widget that shows a value and bind it to
Line1.Temperature; the tag's unit and format come along. - Add a trend widget on the same tag for the last hour. A trend reads from the historian when the module runs, otherwise from what the event backbone retains (History and replay).
- Save and run the screen. Publish another value; the number and the trend move.
Widgets lists the widgets and what each one binds to.
6. Write back to the broker
A tag on an exact topic (no + or #) can be written. Writing publishes the value to that topic with the broker's Default QoS, not retained, as text: numbers with full precision, booleans as true/false, bytes as Base64. Watch it arrive:
mosquitto_sub -h broker -t 'plant/line1/#' -v
Then write the tag from the tag browser, from a screen widget that writes (a button or an input, see Widgets), over /sync with tag.write {path, value}, which is what the SDK's client.write sends (operator role; see Live data over /sync), or with POST /api/v1/runtime/tags/{id}/write (see Tags). A write is refused when the broker is not connected ("The MQTT broker for this tag is not connected."), when the tag is on a wildcard topic, or when the broker answers with a reason code ("The broker refused the write: ...").
Because the tag is also subscribed to the topic, the written value comes back from the broker and becomes the tag's value.
Where to go next
- The MQTT driver, for the module in full.
- Tags for derived tags that read one field of a JSON payload, scaling and deadband.
- Alarms, then Alarm to webhook on the temperature.
- Historian to keep the values longer than the backbone does.