The year is 2040 and Amazon Alexas around the globe have risen to become our robot overlords. While that probably won’t be the case, many of us are choosing to bring automation into our lives and homes. Statisticians estimate that more than half of US households will have some type of “smart home” device by 2024. Privacy concerns aside, it’s hard to deny the convenience of being able to use your phone to switch your lights on, or change your thermostat from almost anywhere in the world. There’s a reason we don’t still turn dials on our televisions, and that reason is what fuels this trend for remote control over our household devices.

One of the most common applications of this remote control concept is the smart home light. Smart lighting comes in multiple flavors, but they all share one core feature: you need to be able to turn them on and off. Typically, users will interact with a mobile application that will have a way to tell the light what to do. A simplified flow for a user turning on a smart light might be the following:

  1. User presses a button in an app, which indicates the app should tell the light to turn “ON”

  2. The light turns on and tells the app that it is now “ON”

  3. The user can continue reading this article

Now, let’s imagine we have to build the communication channel between the app and the light. Ideally our light will be nice and small, which means we need to make efficient use of resources on our smart light device. Our device should communicate with our app using the minimum amount of network possible. Enter MQTT.

MQTT is a TCP/IP based, lightweight, publish/subscribe protocol designed specifically for communication with IoT devices like our smart light. There are two main actors in MQTT communication: the message broker, and the clients. The message broker is responsible for routing messages and managing client connections. Clients are the application components that connect to the broker in order to send and receive messages. In our example, we have two clients: the app and the light. The way clients exchange messages is through topics. Topics are namespaces which clients publish and subscribe to in order to communicate. The messages we’ll be sending on the topics will be simple JSON payloads.

At this point we should be able to start describing our communication flow in terms of MQTT concepts:

  1. The app client publishes a message to a topic with a payload telling the light to turn “ON”

  2. The light is subscribed to the topic in step 1, and receives the “ON” message

  3. The light turns on and publishes to a topic telling the app the command was a “SUCCESS”

  4. The app is subscribed to the topic in step 3, and receives the “SUCCESS” message

We know what we want to build, but we aren’t quite sure how to build it. Luckily, there are some best practices we can follow to actually implement our flow and bring our smart lighting solution to life. Let’s start with our topics.

  1. Topic names should be hierarchical in format, with different levels separated by a forward slash

  2. Topic names should move from generic to specific as you move from left to right in the topic name

  3. Always include a unique identifier for the client in your topic names

We need one topic for the app to publish commands, and another for the light to publish responses.

cmd/house/upstairs/light-1/mode will be our command topic. (We’ll assume our light is on the second floor or our house and has an id of “light-1”)

cmd/house/upstairs/light-1/mode/resp will be our command response topic.

Finally, we need to shape our messages. In order to uniquely identify our commands, we’ll give them arbitrary ids. We will also specify the response topic in the command payload to reduce the configuration required on any given device. The requested command action will be separated into a subsection of the payload to clearly differentiate it from our command metadata. Our command payload will look something like this:

{
Id”: “3c53387b-d96c-47bb-8bd3-c91016be783f,
RespTopic”: “cmd/house/upstairs/light-1/mode/resp,
Action”: {
       “Mode”:ON
   }
}

The device will respond with a simple payload of the following format:

{
Id”: “3c53387b-d96c-47bb-8bd3-c91016be783f,
Status”: “SUCCESS
}

Using unique identifiers for a command type pattern is useful for two reasons:

  1. Deduplication of messages – In some scenarios it’s possible for an MQTT message to be delivered more than once. A unique identifier makes it easy to ignore duplicate messages in both the app client and the device.

  2. Correlation – It’s extremely helpful to be able to correlate command issuance with responses. We want to be sure that we’re associating the correct response with any issued command.

With these simple basics, hopefully you will feel comfortable diving into the wonderful world of IoT. As always, if you’re interested in exciting problem spaces like IoT, reach out to the Nuvalence team!