Probleme mit Python/Mosquitto

Probleme bei der Installation?
Antworten
Nonickatall
User
Beiträge: 17
Registriert: Dienstag 31. Januar 2017, 21:33

Sonntag 30. Mai 2021, 11:17

Hallo,

ich will Nachrichten via MQTT über das Netz schicken und zwischen einem Ubuntu Server 18.04.5 und einem RaspberryPi 3 mit Rasperian 10 austauschen. Der Broker läuft und der Client auch. Ich kann Nachrichten über die Console verschicken, aber wenn ich das aber mit Python versuche, dann bekomme ich den Fehler:

Code: Alles auswählen

1622369636: New connection from 192.168.0.11 on port 1883.
1622369636: New client connected from 192.168.0.11 as SMS_Daemon (c1, k60).
1622369636: Sending CONNACK to SMS_Daemon (0, 0)
1622369706: Socket error on client SMS_Daemon, disconnecting.
im Logfile des Mosquitto Brokers

Ich habe den Code aus einem Tutorial und habe, nachdem das nicht funktioniert hat, anderen Code aus einem anderen Tutorial verwendet, mit dem demselben Ergebnis. Jetzt ist mir aufgefallen, dass die Mosquitto Version auf dem Server eine 1.4.15 und auf dem Raspberry eine 1.5.7 ist, wobei auf dem Server Mosquitto Server und Mosquitto Client installiert sind, auf auf dem Raspberry nur Mosquitto Client. Beide Versionen sind die aktuellen aus dem Standard Repository.

Der Python Code ist:

Code: Alles auswählen

# -*- coding: utf8' -*-
import paho.mqtt.client as mqtt

mqttTopic = 'RaspberryPi1/SMS_Daemon'

# Funktionen für MQTT CLient
def connect_msg():
    print("Connect to broker")

def publish_msg():
    print("Message published")

#MQTT Client generieren
mqttClient = mqtt.Client(client_id='SMS_Daemon') #MQTT Client erzeugen
mqttClient.on_connect = connect_msg #Das Event das bei Connect zum Broker ausgelöst wird
mqttClient.on_publish = publish_msg #Das Event das bei publish ausgelöst wird
mqttClient.connect("192.168.0.1",1883) #Connect zum Broker


Hat jemand eine Idee wo ich weiter suchen kann?

Vielen Dank im Voraus
__deets__
User
Beiträge: 9832
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sonntag 30. Mai 2021, 11:24

Ich bin mir ziemlich sicher, dass die Beispiele für paho nach dem connect noch mehr machen. Denn wenn man deine Fehlermeldung googelt (immer das erste, was passieren sollte), dann beendet der Client die Verbindung. Was ja auch bei dir passiert. Connect, und dann Programmende -> alles sockets gehen ins Bettchen.
Nonickatall
User
Beiträge: 17
Registriert: Dienstag 31. Januar 2017, 21:33

Sonntag 30. Mai 2021, 11:42

__deets__ hat geschrieben:
Sonntag 30. Mai 2021, 11:24
Ich bin mir ziemlich sicher, dass die Beispiele für paho nach dem connect noch mehr machen. Denn wenn man deine Fehlermeldung googelt (immer das erste, was passieren sollte), dann beendet der Client die Verbindung. Was ja auch bei dir passiert. Connect, und dann Programmende -> alles sockets gehen ins Bettchen.
Hallo,

danke für die schnelle Antwort.

Klar machen die Beispiele nach dem Connect noch mehr. Die machen dann ein Subscribe, bzw. schicken Messages. Aber ich habe das Problem eingedampft, denn der connect schlägt ja schon fehl.

Ich habe selbstverständlich gegoogelt, ich versuch schon meine Probleme erst selbst zu lösen, deswegen ja die Idee mit dem unterschiedlichen Versionen. :wink:

Aber ich verstehe was du meinst. Guter Hinweis.. Ich habe mal den vollständigen Code verwendet. Dieser ist:

Code: Alles auswählen

# -*- coding: utf8' -*-
import paho.mqtt.client as mqtt

mqttTopic = 'RaspberryPi1/SMS_Daemon'

# Funktionen für MQTT CLient
def connect_msg():
    print("Connect to broker")

def publish_msg():
    print("Message published")

#MQTT Client generieren
mqttClient = mqtt.Client(client_id='SMS_Daemon') #MQTT Client erzeugen
mqttClient.on_connect = connect_msg #Das Event das bei Connect zum Broker ausgelöst wird
mqttClient.on_publish = publish_msg #Das Event das bei publish ausgelöst wird
mqttClient.connect("192.168.0.1",1883) #Connect zum Broker

def MQTT_senden(Message):
    print("MQTT senden")
    mqttClient.publish("RaspberryPi1/SMS_Daemon","Test") #Schickt Message zum Broker das eine SMS versendet wurde
        
MQTT_senden("Start")
print("MQTT gesendet")
Das schlägt fehl mit:

Code: Alles auswählen

>>> %Run MQTT.py
MQTT senden
Traceback (most recent call last):
  File "/home/pi/MyHome/MQTT.py", line 23, in <module>
    MQTT_senden("Start")
  File "/home/pi/MyHome/MQTT.py", line 21, in MQTT_senden
    mqttClient.publish("RaspberryPi1/SMS_Daemon","Test") #Schickt Message zum Broker das eine SMS versendet wurde
  File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 1274, in publish
    local_mid, topic, local_payload, qos, retain, False, info, properties)
  File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 2563, in _send_publish
    return self._packet_queue(PUBLISH, packet, mid, qos, info)
  File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 2919, in _packet_queue
    return self.loop_write()
  File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 1598, in loop_write
    rc = self._packet_write()
  File "/usr/local/lib/python3.7/dist-packages/paho/mqtt/client.py", line 2359, in _packet_write
    self, self._userdata, packet['mid'])
TypeError: publish_msg() takes 0 positional arguments but 3 were given
>>> 
und im Log steht:

Code: Alles auswählen

1622371017: New connection from 192.168.0.11 on port 1883.
1622371017: New client connected from 192.168.0.11 as SMS_Daemon (c1, k60).
1622371017: Sending CONNACK to SMS_Daemon (0, 0)
1622371017: Received PUBLISH from SMS_Daemon (d0, q0, r0, m0, 'RaspberryPi1/SMS_Daemon', ... (4 bytes))
1622371106: Client SMS_Daemon has exceeded timeout, disconnecting.
Dazu eine Idee?

LG
Ralf
__deets__
User
Beiträge: 9832
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sonntag 30. Mai 2021, 11:46

Was denkst du denn sagt die Fehlermeldung? Beschreib das doch mal.


Und zum ersten Thema: https://pypi.org/project/paho-mqtt/#network-loop
Nonickatall
User
Beiträge: 17
Registriert: Dienstag 31. Januar 2017, 21:33

Sonntag 30. Mai 2021, 12:02

Wenn ich das wüsste, hätte ich das Problem schon gelöst.. :?

Aber danke trotzdem.. :)
LukeNukem
User
Beiträge: 61
Registriert: Mittwoch 19. Mai 2021, 03:40

Sonntag 30. Mai 2021, 12:06

Nonickatall hat geschrieben:
Sonntag 30. Mai 2021, 12:02
Wenn ich das wüsste, hätte ich das Problem schon gelöst.. :?
Naja, die Fehlermeldung sagt:
TypeError: publish_msg() takes 0 positional arguments but 3 were given
Zu deutsch also in etwa:
publish_msg() erwartet 0 positionierte Argumente, aber es wurden drei übergeben
Bitte schau noch einmal in die Dokumentation und vergleiche die dort gezeigten Beispiel-Callbackfunktionen mit denen, die Du geschrieben hast.
Nonickatall
User
Beiträge: 17
Registriert: Dienstag 31. Januar 2017, 21:33

Sonntag 30. Mai 2021, 14:53

Ich schaue mir das später noch mal in Ruhe an, aber ich habe die nicht geschrieben.

Das ist ein 1 zu 1 Beispiel aus dem Tutorial..

Deswegen wundert es mich ja so das es nicht funktioniert.
Wenn ich es geschrieben hätte, würde es mich wundern dass es funktioniert. :D
__deets__
User
Beiträge: 9832
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sonntag 30. Mai 2021, 15:03

Dann ist das ein schlechtes Tutorial. Oder du hast falsch abgeschrieben. Denn dieser on_publish-Callback hat eine ganz spezifische Funktion, und aus dem Grund bekommt er Argumente. Wenn er die nicht bekaeme, waere er sinnlos.
Benutzeravatar
DeaD_EyE
User
Beiträge: 617
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Sonntag 6. Juni 2021, 15:56

Am einfachsten ist es in die Doku auf pypi zu schauen: https://pypi.org/project/paho-mqtt/#callbacks

Code: Alles auswählen

def sub_callback(client, userdata, message):
    """Eingehende Nachricht"""
    print(message.topic, message.payload)
    
def pub_callback(client, userdata, message):
    """Ausgehende Nachricht"""
    print("Gesendet", message.topic, message.payload)
Hinterher darfst du nicht vergessen im Programmcode die Schleife des mqtt-clients aufzurufen.
Call one of the loop*() functions to maintain network traffic flow with the broker
Nachrichten, die publisht werden, gehen sofort raus ohne das Aufrufen der Schleife, aber ankommende Nachrichten werden nicht abgerufen, wenn man die Schleife nicht zwischendurch aufruft.

(Man kann auch den threded Deamon starten.)

Jedenfalls funktioniert dein Code nicht, weil die Funktion, die den Callback auslöst, andere Argumente übermittelt, als deine Funktion akzeptiert. Kurz gefasst, die Signatur des Callbacks ist falsch.

Das Dumme daran ist, dass einem das erst dann um die Ohren fliegt, wenn der Callback ausgelöst wird.
Deswegen bei Callbacks immer in die Doku des jeweiligen Anbieters nachsehen.

Manchmal hat man Glück und die modernen IDEs zeigen einem sogar die Signatur der überladenen Funktion an. Im Fall von MQTT habe ich das aber leider nicht beobachten können.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten