Publishing data retrieved from sensors to the cloud-based MQTT server

If we display the status of the surfer and his surfboard with numbers, it will be difficult to understand the real status. So, we will have to map the integer that represents the status into a string that explains the status.

Now, we will create a new Python file named surfboard_status.py in the main virtual environment folder. The following lines show the code for this file, which defines constants for the different status numbers and a dictionary that maps these constants with integers to strings with the descriptions for the status. The code file for the sample is included in the mqtt_python_gaston_hillar_06_01 folder, in the surfboard_status.py file:

SURFBOARD_STATUS_IDLE = 0 
SURFBOARD_STATUS_PADDLING = 1 
SURFBOARD_STATUS_RIDING = 2 
SURFBOARD_STATUS_RIDE_FINISHED = 3 
SURFBOARD_STATUS_WIPED_OUT = 4 
 
SURFBOARD_STATUS_DICTIONARY = { 
    SURFBOARD_STATUS_IDLE: 'Idle', 
    SURFBOARD_STATUS_PADDLING: 'Paddling', 
    SURFBOARD_STATUS_RIDING: 'Riding', 
    SURFBOARD_STATUS_RIDE_FINISHED: 'Ride finished', 
    SURFBOARD_STATUS_WIPED_OUT: 'Wiped out', 
    } 

Now, we will write the code for the surfboard monitor. We will split the code into many code snippets to make it easier to understand each code section. Create a new Python file named surfboard_monitor.py in the main virtual environment folder. The following lines declare all the necessary imports and the variables that we will use to establish a connection with the PubNub MQTT interface. Don't forget to replace the strings assigned to the pubnub_publish_key and pubnub_subscribe_key variables with the values you have retrieved from the previously explained PubNub key generation process. The code file for the sample is included in the mqtt_python_gaston_hillar_06_01 folder, in the surfboard_monitor.py file:

from config import * 
from surfboard_status import * 
from surfboard_config import * 
import paho.mqtt.client as mqtt 
import time 
import json 
 
 
# Publish key is the one that usually starts with the "pub-c-" prefix 
# Do not forget to replace the string with your publish key 
pubnub_publish_key = "pub-c-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 
# Subscribe key is the one that usually starts with the "sub-c" prefix 
# Do not forget to replace the string with your subscribe key 
pubnub_subscribe_key = "sub-c-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 
pubnub_mqtt_server_host = "mqtt.pndsn.com" 
pubnub_mqtt_server_port = 1883 
pubnub_mqtt_keepalive = 60 
device_id = surfboard_name 
pubnub_topic = surfboard_name 

The first lines import the variables we have declared in the config.py file and in the previously coded surfboard_config.py and surfboard_status.py files. Then, the code declares the following variables that we will use to establish a connection with the PubNub MQTT interface:

  • pubnub_publish_key: This string specifies the PubNub publish key.
  • pubnub_subscribe_key: This string specifies the PubNub subscribe key.
  • pubnub_mqtt_server_host: This string specifies the PubNub MQTT server address. In order to use the PubNub MQTT interface, we must always establish a connection with the mqtt.pndsn.com host.
  • pubnub_mqtt_server_port: This number specifies the PubNub MQTT server port. In this case, we will establish an unsecured connection with the PubNub MQTT server, and therefore we will use port number 1883. We want to keep the PubNub MQTT interface configuration simple for this example, and therefore we won't use TLS.
  • pubnub_mqtt_keepalive: This number specifies the keep alive interval configuration for the connection with the PubNub MQTT interface.
  • device_id: This string specifies the device identifier we want to use when we create an instance of the Surfboard class. The code assigns the surfboard_name value imported from the surfboard_config.py file. We will analyze the code for this class later.
  • Pubnub_topic: This string specifies the topic to which the surfboard monitor will publish the JSON payload with the key-value pairs that specify the status for the surfer and their surfboard. The code assigns the surfboard_name value imported from the surfboard_config.py file.
The surfboard monitor will establish a connection to the mqtt.pndsn.com host on port 1883. So, we have to make sure that our firewall configuration has the appropriate inbound and outbound rules configurations to allow a connection on the specified port.

Add the following lines to the existing surfboard_monitor.py in the main virtual environment folder. The following lines declare the Surfboard class. The code file for the sample is included in the mqtt_python_gaston_hillar_06_01 folder, in the surfboard_monitor.py file:

class Surfboard: 
    active_instance = None 
    def __init__(self, device_id, status,  
        speed_mph, altitude_feet, water_temperature_f): 
        self.device_id = device_id 
        self.status = status 
        self.speed_mph = speed_mph 
        self.altitude_feet = altitude_feet 
        self.water_temperature_f = water_temperature_f 
        self.is_pubnub_connected = False 
        Surfboard.active_instance = self 
 
    def build_json_message(self): 
        # Build a message with the status for the surfboard 
        message = { 
            "Status": SURFBOARD_STATUS_DICTIONARY[self.status], 
            "Speed MPH": self.speed_mph, 
            "Altitude Feet": self.altitude_feet, 
            "Water Temperature F": self.water_temperature_f,  
        } 
        json_message = json.dumps(message) 
        return json_message

We have to specify a device_id and the initial values for the data that the sensors provide in the device_id, status, speed_mph, altitude_feet, and water_temperature_f required arguments. The constructor, that is, the __init__ method, saves the received values in attributes with the same names.

The code also saves a reference to this instance in the active_instance class attribute because we have to access the instance in many functions that we will specify as callbacks for the different events that two MQTT clients will fire: the PubNub MQTT client and the Mosquitto MQTT client. We will access the active instance with the Surfboard.active_instance class attribute after the code creates a Surfboard instance.

The class declares the build_json_message method, which builds a message with the status for the surfboard and returns the JSON string with the key-value pairs that composes the status message. The code maps the number stored in the status attribute into the string that explains the status by using the SURFBOARD_STATUS_DICTIONARY declared in the surfboard_status.py file. The code uses the speed_mph, altitude_feet, and water_temperature_f attributes to provide the values for the other keys.

Add the following lines to the existing surfboard_monitor.py in the main virtual environment folder. The following lines declare the functions that we will use as callbacks and other functions that will be called by these callbacks. The code file for the sample is included in the mqtt_python_gaston_hillar_06_01 folder, in the surfboard_monitor.py file:

def on_connect_mosquitto(client, userdata, flags, rc): 
    print("Result from Mosquitto connect: {}".format( 
        mqtt.connack_string(rc))) 
    # Check whether the result form connect is the CONNACK_ACCEPTED connack code 
    if rc == mqtt.CONNACK_ACCEPTED: 
        # Subscribe to a topic filter that provides all the sensors 
        sensors_topic_filter = topic_format.format( 
            surfboard_name, 
            "+") 
        client.subscribe(sensors_topic_filter, qos=0) 
 
 
def on_subscribe_mosquitto(client, userdata, mid, granted_qos): 
    print("I've subscribed with QoS: {}".format( 
        granted_qos[0])) 
 
 
def print_received_message_mosquitto(msg): 
    print("Message received. Topic: {}. Payload: {}".format( 
        msg.topic,  
        str(msg.payload))) 
 
 
def on_status_message_mosquitto(client, userdata, msg): 
    print_received_message_mosquitto(msg) 
    Surfboard.active_instance.status = int(msg.payload) 
 
 
def on_speed_mph_message_mosquitto(client, userdata, msg): 
    print_received_message_mosquitto(msg) 
    Surfboard.active_instance.speed_mph = float(msg.payload) 
 
 
def on_altitude_feet_message_mosquitto(client, userdata, msg): 
    print_received_message_mosquitto(msg) 
    Surfboard.active_instance.altitude_feet = float(msg.payload) 
 
 
def on_water_temperature_f_message_mosquitto(client, userdata, msg): 
    print_received_message_mosquitto(msg) 
    Surfboard.active_instance.water_temperature_f = float(msg.payload) 
 
 
def on_connect_pubnub(client, userdata, flags, rc): 
    print("Result from PubNub connect: {}".format( 
        mqtt.connack_string(rc))) 
    # Check whether the result form connect is the CONNACK_ACCEPTED connack code 
    if rc == mqtt.CONNACK_ACCEPTED: 
        Surfboard.active_instance.is_pubnub_connected = True 
 
 
def on_disconnect_pubnub(client, userdata, rc): 
    Surfboard.active_instance.is_pubnub_connected = False 
    print("Disconnected from PubNub")

The code declares the following functions that end with the mosquitto prefix:

  • on_connect_mosquitto: This function is the callback that will be executed once a successful connection has been established with the Mosquitto MQTT server. The code checks the value of the rc argument that provides the CONNACK code returned by the Mosquitto MQTT server. If this value matches mqtt.CONNACK_ACCEPTED, it means that the Mosquitto MQTT server accepted the connection request, and therefore the code calls the client.subscribe method for the MQTT client received in the client argument to subscribe to the surfboards/surfboard01/+ topic filter with a QoS level of 0. This way, the MQTT client will receive the messages sent to the surfboards/surfboard01/status, surfboards/surfboard01/speedmph, surfboards/surfboard01/altitudefeet, and surfboards/surfboard01/temperaturef topics with the values retrieved from the different sensors.
  • on_subscribe_mosquitto: This function will be called when the subscription to the surfboards/surfboard01/+ topic filter has been successfully completed. As in previous examples, the function prints a message indicating the QoS level granted to the subscription.
  • print_received_message_mosquitto: This function receives an mqtt.MQTTMessage instance in the msg argument and prints the topic and the payload of this message to help us understand what is happening in the application.
  • on_status_message_mosquitto: This function will be called when a message to the surfboards/surfboard01/status topic arrives from the Mosquitto MQTT server. The function calls the print_received_message_mosquitto function with the received mqtt.MQTTMessage instance as an argument and sets the value of the status attribute of the Surfboard active instance to the conversion of the received message's payload to an int.
  • on_speed_mph_message_mosquitto: This function will be called when a message to the surfboards/surfboard01/speedmph topic arrives from the Mosquitto MQTT server. The function calls the print_received_message_mosquitto function with the received mqtt.MQTTMessage instance as an argument and sets the value of the speed_mph attribute of the Surfboard active instance to the conversion of the received message's payload to a float.
  • on_altitude_feet_message_mosquitto: This function will be called when a message to the surfboards/surfboard01/altitudefeet topic arrives from the Mosquitto MQTT server. The function calls the print_received_message_mosquitto function with the received mqtt.MQTTMessage instance as an argument and sets the value of the altitude_feet attribute of the Surfboard active instance to the conversion of the received message's payload to an int.
  • on_water_temperature_f_message_mosquitto: This function will be called when a message to the surfboards/surfboard01/watertemperaturef topic arrives from the Mosquitto MQTT server. The function calls the print_received_message_mosquitto function with the received mqtt.MQTTMessage instance as an argument and sets the value of the water_temperature_f attribute of the Surfboard active instance to the conversion of the received message's payload to an int.
In this case, we don't have a single function that works as a callback to process all the incoming messages from the Mosquitto MQTT server. We work with a callback for each specific topic. This way, we don't have to check the topic for the message to determine the code that we have to run.

The code declares the following functions that end with the pubnub prefix:

  • on_connect_pubnub: This function is the callback that will be executed once a successful connection has been established with the PubNub MQTT server. The code checks the value of the rc argument that provides the CONNACK code returned by the PubNub MQTT server. If this value matches mqtt.CONNACK_ACCEPTED, it means that the PubNub MQTT server accepted the connection request, and therefore the code sets the value of the is_pubnub_connected attribute of the Surfboard active instance to True.
  • on_disconnect_pubnub: This function is the callback that will be executed if the client that was connected to the PubNub MQTT server loses the connection. The code sets the value of the is_pubnub_connected attribute of the Surfboard active instance to False and prints a message.
..................Content has been hidden....................

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