2014-03-26 32 views
0

我是Python的總新手,擁有非常基本的MQTT知識。將MQTT主題和消息放在數組中

我正在嘗試編寫一個訂閱通配符主題的python腳本,然後生成通配符下的主題列表。我明白MQTT協議並不適合這一點,所以我需要通過python來完成。我正在考慮將主題和消息放入數組中。

我有下列主題:

/天氣/電流/溫度

/天氣/電流/溼度

/天氣/電流/壓力

/天氣/電流/時間

在我的python腳本我正在訂閱/ weather/current /#。

例如,我想在陣列將是這樣的:

[/天氣/電流/溫度,消息]

[/天氣/電流/溼度,消息]

[/天氣/電流/壓力,消息]

[/天氣/電流/時間,消息]

我的腳本幾乎是標準的例子,我嘗試了幾種方法來達到這個目的,但是失敗了。我認爲我的根本問題是我對on_message函數缺乏瞭解。它是針對所有主題執行一次還是針對每個主題執行一次?

def on_connect(mqttc, obj, rc): 
    print("rc: "+str(rc)) 

def on_message(mqttc, obj, msg,): 
    # print(msg.topic+" "+str(msg.payload)) 
    payload = str(msg.payload) 
    print(msg.topic+" Payload -> "+payload) 

def on_publish(mqttc, obj, mid): 
    print("mid: "+str(mid)) 

def on_subscribe(mqttc, obj, mid, granted_qos): 
    print("Subscribed: "+str(mid)+" "+str(granted_qos)) 

def on_log(mqttc, obj, level, string): 
    print(string) 

try: 
    mqttc = mqtt.Client("Python-MQTT-Sub") 

    mqttc = mqtt.Client() 
    mqttc.on_message = on_message 
    mqttc.on_connect = on_connect 
    mqttc.on_publish = on_publish 
    mqttc.on_subscribe = on_subscribe 
    # Uncomment to enable debug messages 
    #mqttc.on_log = on_log 
    mqttc.connect("localhost", 1883, 60) 
    mqttc.subscribe("/weather/current/#", 0) 

    mqttc.loop_forever() 

except KeyboardInterrupt: 
    print("\ninterrupt received, exiting...") 

回答

2

正如@ralight上面所說的,on_message在收到消息(可能是也可能不是保留消息)時被調用。爲了說明,我已經稍微改變了你的代碼來添加一個名爲topic_names的數組,這個數組在消息到達程序時被填充。

import paho.mqtt.client as mqtt 

topic_names = [] 

def on_message(mqttc, obj, msg,): 
    # print(msg.topic + " " + str(msg.payload)) 
    payload = str(msg.payload) 
    print(msg.topic + " Payload -> " + payload) 

    topic_names.append(msg.topic) 

try: 
    mqttc = mqtt.Client() 
    mqttc.on_message = on_message 

    mqttc.connect("localhost", 1883, 60) 
    mqttc.subscribe("weather/current/#", 0) 

    mqttc.loop_forever() 

except KeyboardInterrupt: 
    print "Received topics:" 
    for topic in topic_names: 
     print topic 

運行此程序,併發布兩條消息就說明

weather/current/temp Payload -> Fair 
weather/current/humidity Payload -> 10 
^C 
weather/current/temp 
weather/current/humidity 
+0

非常感謝你的魅力。 – Gregg

1

on_message將在接到來自代理的消息時被調用。這可能是您訂閱的任何主題的消息,因此任何東西/weather/current及以上。即使您只使用單一訂閱,郵件也是不同的事件。

另一個小問題 - 除非您使用clean session設置爲false,否則硬編碼客戶端ID通常不是一個好主意。重複的客戶端ID會導致您與代理斷開連接。或者自行生成一些獨特的東西,或者在Client()的呼叫中保留client_id,然後使用默認值None,這意味着客戶端ID是隨機生成的。

最後一件事 - 除非您有其他原因,否則不需要用主導斜槓啓動主題。主要的斜槓實際上增加了一個額外的層次,第一層是一個空字符串。這不完全是你所期望的,所以在某些情況下可能會令人困惑。

+0

感謝你非常多的指針。我使用龐特作爲經紀人,我認爲它需要主導的斜線,我不是一個測試的家。我會測試並讓你知道。 – Gregg

+0

(燈泡時刻!!!)你對客戶端id和on_message的解釋也可以解釋爲什麼我在arduino YUN上與mqtt作戰。再次,非常感謝您的指示,高度撥出。 – Gregg