paho mqtt not publishing



编写了一段代码,每秒检查gpio状态,如果新的结果与前一个不匹配,它应该发布它。问题是,它不发布它,但如果你输入一个打印,那么一切都很清楚。会出什么问题呢?

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()

我不确定为什么添加print()修复了这个问题-但是在使用client.loop()函数的程序中存在问题。

它被设计为定期调用,以便允许MQTT代码运行、发布和接收消息。此外,通过在一个paho回调中放置一个永远循环,您还可以阻止MQTT代码运行,因为on_connect()回调永远不会返回。

与其使用on_connect()回调来运行代码,不如在MQTT回调之外创建gpio循环,并使用一个标志来检测MQTT连接何时建立。

因为您有一个每2秒延迟一次的循环,所以最好使用client.loop_start()函数,以便客户端在单独的线程中启动MQTT处理循环。这样你就不必担心反复调用client.loop()

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)

你不能运行阻塞代码在任何客户端回调的,因为他们将停止客户端网络循环运行。

在这种情况下,你在on_connect回调中有一个while True:循环,这意味着它永远不会返回。这行不通。

另外,client.loop()只触发客户端网络循环的一次迭代,您需要调用client.loop_start()client.loop_forever()中的一个。前者在一个单独的线程上运行循环,后者在当前线程上运行循环。

最新更新