What a sensor actually sends
MQTT (Message Queuing Telemetry Transport) is a small messaging protocol that lets sensors send readings to a central program. Every reading is a short message made of two parts, a topic and a payload. Once you can read those two parts, you can read any sensor on the network.
A smart thermostat, a door sensor and a soil probe all send their readings this way.
By the end of this lesson
Note
I can read sensor data from messages.
Key words
| Word | What it means | Example |
|---|---|---|
| Sensor | a device that measures something and reports it | |
| Message | one short piece of data sent over the network | |
| Topic | the label on a message, written like a path | home/door/state |
| Payload | the data inside a message | 22 |
| Broker | the middle-man that receives every message and passes it on | |
| Retained message | the last message on a topic, kept for late arrivals |
The cells students fill in are left blank in this preview.
What this lab leaves out
Important
The lab has a broker and four pretend sensors, in one copy only you can reach. Real devices connect over a network with a name and a password, and the connection is encrypted. The lab leaves all of that out, so the broker lets anyone inside it read and write.
A message is a topic and a payload
A sensor does not send its reading to a person. It sends a message to the broker, and the broker passes it on to every program that asked for it.
The message has a topic, which says what it is about, and a payload, which is the reading. When the tools print one line, they print the topic, a space, then the payload.
Worked example: one line, taken apart
| Part | Value | What it tells you |
|---|---|---|
| Whole line | home/livingroom/temperature 22 | One message |
| Topic | home/livingroom/temperature | Where it came from and what it measures |
| Topic levels | home, livingroom, temperature | Separated by slashes, like folders |
| Payload | 22 | The reading |
The cells students fill in are left blank in this preview.
Listen to every topic under home
docker exec broker mosquitto_sub -t 'home/#' -v -C 8 -W 10Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
What the lines look like
The option -t names the topic to listen to, and home/# means everything below home. The option -v prints the topic before each payload. -C 8 stops after 8 messages and -W 10 after 10 seconds, so it always ends.
You will see lines for four topics. The two temperatures and the humidity are whole numbers. The door state is open or closed. The exact numbers depend on when you press Run, so yours will differ.
Some messages are kept by the broker
A sensor that only reports a change, such as a door, could leave a new listener with no idea what the state is now. So some sensors mark a message retained. The broker keeps the last one and hands it to anyone who starts listening.
That is why the first lines of the last command arrive at once. In this lab the kitchen temperature and the door state are retained.
Print only the topic and the value
docker exec broker mosquitto_sub -t 'home/+/temperature' -F '%t is %p' -C 2 -W 10Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
You can choose how a line is printed
The option -F sets the format. %t stands for the topic and %p for the payload. The + in the topic matches exactly one level, so this listens to the temperature in any room.
You get two lines of the form "a topic, the word is, a whole number". Which rooms come first depends on the moment.
A common mistake
Warning
Many people think a payload that looks like 22 is a number. It is text. A program receives the two characters "2" and "2". Join "22" and "1" and you get "221", not 23. Turn the text into a whole number first, and only when you know it is one.
Take a line apart
line = "home/livingroom/humidity 41"
parts = line.split(" ") # the topic and the payload
levels = parts[0].split("/") # home, livingroom, humidity
value = parts[1]
if value.isdigit(): # only digits can become a number
value = int(value)
# Change the line at the top to a door message, then press Run.
print(levels[1], levels[2], value)