我使用mqtt协议将传感器数据的消息发送到mosquitto代理。我想做的是每隔t秒发送一次传感器数据,但是如果我收到一条消息并行处理它。我很想使用时间。睡觉(),但我认为这会延迟" on_message"功能也。使用paho-mqtt和python 2.7。关于如何完成这样的事情的任何想法?
客户编号1。(发送传感器数据)
from mysignals import mysignals
import paho.mqtt.client as mqtt
import time
def on_connect(client, userdata, rc):
mqttc.subscribe(topic='/+/mysignals/status', qos=0)
mqttc.subscribe(topic='/+/mysignals/add_sensor',qos=0)
mqttc.subscribe(topic='/+/mysignals/remove_sensor',qos=0)
def on_message(client,userdata,message):
print 'received data'
base_topic = '/mysignals'
member_id = message.topic.split('/')[1]
status_topic = '/mysignals/status'
add_sensor_topic = '/mysignals/add_sensor'
remove_sensor_topic = '/mysignals/remove_sensor'
log_topic = '/log'
if status_topic in message.topic:
action = mysignals_test.change_status(int(member_id),int(message.payload))
mqttc.publish(topic='/'+member_id+status_topic+log_topic+'/',payload=action,qos=0)
elif add_sensor_topic in message.topic:
action = mysignals_test.add_sensor(message.playload,int(member_id))
mqttc.publish(topic='/'+member_id+add_sensor_topic+log_topic+'/',payload=action,qos=0)
elif remove_sensor_topic in message.topic:
action = mysignals_test.remove_sensor(message.payload,int(member_id))
mqttc.publish(topic='/'+member_id+remove_sensor_topic+log_topic+'/',payload=action,qos=0)
else:
mqttc.publish(topic='/'+member_id+base_topic+log_topic+'/',payload='Wrong Action.',qos=0)
mysignals_test = mysignals(email='blablabla',password='blabla')
mysignals_test.add_sensor('temp',150)
mysignals_test.change_status(150,1)
mqttc = mqtt.Client(client_id='mysignals')
mqttc.on_connect = on_connect
mqttc.on_message = on_message
mqttc.connect('broker ip')
mqttc.loop_start()
while True:
for member in mysignals_test.members:
if member.status == 1:
live_data = mysignals_test.live(member.member_id)
for data in live_data:
topic = '/'+str(data.member_id)+'/mysignals/'+str(data.sensor_id)+'/'
qos = 0
retain = False
if 'raw' in data.sensor_id:
payload = data.values
else:
payload = data.value
mqttc.publish(topic=topic,payload=payload,qos=qos,retain=retain)
print 'sent data'
time.sleep(55)
客户端No2(从客户端接收数据1.仅限订户。也向client1.only订阅者发送测试消息。)
import paho.mqtt.client as mqtt
def on_connect(client, userdata, rc):
mqttc.subscribe(topic='/+/mysignals/+/', qos=0)
mqttc.subscribe(topic='/+/mysignals/status/+/', qos=0)
def on_disconnect(client,userdata,rc):
pass
def on_message(client, userdata, message):
if str(message.payload) == '':
print 'empty message'
else:
print 'Received message :' + str(message.payload) + ', on topic: '+ message.topic + ', with QoS: ' + str(message.qos)
mqttc.publish(topic='/154/mysignals/status',payload=0,qos=0)
mqttc = mqtt.Client(client_id='P1')
mqttc.on_connect = on_connect
mqttc.on_disconnect = on_disconnect
mqttc.on_message = on_message
mqttc.connect('broker ip')
mqttc.loop_start()
仅供记录" mysignals"对象是由我制作的,它不存在于那里。上面的代码的问题是,当客户端2接收到传感器数据时,它会挂起并将测试消息无条件地发送回代理。客户端2发送时的测试消息接收传感器数据应该由客户端1读取,客户端1应该操纵" mysignals"相应的对象。
客户2输出:
Received message :25.4, on topic: /150/mysignals/temp/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with QoS: 0
Received message :Success, on topic: /154/mysignals/status/log/, with
客户1输出:
Login Successfull.
sent data
sent data
received data
received data
received data
received data
received data
received data
received data
received data
PS:我不包括" mysignals.py"因为大约有200行。
答案 0 :(得分:1)
我对Paho MQTT库中回调函数的运行方式的理解是后台循环(由loop_start启动)将中断主线程,所以我不担心使用time.sleep()的延迟。因此,如果您主要关注的是不延迟on_message回调,那么它应该不是问题。我经常在使用MQTT回调的Python脚本中使用sleep。
当然回调可能会稍微延迟传感器发送数据,但实际上您是否需要以绝对精确的时序发送数据?大多数数据库(例如RRD)可以轻松适应略微关闭的更新时间。或者,如果您的on_message回调花费了不可接受的长时间来处理,请考虑将MQTT消息的有效负载传递出回调函数,并在脚本的其他位置处理它。
如果您确实需要传感器更新的瞬间精度,请考虑将功能分成两个脚本(或线程),每个脚本只用于一个目的(发送或接收)。
答案 1 :(得分:0)
好的,我设法得到了预期的结果。我必须在状态子主题上创建2个子主题。一个客户端应该写在状态suptopic的日志子主题上,一个客户端应该在状态子主题的值子主题上写.Also我删除了订阅上的qos参数。我还添加了time.sleep(),我很少会错过一条消息。只有在非常短的时间间隔内收到2条消息。最大的问题是我没有理解主题和子主题是如何实际的工作。