Enabling Data Exchange using MQTT

Your Smart Mailbox consists of a real IoT sensor (PIR motion); a script programmed to provide its status (along with context information) when motion is detected; and a data collection platform (OpenRemote), capable of managing IoT data. The Smart Mailbox asset in Open Remote, represents the digital representation of the physical mailing box.

While the asset exists, its attributes are static for the moment. A dynamic way of updating the attributes of the Smart Mailbox asset must be designed. This required leveraging data exchange protocols at the middleware/(session)-layer.

During this lab you will use the MQTT protocol to dynamically updating the attributes of your Smart Mailbox asset, based on the PIR motion status.

MQTT

MQTT (MQ Telemetry Transport) is the most commonly used messaging protocol for the Internet of Things (IoT). The protocol is a set of rules that defines how IoT devices can publish and subscribe to data over the Internet. MQTT is used for data exchange between IoT devices, such as embedded devices, sensors, etc. The protocol is event driven and connects devices using the publish /subscribe (Pub/Sub) pattern. The sender (Publisher) and the receiver (Subscriber) communicate via Topics and are decoupled from each other. The connection between them is handled by the MQTT broker. The MQTT broker filters all incoming messages and distributes them correctly to the Subscribers.

More details can be found at https://mqtt.org/.

Attributes of the Smart Mailbox asset

Before connecting your asset to your device, you have to make sure that attributes have been created. For example, the letter_count, new_mail attributes, etc.

You will use these attritutes later as subscribers to your IoT project.

Create a service user

The service user will give programmatic access to MQTT clients (publishers, subscribers).

In Open Remote:

  1. Go to the users page and create a new service user (second panel on the page)
  2. Name the service user mqttuser and give the user the read and write role for the sake of convenience. It is advised to configure a more restricted role for your service users.
  3. Click ‘Create’, a secret will be generated automatically.
  4. Open the ‘mqttuser’ user to see and copy the secret

Establish a connection from client to broker

Clients can be either publishers or subcribers. In your Raspberry Pi, the PIR motion sensor can act as publisher in order to update the corresponding attributes in the Smart Mailbox asset. Then, a subscriber can be created to monitor certain attributes in order to receive notifications if their values are chaning.

In your Raspberry Pi, use Python to create an MQTT client. Then, in your MQTT client set up a new connection using the Python Paho Client documentation.

The following parameters are necessary:

  • host: mqtt://localhost (or URL of your hosted environment e.g. demo.openremote.io)
  • Port: 8883 with TLS/SSL enabled; most clients will work with our self generated letsencrypt certificates, but if using a self signed certificate or your client isn’t able to validate the cert chain then you may need to explicitly load the cert into your client or disable/relax the client’s TLS verification settings (refer to your specific client’s documentation). It is possible to expose the broker un-encrypted on port 1883 by creating a port mapping for that on the manager service in your docker compose file
  • password: the secret generated for the mqtt service user (you can find it on the mqttuser users page)
  • username: master:mqttuser ({realm}:{user})
  • clientID: client123 (this can be anything you like but must be unique - Any existing connection with the same client ID will be replaced. Make sure this clientID remains identical.)

Subscribe to attributes using the MQTT API

There are many more options of subscribing to (all) updates of assets and attributes. The asset attributes that you will be subscribing to can be written by the user, by rules, or can be a live value gathered through a device in the field. You can imagine this boolean value could toggle a function of the device subscribed to the attribute.

  • Get the ID of the Thing asset by navigating to its asset page (Smart Mailbox asset) and copying the ID in the URL (e.g. http://localhost:9000/manager/#!assets/false/6xIa9MkpZuR7slaUGB6OTZ => 6xIa9MkpZuR7slaUGB6OTZ)
  • Create a subscription for the attribute of your choice in your MQTT client with the topic: {realm}/{clientId}/attribute/{attributeName}/{assetId}. E.g.,: master/client123/attribute/letter_count/6xIa9MkpZuR7slaUGB6OTZ.
  • In the view mode of the Smart Mailbox asset in the OpenRemote Manager, write a new value to the ‘Subscribe attribute’ by clicking the checkbox.
  • Verify that you see the value (true/false) coming in on your MQTT client!

Here is an example:

import paho.mqtt.client as mqtt
import ssl

# Define MQTT broker address and port
broker_address = "mqtt://localhost"
broker_port = 8883

# Define MQTT topic to subscribe to
topic = "master/client123/attribute/letter_count/6xIa9MkpZuR7slaUGB6OTZ"

# Define MQTT client ID and credentials
client_id = "client123"
username = "master:mqttuser"
password = "to_be_defined"

# Create a MQTT client instance
client = mqtt.Client(client_id=client_id)

# Define callback functions for connection and subscription
def on_connect(client, userdata, flags, rc):
    print("Connected to MQTT broker with result code " + str(rc))
    # Subscribe to the topic
    client.subscribe(topic)

def on_message(client, userdata, message):
    print("Received message on topic " + message.topic + ": " + str(message.payload))

# Assign callbacks and credentials to MQTT client instance
client.username_pw_set(username=username, password=password)
client.tls_set(cert_reqs=ssl.CERT_NONE)

client.on_connect = on_connect
client.on_message = on_message

# Connect to the MQTT broker and start the loop
client.connect(broker_address, broker_port)
client.loop_forever()

Refer to the wiki page for the definition of subscription schemes by OpenRemote.

Publish attribute values from the MQTT client

You can publish data from your MQTT client (device) to the OpenRemote manager so that you can monitor the device and create rules.

  1. Define the correct topic. For directly writing an attribute value: {realm}/{clientID}/writeattributevalue/{attributeName}/{assetID}. So in our case this will be master/client123/writeattributevalue/letter_count/6xIa9MkpZuR7slaUGB6OTZ
  2. Send the JSON over this topic. For a Number, this is really simple: 23
  3. Go to the Manager and check if the value updated!

Here is an example:

import paho.mqtt.client as mqtt
import ssl

# Define MQTT broker address and port
broker_address = "mqtt://localhost"
broker_port = 8883

# Define MQTT topic and message
topic = "master/client123/writeattributevalue/letter_count/6xIa9MkpZuR7slaUGB6OTZ"
message = 123  # Replace with the number you want to send

# Define MQTT client ID and credentials
client_id = "client123"
username = "master:mqttuser"  # Replace with your own username
password = "to_be_defined"  # Replace with your own password

# Create a MQTT client instance
client = mqtt.Client(client_id=client_id)

# Define callback functions for connection and publishing
def on_connect(client, userdata, flags, rc):
    print("Connected to MQTT broker with result code " + str(rc))

def on_publish(client, userdata, mid):
    print("Published message with ID " + str(mid))

# Assign callbacks and credentials to MQTT client instance
client.username_pw_set(username=username, password=password)
client.tls_set(cert_reqs=ssl.CERT_NONE)
client.on_connect = on_connect
client.on_publish = on_publish

# Connect to the MQTT broker
client.connect(broker_address, broker_port)

# Publish the message to the topic
mid = client.publish(topic, message)

# Wait for the message to be sent (in case of slow network)
mid.wait_for_publish()

# Disconnect from the MQTT broker
client.disconnect()

More details regarding this tutorial can be found at: https://github.com/openremote/openremote/wiki/Tutorial:-Connect-your-MQTT-Client.

Previous
Next