[MQTT / Python] Implémentation d'une classe qui fait Pub / Sub de MQTT en Python

introduction

J'ai essayé d'utiliser MQTT avec Python / Java, donc je le poste. J'ai essayé de le faire en appelant d'un autre système Cet article correspond aux deux suivants. Si vous ne l'avez pas déjà fait, veuillez d'abord voir 1.

  1. [MQTT] Présentation de MQTT sur une base de commande (précédent)
  2. [Python] Implémentation d'une classe qui fait Pub / Sub de MQTT en Python (cet article)
  3. [Java] Implémentation d'une classe qui fait Pub / Sub de MQTT en Java (la prochaine fois)
  4. [ROS] Implémentation d'un nœud pour la communication MQTT (l'un après l'autre)

Environnement d'exploitation

Python 2.7 Python 3.7

Bibliothèque, installation de courtier

Ceci est tiré de l'article précédent, je vais donc l'écrire pour ceux qui ne l'ont pas encore installé.

Bibliothèque, installation du courtier
### 1. Pour Windows Veuillez télécharger le programme d'installation en fonction de votre environnement à partir de «Installation binaire» ⇒ «Windows» sur le site suivant. 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. Pour Linux Exécutez les deux commandes suivantes.
# Mosquitto(Broker)Installer
$ sudo apt-get install mosquitto

#Installer le client Mosquitto
$ sudo apt-get install mosquitto-clients

Installation de la bibliothèque cliente

Je décrirai également comment installer les bibliothèques clientes Python et Java qui seront utilisées la prochaine fois. Python Installation de la bibliothèque paho

$ pip install paho-mqtt

Communication MQTT avec Python

Il existe un échantillon officiel.

Publisher n'a qu'à accéder à la connexion à chaque fois, la ligne suivante suffit donc. Si vous voulez le faire en continu, bouclez la troisième ligne.

simplepub.py


import paho.mqtt.publish as publish

publish.single("Nom du sujet", "Contenu du message", hostname="nom d'hôte")

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")

L'abonné définit la fonction de rappel et effectue le traitement. (C'est aussi la même chose que 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")

Courir

Démarrez le courtier de la même manière que Article précédent Puis démarrez le client.

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

Exécutez chacune des opérations suivantes et si le message publié apparaît sur l'écran de l'abonné, il réussit.

$ python simple_sub.py
$ python simple_pub.py

De plus, le client MQTT (paho.mqtt.client) a des méthodes par défaut. Il existe également un exemple d'implémentation qui écrit chaque méthode au lieu d'une seule ligne comme décrit ci-dessus. Envoyer et recevoir MQTT avec python Essayer de comprendre la bibliothèque MQTT Paho Python

Classe de communication MQTT

Ce qui précède est un exemple d'implémentation de Pub / Sub seul, mais ROS et OpenRTM etc. , Je voulais l'appeler à partir d'un système fonctionnant séparément, donc Je les ai rassemblés dans une classe afin qu'ils puissent être facilement lus comme des modules auto-créés.

Ce qui suit est la classe. Il hérite de mqtt.Client. Pour référence, consultez client_sub-class.py de 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)

Le rôle de chaque méthode est le suivant.

Nom de la méthode rôle
on_connect Méthode appelée lors de la connexion au courtier
on_message Méthode appelée lors de la réception d'un message(recieve_Remplacez le message reçu par des données)
run Démarrer une boucle d'abonné, une méthode appelée de l'extérieur
publish_message Méthode de publication du message, ci-dessussimplepub.pyTel quel
isNew Une méthode pour déterminer si le message reçu est nouveau

En fait, il y a une méthode publish () dans la classe parent, mais je pensais que cela ne pouvait être fait par l'hôte que lorsque connect () était fait, et je voulais le mettre dans une classe, donc de cette façon Je l'ai implémenté. Il semble y avoir un autre moyen.

Exemple d'utilisation

Voici un exemple d'implémentation utilisant un appel de classe. Placez le fichier dans le même répertoire que MQTTClient.py.

sample_mqtt_lient.py


import MQTTClient

mqttc = MQTTClient.MyMQTTClass()
mqttc.run("nom d'hôte","Nom du sujet")

#Publier une seule fois
mqttc.publish_message("nom d'hôte", "Nom du sujet","message")

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

Démarrez Subscribe avec mqttc.run () et publiez le message une seule fois avec mqttc.publish_message (). De plus, la variable souscrite à recieve_data est saisie. Puisqu'il est jugé par la fonction mqttc.isNew () s'il a été abonné, utilisez-le comme un ensemble comme décrit ci-dessus. (Identique à Open RTM)

mqttc = MQTTClient.MyMQTTClass()
mqttc.run("nom d'hôte","Nom du sujet")

Les deux lignes du haut sont les endroits où elles sont exécutées une fois, et les trois lignes suivantes sont les images à mettre dans la boucle principale.

#Publier une seule fois
mqttc.publish_message("nom d'hôte", "Nom du sujet","message")

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

en conclusion

J'ai implémenté une classe qui permet la communication MQTT avec Python. Quand j'ai essayé de l'utiliser avec ROS, cela a bien fonctionné, donc je pense que j'ai pu atteindre mon objectif.

Recommended Posts

[MQTT / Python] Implémentation d'une classe qui fait Pub / Sub de MQTT en Python
Notes de programme simples Pub / Sub en Python
Une classe qui résume les méthodes fréquemment utilisées dans l'api twitter (python)
Générer une collection de première classe en Python
Un client HTTP simple implémenté en Python
Générer une classe à partir d'une chaîne en Python
Un mémo que j'ai écrit un tri rapide en Python
[Python / Tkinter] Une classe qui crée un cadre défilable
J'ai écrit une classe en Python3 et Java
Un programme qui supprime les instructions en double en Python
Python: créer une classe qui prend en charge l'affectation décompressée
J'ai essayé de créer une classe qui peut facilement sérialiser Json en Python
classe de cas en python
Implémentation de SimRank en Python
Notation de classe en Python
Implémentation de Shiritori en Python
Entrée clé qui n'attend pas l'entrée clé en Python
Que contient cette variable (lorsque le script Python est en cours d'exécution)
En Python, créez un décorateur qui accepte dynamiquement les arguments Créer un décorateur
J'ai implémenté une commande de remplacement de type Vim dans Slackbot #Python
MALSS (introduction), un outil qui prend en charge l'apprentissage automatique en Python
Que signifie le dernier () dans une fonction en Python?
Prendre une capture d'écran en Python
Programme Python du "Livre qui enseigne facilement la programmation difficile"
Un programme polyvalent qui formate les chaînes de commande Linux avec python
Créer une fonction en Python
Créer un dictionnaire en Python
Une fonction qui divise l'itérable en N morceaux en Python
Boucle sur un générateur qui renvoie un itérateur de date en Python
Comment utiliser la méthode __call__ dans la classe Python
Créons un script qui s'enregistre avec Ideone.com en Python.
J'ai essayé "un programme qui supprime les déclarations en double en Python"
Créer un bookmarklet en Python
Créez le code qui renvoie "A et prétendant B" en python
J'ai créé une classe en Python et essayé de taper du canard
Implémentation de Supreme Solver dans Python 3
Dessinez un cœur en Python
Un ensemble de fichiers de script qui font wordcloud avec Python3
Créer une instance d'une classe prédéfinie à partir d'une chaîne en Python
Jouez des sons en Python en supposant que le clavier est un clavier de piano
Un mémo qui gère les guillemets doubles pleine largeur avec les expressions régulières Python
Utilisez networkx, une bibliothèque qui gère les graphiques en python (Partie 2: Tutoriel)
Facile! Implémenter un bot Twitter qui s'exécute sur Heroku en Python
[Python / Django] Créer une API Web qui répond au format JSON
Un enregistrement que GAMEBOY n'a pas pu être fait avec Python. (PYBOY)
À propos de psd-tools, une bibliothèque capable de traiter des fichiers psd en Python
Une fonction qui mesure le temps de traitement d'une méthode en python
Un programme qui détermine si un nombre entré en Python est un nombre premier
Un codec Python spécial qui semble savoir mais ne sait pas
Quoi de neuf dans datetime qui est un peu plus utile dans Python 3
[python] J'ai créé une classe qui peut écrire rapidement une arborescence de fichiers
Probablement dans un serpent Nishiki (Titre original: Peut-être en Python)
Ecrire une dichotomie en Python
[python] Gérer les fonctions dans une liste
Appuyez sur une commande en Python (Windows)
Implémentation de la segmentation d'image en python (Union-Find)
Les mines terrestres cachées dans les variables de classe Python
Créer un conteneur DI avec Python
Dessinez une matrice de diagramme de dispersion avec python