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.
Python 2.7 Python 3.7
This is from the previous article, so I'll write it for those who haven't installed it yet.
# Mosquitto(Broker)Install
$ sudo apt-get install mosquitto
#Install Mosquitto client
$ sudo apt-get install mosquitto-clients
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
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")
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
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)
super () .__ init __ ()
part is changed to super (MyMQTTClient, self) .__ init () __
.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.py As 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.
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)
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