我从我的Raspberry Pi Zero W(拉伸操作系统)上使用的pimoroni上买了一个触摸phat。 Touch phat基本上是一个用于覆盆子设备屏蔽的电容式按钮。(https://shop.pimoroni.com/products/touch-phat)。我决定在我的touch phat python脚本中实现Paho MQTT函数,我从pimoroni示例脚本(https://github.com/pimoroni/touch-phat/blob/master/examples/buttons.py)中获取。例如,当我按下A' A'按钮,脚本将MQTT消息发布到另一个同时运行的脚本(MQTT客户端),通知按钮已被按下,MQTT客户端脚本将执行最终操作(例如播放音频文件)。当我的脚本处于非活动状态大约5分钟时出现问题。当我再次触摸该按钮时,终端会打印一个错误,指出具有MQTT发布者功能的touchphat脚本的管道损坏([Errno 32] Broken pipe
)。按下touchphat按钮的后续尝试不会导致在终端上打印相同的错误(损坏的管道),但MQTT客户端无法接收任何进一步的消息。我怀疑MQTT发布者脚本中的signal.pause()
可能导致MQTT发布者和MQTT客户端通信之间的连接在短暂的不活动之后永久地被切断。有什么想法吗?我该如何解决这个问题?或者,如何在我的脚本中自动重新建立连接,而无需重新启动这些python脚本。
我的MQTT发布者脚本的代码是:
#!/usr/bin/env python
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
import signal
import time
import os
import touchphat
mqttc = mqtt.Client("client1", clean_session=False)
mqttc.username_pw_set("user", "mypassword")
mqttc.connect("m14.cloudmqtt.com", 21543, 50)
@touchphat.on_touch(['A'])
def handle_touch(event):
mqttc.publish("touchphat", payload="A", qos=0)
print("Button A pressed")
@touchphat.on_touch(['B'])
def handle_touch(event):
mqttc.publish("touchphat", payload="B", qos=0)
print("Button B pressed")
@touchphat.on_touch(['Back'])
def handle_touch(event):
mqttc.publish("touchphat", payload="Back", qos=0)
print("Button back pressed")
@touchphat.on_touch(['Enter'])
def handle_touch(event):
mqttc.publish("touchphat", payload="Enter", qos=0)
print("Button Enter pressed")
signal.pause() # I think this might be causing the broken pipe problem but I am not sure.
MQTT客户端脚本是:
#!/usr/bin/env python
import signal
import time
from subprocess import call# added for aplay
import touchphat
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
client.subscribe("touchphat")
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
if msg.topic == "touchphat":
if msg.payload == "A":
print("button A is pressed")
call(["aplay", "/home/pi/projectfolder/music.wav"])
if msg.topic == "touchphat":
if msg.payload == "B":
print("button B is pressed")
if msg.topic == "touchphat":
if msg.payload == "Back":
print("button Back is pressed")
if msg.topic == "touchphat":
if msg.payload == "Enter":
print("button Enter is pressed")
# Create an MQTT client and attach our routines to it.
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set("user", "mypassword")
client.connect("m14.cloudmqtt.com", 21543, 50)
client.loop_forever()
答案 0 :(得分:1)
我看到你的端口是21543,这可能表示cloudmqtt上的ssl端口。检查您的帐户,如果是,请在连接之前使用非ssl端口或在客户端上调用tls_set_context()。
答案 1 :(得分:0)
您需要让发布者中的MQTT客户端处理网络事件,为此,您需要启动网络循环。最简单的方法是将signal.pause()
替换为client.loop_forever()