wrote a code that checks gpio statuses every second and if the new result does not match the previous one, it should publish it. The problem is that it does not publish it, but if you enter a print, then everything works clearly. What can be wrong?
from argparse import ArgumentError
from multiprocessing.connection import Client
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
import re
import subprocess
import time
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected with result code "+str(rc))
values = dict()
k = 0
while True:
DIN4R=subprocess.run("gpioget `gpiofind \"DIN4\"`",shell=True,check=True, capture_output=True)
DIN3R=subprocess.run("gpioget `gpiofind \"DIN3\"`",shell=True,check=True, capture_output=True)
DIN2R=subprocess.run("gpioget `gpiofind \"DIN2\"`",shell=True,check=True, capture_output=True)
arr= str(DIN4R.stdout + DIN3R.stdout + DIN2R.stdout)
arrr = re.sub("[^0,^1]", "", arr)
if k % 2 == 0:
values['0'] = arrr
else:
values['1'] = arrr
if k != 0:
if values['1'] != values['0']:
global arrrr
arrrr=arrr
print(arrrr)
client.publish("test/5555result", arrrr)
k+=1
time.sleep(2)
def on_publish(client, userdata, result):
print("data published \n")
pass
client = mqtt.Client()
client.on_connect = on_connect
client.on_publish = on_publish
client.connect("test.mosquitto.org", 1883, 60)
client.loop()
I'm not sure why adding a print()
fixed the problem - but there are issues in the program around the use of the client.loop()
function.
This is designed to be called regularly in order to allow the MQTT code to run, publishing and receiving messages. Also - by putting a forever loop in one of the paho callbacks - you're also stopping the MQTT code from running, since the on_connect() callback never returns.
Rather than use the on_connect()
callback to run your code, it may be better to create your gpio loop outside of the MQTT callbacks, and use a flag to detect when the MQTT connection has been established.
Because you have a loop that delays every 2 seconds you're also better off using the client.loop_start()
function so that the client will start the MQTT handling loop in a separate thread. That way you don't have to worry about repeatedly calling client.loop()
.
eg.
from argparse import ArgumentError
from multiprocessing.connection import Client
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
import re
import subprocess
import time
is_connected = False
def on_connect(client, userdata, flags, rc):
global is_connected
if rc == 0:
print("Connected with result code "+str(rc))
is_connected = True
def on_publish(client, userdata, result):
print("data published \n")
pass
client = mqtt.Client()
client.on_connect = on_connect
client.on_publish = on_publish
client.connect("test.mosquitto.org", 1883, 60)
client.loop_start()
while( not is_connected ):
print("Waiting for MQTT connection ...")
time.sleep(1)
values = dict()
k = 0
while True:
DIN4R=subprocess.run("gpioget `gpiofind \"DIN4\"`",shell=True,check=True, capture_output=True)
DIN3R=subprocess.run("gpioget `gpiofind \"DIN3\"`",shell=True,check=True, capture_output=True)
DIN2R=subprocess.run("gpioget `gpiofind \"DIN2\"`",shell=True,check=True, capture_output=True)
arr= str(DIN4R.stdout + DIN3R.stdout + DIN2R.stdout)
arrr = re.sub("[^0,^1]", "", arr)
if k % 2 == 0:
values['0'] = arrr
else:
values['1'] = arrr
if k != 0:
if values['1'] != values['0']:
arrrr=arrr
print(arrrr)
client.publish("test/5555result", arrrr)
k+=1
time.sleep(2)