Naming and Behavioral Conventions
Naming and Behavioral Conventions - A Scheme for IoT Devices, Topics, and Payloads
MQTT lets you do with it want you want. After implementing a few devices I felt I would like a bit more order in the zoo. Some problems or features are the same across devices, so why not handle them in a consistent way?
Every device needs to have a MQTT ID. It has a global status such as "connected" or "unresponsive". If it is connected via TCP, it will have an IP and, likely, MAC address. The installed software has a version.
This lead to the following topics:
- topic "<mqttID>/status": The status of the device. "connected" if it is connected and communicating, "unresponsive" (via last will message) if it is not
- topic "<mqttID>/version": The version of the specific devices.
- topic "<mqttID>/ip": The IP address, determined by the DHCP server of the WLAN network
- topic "<mqttID>/mac": The MAC address, determined by the WLAN chip
- topic "<mqttID>/iotVersion": The version of my Arduino IoT framework
Example! My balcony device with MQTT-ID "acbalcony" reports on connection:
- topic "acbalcony/status", payload "connected"
- topic "acbalcony/version", payload "1.021"
- topic "acbalcony/ip", payload "192.168.0.24"
- topic "acbalcony/mac", payload "ac:3f:35:bd:4f"
- topic "acbalcony/iotVersion", payload "1.005"
A monitor subscribing to "+/status" receives the status messages of all connected devices. Neat! The IP and mac address reported may help me to configure the WLAN router (in example, if I want to always assign the same IP address to the same, mac-identified, device).
Often, devices are composed of capabilities that can be reused across devices. I am thinking of sensors for measuring temperature, air pressure, brightness, humidity, soil moisture, acceleration, location, direction etc. These capabilities possibly have input and output parameters, and the software has its own version which is independent of the device framework.
When the connection is made, I am using the following topics:
- topic "<mqttID>/<capabilityID>/version, payload <versionNumber>
- topic "<mqttID>/capabilityID>/capa<n{2}>. The payload is a concise textual description of input and output topics.
During regular operations I use:
- topic "<mqttID>/<capabilityID>/<whatever!>: Depending on what the capability is able to do.
Example! The "power" capability of my power switch device number 3 supports the operation of one or more relays connected to digital ports. The reported capabilities when the connection is made are:
- topic "acpower03/power/capa01", payload ">power/0:[0|1]"
- topic "acpower03/power/capa02", payload "<power/out/0:[0|1]"
What does that mean? ">power/0:[0|1]": The capability reacts to messages specifying the number of the relay in the topic and "0" or "1" in the payload by turning relay 0 off or on (the mapping of relay numbers to digital ports is part of the configuration of the capability at compile time). "<power/out/0:[0|1]": The capability sends messages with the number of the relay in the topic and a payload of "0" or "1" to reflect the state of a relay. With that kind of feedback it is possible to determine whether the command was actually executed. It allows for reflecting state when a command has sent by somebody else. Capable MQTT clients do support this input/ output message scheme.
To switch on relay number 3, I send "acpower03/power/3", payload "1" and receive "acpower03/power/out/3", payload "1" soon thereafter. Or not, if something went wrong, but at least I know (yes, the reply could get lost as well).
Another example! The "BMP280" sensor (air pressure and temperature) capability of my balcony device reports on air pressure and temperature
When the connection is made it reports:
- topic "acbalcony"/bmp280/version", payload "1.008"
- topic "acbalcony"/bmp280/capa01", payload "<temperature:<n.m>"
- topic "acbalcony"/bmp280/capa02", payload "<pressure:<n.m>"
Every 60 seconds it sends sensor readings:
- topic "acbalcony"/bmp280/temperature", payload "24.5"
- topic "acbalcony"/bmp280/pressure", payload "100463.26
What if there is more that one device of the same class in the network, or more than one capability of the same kind on the device? Just give it a different name when you configure it, at compile time.