Where is the error in my Python code (MQTT)?

I created a Python script so that certain commands can be executed later when messages are received. For the first script (Openhab_Mqtt.py), I opened three terminals while testing, and for the second (Openhab_Mqttv2.py), I used exactly the same procedure.

In the first terminal I started the Python script with:

 python Openhab_Mqttv2.py

Output:
Script 1: Connected to MQTT broker
Script 2: Connected to MQTT broker
Connected to MQTT broker

In the second terminal I displayed the message for messages with:

 mosquitto_sub -t "main/messager" -v -u xxx -P xxx

Output (after T3):
Script 1: main/messager test
Script 2: main/messager test

And in the 3rd terminal I sent a message with:

 mosquitto_pub -t "main/messager" -m "test" -u xxx-P xxx

Output:
Script 1: Payload: test and BLA…
Script 2:

I just can't find the error why it works for Openhab_Mqtt.py and not for Openhab_Mqttv2.py.

Openhab_Mqtt.py DATA:

 import paho.mqtt.client as mqtt import os import time import bme280_temp import smbus2 import bme280 import threading def on_subscribe(client, userdata, mid, granted_qos): print("Subscribed to topic : " + str(mid) +" with QoS" + str(granted_qos)) def on_connect(client, userdata, flags, rc): print("Connected to MQTT broker") def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload)) print("Payload: " + msg.payload.decode()) if msg.payload.decode() == "send_signal": print("Calling script to send signal...") IR_Signal() if msg.payload.decode() == "temp_bme280_start": print("Calling script to for temperature start...") userdata["counter"] += 1 print(str(userdata["counter"])) client.publish("frame/monitor", "START", qos=0, retain=True) Temp_sensor() if msg.payload.decode() == "temp_bme280_stop": print("Calling script to for temperature stop...") userdata["counter"] -= 1 print(str(userdata["counter"])) client.publish("frame/monitor", "STOP", qos=0, retain=True) if msg.payload.decode() == "test": print("BLA...") print(str(["counter"])) os.system("vcgencmd measure_temp") else: pass #Bme280_basic Temperature address = 0x76 bus = smbus2.SMBus(1) calibration_params = bme280.load_calibration_params(bus, address) def Temp_sensor(): data = bme280.sample(bus, address, calibration_params) temperature_celsius = data.temperature print("Temperature: {:.2f} °C".format(temperature_celsius)) time.sleep(2) def IR_Signal(): os.system("irsend SEND_ONCE pioneer_vsx-301 KEY_POWER") print ("Signal Send!") client = mqtt.Client() client.on_message = on_message client.on_connect = on_connect client.user_data_set({"counter": 0}) client.username_pw_set( "xx" , "xx" ) client.connect( "192.xxx", 1883, 60) client.subscribe( "main/messager" , qos=0) client.loop_forever()

Openhab_Mqttv2.py

 import paho.mqtt.client as mqtt import time import smbus2 import bme280 import threading # Getting information def on_subscribe(client, userdata, mid, granted_qos): print("Subscribed to topic : " + str(mid) +" with QoS" + str(granted_qos)) def on_connect(client, userdata, flags, rc): print("Connected to MQTT broker") # Damit loops nicht am anfang durchstarten TempLoop_running = False # Checking for messages to execute code def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload)) print("Payload: " + msg.payload.decode()) if msg.payload.decode() == "Temp_Start": start_TempLoop() if msg.payload.decode() == "Temp_Stop": stop_TempLoop() if msg.payload.decode() == "test": print("TESTING...") client.publish("main/messager", "START", qos=0, retain=True) else: pass # Execute things here -> # Getting Temperature address = 0x76 bus = smbus2.SMBus(1) # Load calibration parameters calibration_params = bme280.load_calibration_params(bus, address) def Temperature_loop(): global TempLoop_running while TempLoop_running: data = bme280.sample(bus, address, calibration_params) #Extract temperature, pressure, and humidity temperature_celsius = data.temperature #Print the readings print("Temperature: {:.2f} °C".format(temperature_celsius)) # Nachricht an das entsprechende Topic senden client.publish("Temp/Loop", "Temperature: {:.2f} °C".format(temperature_celsius)) # Wartezeit, um die Ausgabe zu verlangsamen time.sleep(2) # Funktion zum Starten der Temperatur Schleife def start_TempLoop(): global TempLoop_running TempLoop_running = True threading.Thread(target=Temperature_loop).start() # Funktion zum Stoppen der Temperatur Schleife def stop_TempLoop(): global TempLoop_running TempLoop_running = False # Set general data client = mqtt.Client() client.on_message = on_message client.on_connect = on_connect client.connect( "192.xxx", 1883, 60) client.username_pw_set( "xx", "xx" ) client.subscribe( "main/messager", qos=0) # Loop forever client.loop_forever()
(1 votes)
Loading...

Similar Posts

Subscribe
Notify of
1 Answer
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
MasterFAQ
1 year ago

The main difference between the two scripts is how the temperature loop (

Temperature_loop()

) is controlled. In the first script (

Openhab_Mqtt.py

) the loop within the

Temp_sensor()

-Function started, which is activated by an MQTT message. In the second script (

Openhab_Mqttv2.py

) the loop becomes within a separate function (

Temperature_loop()

) started by the functions

start_TempLoop()

and

stop_TempLoop()

is controlled.

Here is the error in your second script (

Openhab_Mqttv2.py

:

You forgot the

on_subscribe

-use function to process the subscriptions for the MQTT messages. Since you have not defined any explicit function, the default function of Paho MQTT is used that does nothing. Therefore, the “Temp_Start” message is not subscribed, and the temperature loop is not started.

To solve the problem, just add one

on_subscribe

– Function that processes the subscriptions for the MQTT messages. Here is a revised version of your second script (

Openhab_Mqttv2.py

the

on_subscribe

-Function contains:

import paho.mqtt.client as mqtt
import time
import smbus2
import bme280
import threading


# Getting information
def on_subscribe(client, userdata, mid, granted_qos):
    print("Subscribed to topic : " + str(mid) +" with QoS" + str(granted_qos))
                                                                 
def on_connect(client, userdata, flags, rc):
    print("Connected to MQTT broker")




# Damit loops nicht am anfang durchstarten 
TempLoop_running = False




# Checking for messages to execute code
def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))
    print("Payload: " + msg.payload.decode())
    if msg.payload.decode() == "Temp_Start":
        start_TempLoop()
    if msg.payload.decode() == "Temp_Stop":
        stop_TempLoop()
    if msg.payload.decode() == "test":
        print("TESTING...")
        client.publish("main/messager", "START", qos=0, retain=True)
    else:
        pass


# Execute things here ->


# Getting Temperature
address = 0x76
bus = smbus2.SMBus(1)
# Load calibration parameters
calibration_params = bme280.load_calibration_params(bus, address)
def Temperature_loop():
    global TempLoop_running
    while TempLoop_running:
        data = bme280.sample(bus, address, calibration_params)
        #Extract temperature, pressure, and humidity
        temperature_celsius = data.temperature      
        #Print the readings
        print("Temperature: {:.2f} °C".format(temperature_celsius))
        # Nachricht an das entsprechende Topic senden
        client.publish("Temp/Loop", "Temperature: {:.2f} °C".format(temperature_celsius))
        # Wartezeit, um die Ausgabe zu verlangsamen
        time.sleep(2)
# Funktion zum Starten der Temperatur Schleife
def start_TempLoop():
    global TempLoop_running
    TempLoop_running = True
    threading.Thread(target=Temperature_loop).start()
# Funktion zum Stoppen der Temperatur Schleife
def stop_TempLoop():
    global TempLoop_running
    TempLoop_running = False


# Set general data
client = mqtt.Client()
client.on_message = on_message 
client.on_connect = on_connect
client.on_subscribe = on_subscribe  # Subscribe-Funktion hinzufügen
client.connect( "192.x.x.x", 1883, 60)
client.username_pw_set( "xx", "xx" )
client.subscribe( "main/messager", qos=0)




# Loop forever
client.loop_forever()