Bonjour,
L'inscription sur ce forum et les premiers messages sont modérés par un Administrateur.
Ce n'est pas très convivial mais malheureusement nécessaire suite au spam intensif de nos amis russes.
Cordialement,
Dominique

MQTT - Problème de souscription

Le langage MicroPython, l'API machine (I2C, SPI, UART, Pin, etc)
Règles du forum
Vous aimez MicroPython? Nous aussi! Ces forums sont destinés aux amoureux de Python sur MicroContrôleur.
Le support se fait sur base volontaire et uniquement pour des produits officiels (pas de copie SVP).
Le forum de MicroPython.org sera une excellente référence documentaire (en anglais).

Merci de suivre les recommandations suivantes.
Pensez à:
  • Titre claire: permettant d'identifier le produit et le problème
  • Contenu complet: schema, message d'erreur, etc (tout ce qui permet d'aider à distance).
  • Fichier joint: Max 300 Ko
  • Courtoisie et précision
PhRaucq
Messages : 7
Inscription : lun. 24 août 2020 20:03

MQTT - Problème de souscription

Message par PhRaucq »

Bonjour,

Je suis en train de lire "Pyhton, Raspberry pi et Flask" et j'ai un problème de dialogue Publisher-subscriber en MQTT.

En m'inspirant des exemples proposés dans le livre, j'ai produit les codes suivant:
Pour le subscriber:

Code : Tout sélectionner

# coding: utf-8
import paho.mqtt.client as mqtt_client

# Configuration 
MQTT_BROKER = "192.168.1.**"
MQTT_PORT   = 1883
KEEP_ALIVE  = 45 # interval en seconde

def on_log( client, userdata, level, buf ):
    print( "log: ",buf)

def on_connect( client, userdata, flags, rc ):
    print( "Connexion: code retour = %d" % rc )
    print( "Connexion: Statut = %s" % ("OK" if rc==0 else "échec") )


def on_message( client, userdata, message ):
    print( "Reception message MQTT..." )
    print( "Topic : %s" % message.topic )
    print( "Data  : %s" % message.payload )

# Client(client_id=””, clean_session=True, userdata=None, protocol=MQTTv311, transport=”tcp”)
client = mqtt_client.Client( client_id="client007" )

# Assignation des fonctions de rappel
client.on_message = on_message
client.on_connect = on_connect
client.on_log = on_log 

# Connexion broker
client.username_pw_set( username="********", password="**********" )
client.connect( host=MQTT_BROKER, port=MQTT_PORT, keepalive=KEEP_ALIVE )
client.subscribe( "demo/#" )

# Envoi des messages
client.loop_forever()
Et pour le Publisher:

Code : Tout sélectionner

# coding: utf-8

import paho.mqtt.client as mqtt_client
from time import sleep

# Configuration 
MQTT_BROKER = "192.168.1.**"
MQTT_PORT   = 1883
KEEP_ALIVE  = 45 # interval en seconde

def on_log( client, userdata, level, buf ):
    print( "log: ",buf)

client = mqtt_client.Client( client_id="client007" )

# Assignation des fonctions de rappel
#client.on_log = on_log 

# Connexion broker
client.username_pw_set( username="*******", password="********" )
client.connect( host=MQTT_BROKER, port=MQTT_PORT, keepalive=KEEP_ALIVE )

# traitement des message
for i in range(4):
    print( "Publication iteration %s" % i )
    r = client.publish( "demo/machin-chose", "message %s"%i )
    print( "  envoyé" if r[0] == 0 else "  echec" ) 
    sleep( 1 )
Observations:

- J'ouvre un terminal et je lance le subscriber:
j'obtiens ceci:

Code : Tout sélectionner

('log: ', 'Sending CONNECT (u1, p1, wr0, wq0, wf0, c1, k45) client_id=client007')
('log: ', "Sending SUBSCRIBE (d0, m1) [('demo/#', 0)]")
('log: ', 'Received CONNACK (0, 0)')
Connexion: code retour = 0
Connexion: Statut = OK
('log: ', 'Received SUBACK')
- J'ouvre un second terminal et je lance "mosquitto_pub -h 192.168.1.58 -t "demo/brol" -m "hello world!" -u ********* -P *********
Le premier terminal m'affiche bien le topic et la publication.

- Si par contre, dans ce second terminal, je lance mon script de publisher, tout semble se dérouler normalement dans cette fenêtre (hormis l'un ou l'autre échec)

Code : Tout sélectionner

Publication iteration 0
  envoyé
Publication iteration 1
  envoyé
Publication iteration 2
  envoyé
Publication iteration 3
  echec
mais dans le terminal du subscriber, c'est la cata:

Code : Tout sélectionner

pi@raspberrypi:~/Documents/Maison_Python $ sudo python test-mqtt-client-sub.py
('log: ', 'Sending CONNECT (u1, p1, wr0, wq0, wf0, c1, k45) client_id=client007')
('log: ', "Sending SUBSCRIBE (d0, m1) [('demo/#', 0)]")
('log: ', 'Received CONNACK (0, 0)')
Connexion: code retour = 0
Connexion: Statut = OK
('log: ', 'Received SUBACK')
('log: ', 'Sending CONNECT (u1, p1, wr0, wq0, wf0, c1, k45) client_id=client007')
('log: ', 'Received CONNACK (0, 0)')
Connexion: code retour = 0
Connexion: Statut = OK
Le terminal qui avait annoncé une connexion OK semble redémarrer lors de la réception du message et puis ne fait plus rien.
Si je relance le script de publication, le souscripteur redémarre à nouveau.

Qu'ai-je fait de travers?
Une idée, quelqu'un?

Merci d'avance.
Avatar de l’utilisateur
Dominique
Administrateur du site
Messages : 109
Inscription : dim. 17 mai 2020 22:43

Re: MQTT - Problème de souscription

Message par Dominique »

Là, de façon évidente, je n'identifie pas immédiatement ce qui cloche.
La seule chose, c'est que l'adresse IP du broker MQTT est maquée dans les scripts.
J'imagine que, comme la commande MQTT, elles sont toutes bien à 192.168.1.58.

La connexion semble OK. Par contre, je suis étonné de ne pas voir de message PINGREQ, ni de Received PUBLISH...
Soit le message envoyé n'est pas sur le topic souscrit, soit il y a une erreur d'adresse IP.

Quand j'ai des doutes, j'utilise un 3ieme terminal et utilise un mosquito_sub sur tous les topics "#" comme cela, je vois au moins le message passer.

Cordialement
Dominique, MC Hobby.
PhRaucq
Messages : 7
Inscription : lun. 24 août 2020 20:03

Re: MQTT - Problème de souscription

Message par PhRaucq »

Merci pour cette réponse.

J'ai vérifié les IP. Elles sont bien identiques.

Pour le test de souscription, si je le laisse tourner seul, après connexion, il enchaîne des PINGREQ/PINGRESP

Code : Tout sélectionner

pi@raspberrypi:~/Documents/Maison_Python $ sudo python test-mqtt-client-sub.py
('log: ', 'Sending CONNECT (u1, p1, wr0, wq0, wf0, c1, k45) client_id=client007')
('log: ', "Sending SUBSCRIBE (d0, m1) [('demo/#', 0)]")
('log: ', 'Received CONNACK (0, 0)')
Connexion: code retour = 0
Connexion: Statut = OK
('log: ', 'Received SUBACK')
('log: ', 'Sending PINGREQ')
('log: ', 'Received PINGRESP')
('log: ', 'Sending PINGREQ')
('log: ', 'Received PINGRESP')
Et lorsque je démarre la publication dans l'autre terminal, cette suite s'arrête après l'envoi du premier message et amène ce qui, pour moi, ressemble à une reconnexion du souscripteur au broker. (C'est le 'sending connect' ci-dessous)
Puis les PINGREQ/PINGRESP reprennent.

Code : Tout sélectionner

pi@raspberrypi:~/Documents/Maison_Python $ sudo python test-mqtt-client-sub.py
('log: ', 'Sending CONNECT (u1, p1, wr0, wq0, wf0, c1, k45) client_id=client007')
('log: ', "Sending SUBSCRIBE (d0, m1) [('demo/#', 0)]")
('log: ', 'Received CONNACK (0, 0)')
Connexion: code retour = 0
Connexion: Statut = OK
('log: ', 'Received SUBACK')
('log: ', 'Sending PINGREQ')
('log: ', 'Received PINGRESP')
('log: ', 'Sending PINGREQ')
('log: ', 'Received PINGRESP')
('log: ', 'Sending PINGREQ')
('log: ', 'Received PINGRESP')
('log: ', 'Sending CONNECT (u1, p1, wr0, wq0, wf0, c1, k45) client_id=client007')
('log: ', 'Received CONNACK (0, 0)')
Connexion: code retour = 0
Connexion: Statut = OK
('log: ', 'Sending PINGREQ')
('log: ', 'Received PINGRESP')
Si je lance un troisième terminal avec Mosquitto_sub, j'ai deux cas de figure:
- si le souscripteur ne tourne pas, je vois les quatre messages du publisher (et ce dernier nous annonce quatre succès)
- si le souscripteur tourne, Mosquitto_sub affiche les deux premiers messages puis, quand le souscripteur se "reconnecte", Mosquitto_sub cesse d'afficher et le publisher met un "échec" pour l'envoi des deux derniers messages.
Avatar de l’utilisateur
Dominique
Administrateur du site
Messages : 109
Inscription : dim. 17 mai 2020 22:43

Re: MQTT - Problème de souscription

Message par Dominique »

Quelle configuration pour le serveur MQTT ?
Quelle configuration pour les machines exploitant les script Python ?
Dominique, MC Hobby.
PhRaucq
Messages : 7
Inscription : lun. 24 août 2020 20:03

Re: MQTT - Problème de souscription

Message par PhRaucq »

Une seule machine: un raspberry pi3B+ avec raspian (Llinux raspberrypi 5.4.51-v7 #1333)

J'y ai installé Mosquitto en suivant les prescriptions du livre python - raspberry pi - flask.
La version installée est 1.5.7+deb 10u1

Les versions de 2.7.16 et 3.7.3 de python sont installées et j'ai semble-t-il le même comportement avec les deux.
Avatar de l’utilisateur
Dominique
Administrateur du site
Messages : 109
Inscription : dim. 17 mai 2020 22:43

Re: MQTT - Problème de souscription

Message par Dominique »

Bonjour,
Je vais bientôt attaquer la relecture de ce chapitre... je vais faire des essais complémentaires sur Pi 4 et Pi 3B+ avec le dernier OS.

Il faut savoir que sur un Pi 3B+, le TCP/IP est en fait un TCP-IP over USB et que le chip USB était parfois sujet à la perte de trame de donnée. Je ne sais pas si cela pourrait expliquer le comportement que vous avez identifié.
Autre question que je me pose: est ce qu'un nouveau kernel récent (5.4) ne pourrait pas introduire un bug sur un ancien Pi???

Je reviens prochainement vers vous avec mes propres tests.
Dominique, MC Hobby.
PhRaucq
Messages : 7
Inscription : lun. 24 août 2020 20:03

Re: MQTT - Problème de souscription

Message par PhRaucq »

Merci. On verra ce que ça donne.

Ce qui est amusant, c'est que si j'utilise mosquitto_pub, le subscriber reçoit tout sans problème.
De même, avec mosquitto_sub, il lit tout ce qu'envoie le publisher.

C'est quand j'essaie de les faire dialoguer entre eux qu'il se passe de drôles de choses...
Avatar de l’utilisateur
Dominique
Administrateur du site
Messages : 109
Inscription : dim. 17 mai 2020 22:43

Re: MQTT - Problème de souscription (ClientId !!!!)

Message par Dominique »

He bien, j'ai trouvé d'où provient le problème.
Il faut des ClientId différents pour tous les clients... sinon cela met le subscriber (ou le broker) totalement en vrac. Il faut relancer le sub.py pour refaire une nouvelle souscription.

Si tous les clientId sont tous différents.... alors cela fonctionne parfaitement.
Dominique, MC Hobby.
PhRaucq
Messages : 7
Inscription : lun. 24 août 2020 20:03

Re: MQTT - Problème de souscription

Message par PhRaucq »

Ok. Super.
Merci pour cette réponse (que j'ai mis un peu de temps à venir lire, je l'avoue).
Répondre