MQTT working example

For a working example, Google Cloud Platform (GCP) will be used as the MQTT receiver and ingestor into their cloud. Most MQTT cloud services follow a similar model, so this framework can be used as a reference. We will use open source tools to start an MQTT client and a simple Python example to publish a hello world string to a topics branch. Preliminary steps are needed to start using GCP. Google accounts and payment systems need to be secured before proceeding. Please refer to these instructions regarding getting started with  Google IoT Core https://cloud.google.com/iot/docs/how-tos/getting-started.

Proceed within GCP to create a device, enable the Google API, create a topics branch, and add a member to the pub/sub publisher.  

Google is unique in that it requires strong encryption (TLS) on top of MQTT to encrypt all data packets using JSON Web Tokens (JWT) and a certificate agent. Each device will create a public/private key pair. Google ensures each device has a unique ID and key; in the event one is compromised, it will only affect a single node and contain the surface area of an attack.

The MQTT broker starts by importing several libraries. The paho.mqtt.client Python library is an Eclipse-sponsored project and is the referenced home of the original IBM MQTT project. Paho is also the core deliverable of the Eclipse M2M Industry Working Group. There are other variants of MQTT message brokers, such as the Eclipse Mosquitto project and Rabbit MQ:

#Simple MQTT Client publishing example for Google Cloud Platform
import datetime
import os
import time
import paho.mqtt.client as mqtt
import jwt

project_id = 'name_of_your_project'
cloud_region = 'us-central1'
registry_id = 'name_of_your_registry'
device_id = 'name_of_your_device'
algorithm = 'RS256'
mqtt_hostname = 'mqtt.googleapis.com'
mqtt_port = 8883
ca_certs_name = 'roots.pem'
private_key_file = '/Users/joeuser/mqtt/rsa_private.pem'


The next step is authentication with Google through the use of a key. Here we use a JWT object to contain the certificate:

#Google requires certificate based authentication using JSON Web Tokens (JWT) per device.
#This limits surface area of attacks
def create_jwt(project_id, private_key_file, algorithm):
token = {
# The time that the token was issued
'iat': datetime.datetime.utcnow(),
# The time the token expires.
'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=60),
# Audience field = project_id
'aud': project_id
}

# Read the private key file.
with open(private_key_file, 'r') as f:
private_key = f.read()
return jwt.encode(token, private_key, algorithm=algorithm)

We define several callbacks using the MQTT library such as errors, connections, disconnects, and publishing:

#Typical MQTT callbacks
def error_str(rc):
return '{}: {}'.format(rc, mqtt.error_string(rc))

def on_connect(unused_client, unused_userdata, unused_flags, rc):
print('on_connect', error_str(rc))

def on_disconnect(unused_client, unused_userdata, rc):
print('on_disconnect', error_str(rc))

def on_publish(unused_client, unused_userdata, unused_mid):
print('on_publish')

The main structure of an MQTT client follows. First, we register the client as Google prescribes. Google IoT requires a project to be identified, a region, a registry ID, and a device ID. We also skip the username and use the password field via the create_jwt method. This is also where we enable SSL encryption in MQTT—many MQTT cloud providers require this provision. After connecting to Google's cloud MQTT server, the program's main loop publishes a simple hello world string to a topics branch which is subscribed to. Also of note is the QoS level that is set in the publish message.

If a parameter is required but not explicitly set in the program, the client library is obligated to use default values (for example, the RETAIN and DUP flags used as default values during the PUBLISH message):

def main():
client = mqtt.Client(
client_id=('projects/{}/locations/{}/registries/{}/devices/{}'
.format(
project_id,
cloud_region,
registry_id,
device_id))) #Google requires this format explicitly

client.username_pw_set(
username='unused', #Google ignores the user name.
password=create_jwt( #Google needs the JWT for authorization
project_id, private_key_file, algorithm))

# Enable SSL/TLS support.
client.tls_set(ca_certs=ca_certs_name)

#callback unused in this example:
client.on_connect = on_connect
client.on_publish = on_publish
client.on_disconnect = on_disconnect

# Connect to the Google pub/sub
client.connect(mqtt_hostname, mqtt_port)

# Loop
client.loop_start()

# Publish to the events or state topic based on the flag.
sub_topic = 'events'
mqtt_topic = '/devices/{}/{}'.format(device_id, sub_topic)

# Publish num_messages mesages to the MQTT bridge once per second.

for i in range(1,10):
payload = 'Hello World!: {}'.format(i)
print('Publishing message'{}''.format(payload))
client.publish(mqtt_topic, payload, qos=1)

time.sleep(1)


if __name__ == '__main__':
main()
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset