2017-07-28 188 views
1

因此,我有一个Raspberry Pi#1,它将通过主题sensors/Button向AWS发布MQTT消息。这会在按下按钮时触发,如下所示。将Ras Raspberry Pi#1连接到使用AWS作为MQTT Broker的Rapsberry Pi#2

# Import SDK packages 
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient 
from time import sleep 
from gpiozero import Button 
from signal import pause 

button = Button(13, pull_up=False) 

def callMQTT(): 
    print("button is pressed.Sending to MQTT") 
    mqtt_message = "{\"message\":\"button_pressed\"}" 
    print(mqtt_message) 
    my_rpi.publish("sensors/Button", mqtt_message, 1) 
    print("Message Published!") 
    sleep(5) 


host="host.amazonaws.com" 
rootCAPath = "rootca.pem" 
certificatePath = "certificate.pem.crt" 
privateKeyPath = "private.pem.key" 

try: 
    my_rpi = AWSIoTMQTTClient("basicPubSub") 
    my_rpi.configureEndpoint(host,8883) 
    my_rpi.configureCredentials(rootCAPath, privateKeyPath, certificatePath) 

    my_rpi.configureOfflinePublishQueueing(-1) # Infinite offline Publish queueing 
    my_rpi.configureDrainingFrequency(2) # Draining: 2 Hz 

    # Connect and subscribe to AWS IoT 
    my_rpi.connect() 
    print("Connection Succesful") 
except: 
    print("Unexpected error:", sys.exc_info()[0]) 

button.when_pressed = callMQTT 
pause() 

树莓PI#2,它会尝试使用同一台主机,同样的事情,同样的密钥和相同证书Raspbery PI#1从AWS认购MQTT。如果收到消息,它会发出蜂鸣声并点亮LED,如下所示。

# Import SDK packages 
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient 
from time import sleep 
from gpiozero import Buzzer,LED 
import random 
import sys 
from datetime import datetime 

bz = Buzzer(22) 
led = LED(18) 

# Custom MQTT message callback 
def customCallback(client, userdata, message): 
    print("Received a new message: ") 
    print(message.payload) 
    print("from topic: ") 
    print(message.topic) 
    print("--------------\n\n") 
     timestring = str(datetime.now()) 
    print("Doorbell pressed") 
    bz.on() 
    led.blink() 
    sleep(1) 
    bz.off() 
    led.off() 

host="host.amazonaws.com" 
rootCAPath = "rootca.pem" 
certificatePath = "certificate.pem.crt" 
privateKeyPath = "private.pem.key" 

try: 
    my_rpi = AWSIoTMQTTClient("basicPubSub") 
    my_rpi.configureEndpoint(host, 8883) 
    my_rpi.configureCredentials(rootCAPath, privateKeyPath, certificatePath) 

    my_rpi.configureOfflinePublishQueueing(-1) # Infinite offline Publish queueing 
    my_rpi.configureDrainingFrequency(2) # Draining: 2 Hz 
    my_rpi.configureConnectDisconnectTimeout(10) # 10 sec 
    my_rpi.configureMQTTOperationTimeout(5) # 5 sec 

    # Connect and subscribe to AWS IoT 
    my_rpi.connect() 
except: 
    print("Unexpected error:", sys.exc_info()[0]) 

while True: 
my_rpi.subscribe("sensors/Button", 1, customCallback) 
sleep(2) 

但是,这是不可能的。当两个程序同时运行时,Rasberry Pi#2将始终超时。由于某种原因,它只允许一次连接一个。 我尝试在运行Raspberry Pi#1代码时直接通过AWS订阅主题。它在AWS上显示消息。此外,如果我尝试直接在AWS上发布消息并仅运行Raspberry Pi#2代码,它也可以运行,但在运行代码时不会运行。我对树莓派#2得到的错误是这样的:

没有处理程序可以为记录器 “AWSIoTPythonSDK.core.protocol.mqttCore”回溯(最近通话 最后一个)中找到:文件“Doorbell_Indoor.py” ,第72行,在 my_rpi.subscribe(“sensors/Button”,1,customCallback)文件“/usr/local/lib/python2.7/dist-packages/AWSIoTPythonSDK/MQTTLib.py”, line 491,in subscribe return self._mqttCore.subscribe(topic,QoS,callback)文件“/usr/local/lib/python2.7/dist-packages/AWSIoTPythonSDK/core/protocol/mqttCore.py”, line 416,在订阅 raise subscribeTimeoutException()AWSIoTPythonSDK.exception.AWSIoTExceptions.sub scribeTimeoutException

任何人都知道如何解决这个问题?提前致谢!

+0

每个客户端都必须有一个唯一的客户端ID,最好的猜测是传递给'AWSIoTMQTTClient()'的字符串是客户端ID,使这些不同并看看会发生什么 – hardillb

回答

1

我没有看到它在Python SDK文档记录,但在Java SDK文档,它说:

的clientId - 客户端ID唯一标识MQTT连接。具有相同客户端ID的两个 客户端不允许同时连接 到同一端点。

尝试使用每个连接的唯一clientId值而不是"basicPubSub"

+0

在哪里可以找到clientId? AWS似乎没有它。我是否构建了自己的clientId? –

+0

你完成了。您应该为每个正在运行的脚本使用不同的ID。 –

0

http://docs.aws.amazon.com/iot/latest/developerguide/protocols.html

消息中介器使用客户端ID来识别各客户端。客户端ID作为MQTT有效负载的一部分从客户端传递到消息代理。具有相同客户端ID的两个客户端不允许同时连接到消息代理。当客户端使用另一客户端正在使用的客户端ID连接到消息代理时,CONNACK消息将发送到两个客户端>,并且当前连接的客户端将断开连接。

您必须将每个客户端的唯一字符串传递给AWSIoTMQTTClient()或空字符串。如果您为客户端ID传递空字符串,AWS IoT网关将为您连接时分配一个随机客户端ID。

变化从

my_rpi = AWSIoTMQTTClient("basicPubSub") 

的AWSIoTMQTTClient调用

my_rpi = AWSIoTMQTTClient("") 

和各的RPI将在连接分配一个唯一的随机客户端ID。 AWS不建议按比例进行此操作,但对测试来说可以。您也失去了在政策中使用客户端的能力。