[MQTT / Python] Implemented a class that does MQTT Pub / Sub in Python

Introduction

I've tried using MQTT in Python / Java, so I'm posting it. I tried to do it when actually calling from another system This article corresponds to the following two. If you haven't done so already, please see 1 first.

  1. [MQTT] Introducing MQTT on a command basis (previous)
  2. [Python] Implemented a class that does MQTT Pub / Sub in Python (this article)
  3. [Java] Implemented a class that does MQTT Pub / Sub in Java (next time)
  4. [ROS] Implemented a node for MQTT communication (one after another)

Operating environment

Python 2.7 Python 3.7

Library, broker installation

This is from the previous article, so I'll write it for those who haven't installed it yet.

Library, broker installation
### 1. For windows Please download the installer according to your environment from "Binary Installation" ⇒ "Windows" on the following site. https://mosquitto.org/download/ ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426354/e6ec1314-653b-3dd2-31d7-dc1619f14f1f.png) ### 2. For Linux Execute the following two commands.
# Mosquitto(Broker)Install
$ sudo apt-get install mosquitto

#Install Mosquitto client
$ sudo apt-get install mosquitto-clients

Client library installation

It also describes how to install the Python and Java client libraries that will be used next time. Python Installation of library paho

$ pip install paho-mqtt

MQTT communication with Python

There is an Official Samples.

Publisher only has to go to the connection every time, so the following line is enough. If you want to do it continuously, loop the third line.

simplepub.py


import paho.mqtt.publish as publish

publish.single("Topic name", "Message content", hostname="hostname")

simplepub_loop.py


import paho.mqtt.publish as publish
import time
i = 0
while True:
    time.sleep(3)
    i += 1
    print(i)
    publish.single("testTopic2", i, hostname="localhost")

Subscriber sets the callback function and processes it. (This is also the same as ROS1)

simplesub.py


import paho.mqtt.subscribe as subscribe

topics = 'test'

def print_msg(client, userdata, message):
    print("%s : %s" % (message.topic, message.payload))

while True:
    subscribe.callback(print_msg, "test", hostname="localhost")

Run

Start the broker in the same way as previous article Then start the client.

$ cd C:\Program Files (x86)\mosquitto
$ mosquitto -v

Execute each of the following, and if the published message appears on the subscriber screen, it is successful.

$ python simple_sub.py
$ python simple_pub.py

Also, the MQTT client (paho.mqtt.client) has some default methods. There is also an implementation example that writes each method instead of just one line as described above. Send and receive MQTT with python Trying to understand MQTT library Paho Python

MQTT communication class

The above is an implementation example of both Pub / Sub alone, but ROS and OpenRTM etc. , I wanted to call it from a system running separately, so I have put them together in a class so that they can be easily read as a self-made module.

The following is the class. It inherits mqtt.Client. For reference, see client_sub-class.py of Official GitHub. blob / master / examples / client_sub-class.py).

MQTTClient.py


import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
import time

class MyMQTTClass(mqtt.Client):
    def __init__(self):
        super().__init__()
        self.recieve_data = ""
        self.recieve_time = ""
        self.lasttime     = ""

    def on_connect(self, mqttc, obj, flags, rc):
        print("rc: "+str(rc))

    def on_message(self, mqttc, obj, msg):
        print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))
        self.recieve_time = time.time()
        self.recieve_data = (msg.payload).decode()

    def run(self, hostname, topic):
        self.connect(hostname, 1883, 60)
        self.subscribe(topic, 0)

        self.loop_start()
        
        rc = 0

        return rc

    def publish_message(self, host_name, topic, message):
        publish.single(topic, message, hostname=host_name)

    def isNew(self):
        flag = False
        if self.lasttime==self.recieve_time: flag =  False
        else: flag = True
        self.lasttime = self.recieve_time
        return flag

# If you want to use a specific client id, use
# mqttc = MyMQTTClass("client-id")
# but note that the client id must be unique on the broker. Leaving the client
# id parameter empty will generate a random id for you.
mqttc = MyMQTTClass()
rc = mqttc.run("localhost","testTopic1")

print("rc: "+str(rc))

i=0
while(1):
    i+=1
    print(i)
    mqttc.publish_message("localhost", "testTopic2",i)
    
    if mqttc.isNew(): print(mqttc.recieve_data)

The role of each method is as follows.

Method name role
on_connect Method called when connecting to the broker
on_message Method called when receiving a message(recieve_Substitute the received message for data)
run Start a loop of subscriber, a method called from the outside
publish_message Method to publish message, abovesimplepub.pyAs it is
isNew A method to determine if the received message is new

Actually, there is a publish () method in the parent class, but I thought that it could only be done by the host when connect () was done, and I wanted to put it in one class, so in this way I implemented it. There seems to be another way.

Example of use

The implementation example using the class call is as follows. Place the file in the same directory as MQTTClient.py.

sample_mqtt_lient.py


import MQTTClient

mqttc = MQTTClient.MyMQTTClass()
mqttc.run("hostname","Topic name")

#Publish only once
mqttc.publish_message("hostname", "Topic name","message")

if(mqttc.isNew()):
    print(mqttc.receive_data)

Start Subscribe with mqttc.run () and publish the message only once with mqttc.publish_message (). Also, the variable subscribed to recieve_data is entered. Since it is judged by the mqttc.isNew () function whether it was subscribed, use it as a set as described above. (It is the same as Open RTM)

mqttc = MQTTClient.MyMQTTClass()
mqttc.run("hostname","Topic name")

The top two lines are the places where it is executed once, and the following three lines are the images to put in the main loop.

#Publish only once
mqttc.publish_message("hostname", "Topic name","message")

if(mqttc.isNew()):
    print(mqttc.receive_data)

in conclusion

I implemented a class that can perform MQTT communication with Python. When I tried using it with ROS, it worked well, so I think I was able to achieve my goal.

Recommended Posts

[MQTT / Python] Implemented a class that does MQTT Pub / Sub in Python
A simple Pub / Sub program note in Python
A class that summarizes frequently used methods in twitter api (python)
Generate a first class collection in Python
A simple HTTP client implemented in Python
Generate a class from a string in Python
A memo that I wrote a quicksort in Python
[Python / Tkinter] A class that creates a scrollable Frame
I wrote a class in Python3 and Java
A program that removes duplicate statements in Python
Python: Create a class that supports unpacked assignment
I tried to create a class that can easily serialize Json in Python
case class in python
Implemented SimRank in Python
Class notation in Python
Implemented Shiritori in Python
Key input that does not wait for key input in Python
What's in that variable (when running a Python script)
In Python, create a decorator that dynamically accepts arguments Create a decorator
I implemented a Vim-like replacement command in Slackbot #Python
MALSS, a tool that supports machine learning in Python
What does the last () in a function mean in Python?
Take a screenshot in Python
A Python program in "A book that gently teaches difficult programming"
A general-purpose program that formats Linux command strings in python
Create a function in Python
Create a dictionary in Python
A function that divides iterable into N pieces in Python
Loop through a generator that returns a date iterator in Python
How to use the __call__ method in a Python class
Let's create a script that registers with Ideone.com in Python.
I tried "a program that removes duplicate statements in Python"
Make a bookmarklet in Python
Create code that outputs "A and pretending B" in python
I created a class in Python and tried duck typing
Sudoku solver implemented in Python 3
Draw a heart in Python
A set of script files that do wordcloud in Python3
6 Ball puzzle implemented in python
Create an instance of a predefined class from a string in Python
Play a sound in Python assuming that the keyboard is a piano keyboard
A memo that handles double-byte double quotes in Python regular expressions
Use networkx, a library that handles graphs in python (Part 2: Tutorial)
Easy! Implement a Twitter bot that runs on Heroku in Python
[Python / Django] Create a web API that responds in JSON format
A record that GAMEBOY could not be done in Python. (PYBOY)
About psd-tools, a library that can process psd files in Python
A function that measures the processing time of a method in python
A program that determines whether a number entered in Python is a prime number
A special Python codec that seems to know but does not know
What's new in datetime that is a bit more useful in Python 3
[python] I made a class that can write a file tree quickly
Maybe in a python (original title: Maybe in Python)
Write a binary search in Python
How to write a Python class
[python] Manage functions in a list
Hit a command in Python (Windows)
Implemented image segmentation in python (Union-Find)
Landmines hidden in Python class variables
Create a DI Container in Python
Draw a scatterplot matrix in python