@Tola-Emma: Wenn man eine Funktion mit `print()` ausgibt, wird die Funktion ausgegeben. Also das Funktionsobjekt selbst. Was in diesem Fall eine Zeichenkettendarstellung der Funktion ist, also die `repr()`-Form von einem definierten Objekt: Der Typ, der Name unter dem es definiert wurde, und eine eindeutige ID, damit man auch Objekte mit dem gleichen Definitionsnamen noch auseinanderhalten kann, in ”spitzen Llammern”. Sieht man ja in der Ausgabe.
Und dieses `print()` passiert ganz am Anfang des Hauptprogramms, noch bevor das `Client()`-Objekt erstellt wurde. Ein `print()` führt nicht auf magische Weise irgendwann später mal zu ausgaben. Das führt genau dann zu einer Ausgabe wenn es ausgeführt wird. Und kann zu dem Zeitpunkt nichts ausgeben was es zu dem Zeitpunkt noch gar nicht gibt.
Die Funktion `mqtt_auswahl()` wird ja auch überhaupt nicht aufgerufen, weder direkt, noch wird sie irgendwo als Rückruffunktion übergeben. Also kann die auch niemals ausgeführt werden.
Die Funktion bekommt ein Argument übergeben, welches überhaupt nicht verwendet wird, verwendet selbst aber zwei Namen `message` und `msg` die überhaupt nicht definiert sind. `message` und `msg` sind als Namen auch nicht so wirklich sinnvoll, weil man als Leser durcheinander kommen kann was denn der Unterschied zwischen der Nachricht und der Nachricht ist.
Wo wir gerade bei Namen sind: Funktionen und Methoden werden üblicherweise nach der Tätigkeit benannt die sie durchführen. Damit der Leser weiss was da passiert, und damit sie leicht von eher passiven Werten unterscheiden kann. `mqtt_nachricht` wäre ein passender Name für ein Objekt, das eine MQTT-Nachricht repräsentiert. Weniger für eine Funktion die etwas mit so einer Nachricht anstellt. `mqtt_verbindung` wäre ein passender Name für eine Verbindung. Statt einer Tätigkeit gibt es bei Rückruffunktionen noch das übliche Muster `on_<ereignis>` für Reaktionen auf bestimmte Ereignisse. Das `Client`-Objekt macht es mit `on_connect()` und `on_message()` vor.
Bei `mqtt_nachricht()` macht das ``return`` keinen Sinn. Die Funktion wird vom `Client`-Objekt aus aufgerufen wenn eine neue Nachricht kommt. Und das `Client`-Objekt erwartet von dieser Rückruffunktion keine Werte als Ergebnis. Damit passiert also nichts.
Sämtliche Aufrufe von `str()` sind falsch. Bei einer Zeichenkette ist der Aufruf von `str()` einfach nur sinnlos — das ist ja bereits eine Zeichenkette. Die Zeichenkettendarstellung von literalen `bytes`-Objekten macht keinen Sinn, da hätte man dann ja gleiche eine Zeichenkette mit dem Inhalt schreiben können. Was aber in aller Regel ebenfalls keinen Sinn macht.
Man sollte keine Daten wiederholen. Die Topics sollten *einmal* als Konstanten definiert werden, statt mehrfach als laaange Zeichenkettenliterale im Code zu stehen, wo schon beim schreiben die Gefahr besteht, dass man sich vertippt, und dann jedes mal wenn man da etwas dran ändern will oder muss.
Wenn man in allen ``if``/``elif``-Answeisungen immer die gleiche Teilbedingung prüft, sollte man die dort herausziehen und einmal vorher prüfen. So eine Abbildung von einem Wert auf einen anderen Wert löst man eher mit einem Wörterbuch anstelle eines ``if``/``elif``-Konstrukts.
Zwischenstand (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
import paho.mqtt.client as mqtt
BROKER_ADDRESS = "localhost"
BASE_TOPIC = "/RS485/empfang/daten/Tasten/"
INNER_LIGHT_TOPIC = BASE_TOPIC + "Innenlicht"
OUTER_LIGHT_TOPIC = BASE_TOPIC + "Aussenlicht"
WATERPUMP_TOPIC = BASE_TOPIC + "Wasserpumpe"
TOPIC_TO_ANSWER = {
INNER_LIGHT_TOPIC: b"\xff\x01\x00\x00\x00",
OUTER_LIGHT_TOPIC: b"\xff\x02\x00\x00\x01",
WATERPUMP_TOPIC: b"\xff\x04\x00\x00\x03",
}
def get_answer(message):
if message.payload == b"true":
return TOPIC_TO_ANSWER.get(message.topic, b"")
return b""
def on_connect(client, _userdata, _flags, _rc):
client.subscribe(INNER_LIGHT_TOPIC)
client.subscribe(OUTER_LIGHT_TOPIC)
client.subscribe(WATERPUMP_TOPIC)
def on_message(_client, _userdata, message):
print("message received:", message.payload.decode("utf-8"))
print("message topic:", message.topic)
answer = get_answer(message)
print("answer:", answer)
def main():
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER_ADDRESS)
client.loop_start()
if __name__ == "__main__":
main()
Die Warnung mit der API sollte man auch ernst nehmen. Ich habe anscheinend eine neuere Version von `paho-mqtt` auf dem Rechner: bei mir kommt statt der Warnung bereits ein Fehler an der Stelle.