2017-07-28 83 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不建議按比例進行此操作,但對測試來說可以。您也失去了在政策中使用客戶端的能力。