Raspberry Pi

樹莓派安裝MQTT伺服器

MQTT是一個非常流行的網路傳輸協定,在物聯網的世界中,可以利用它來傳送感測器所取得的資料到另外一個節點,也可以利用它來控制遠端的裝置或電路。它是一種Publish/Subscribe機制的傳輸協定,也就是所謂的「發佈/訂閱」機制。資訊來源端利用「發佈」功能把想要傳出去的資料透過某一個「主題(Topic)」傳送出去,在同一個網段的節點只要到伺服器上「訂閱」這個「主題」,就可以獲得資訊來源端所傳送出來的資料。

為了使用MQTT,發佈端和訂閱端中間要有一個中介的伺服器,也就是MQTT的伺服器,兩端的節點都必需要能夠連得到MQTT伺服器,彼此之間才能夠相互傳遞資料。在此例中,我們可以利用以下的指令在樹莓派上安裝MQTT伺服器公及客戶端:

sudo apt install mosquitto mosquitto-clients -y

安裝完成之後,在樹莓派上就有一個運行中的MQTT伺服器,它是系統的服務,所以可以利用以下的指令查詢目前伺服器的運作狀態:

sudo service mosquitto status

順利的話可以看到以下的訊息:

要測試MQTT伺服器是否能夠正常地運作,需要兩個不同的終端機,在其中一個終端機請執行以下的指令,用來訂閱「minhuang/test」這個主題:

mosquitto_sub -t minhuang/test

上述的指令會處於一個等待接收訊息的狀態,此時,請在另外一個終端機則可以執行以下的指令,對主題「minhuang/test」發佈訊息:

mosquitto_pub -t minhuang/test -m "Hello"

上述指令執行之後,在前一個終端機中就可以看到訊息"Hello"被傳遞過去了。

當然,在終端機中進行訊息的傳輸並沒有那麼地方便,因為我們的感測器取得的方法都是在Python程式中進行,所以也需要可以在Python語言中可以傳送資料才行。在Python語言中有一個叫做paho_mqtt模組可以做這件事。請使用以下的指令安裝:

pip install paho_mqtt

然後利用以下的程式即可傳送資料到剛剛那個主題(mqtt_pub.py):

import paho.mqtt.client as mqtt
client = mqtt.Client()
client.connect("127.0.0.1", 1883, 60)
client.publish("minhuang/test", "Hello")

如果需要可以讓我們在Python程式執行時可以透過命令列參數的方式傳遞想要的訊息,則可以把上述的程式修改如下(mqtt_pub.py),本程式可以在Windows 10作業系統下執行:

import sys
import paho.mqtt.client as mqtt
client = mqtt.Client()
client.connect("192.168.132.224", 1883, 60)
if len(sys.argv)>1:
    client.publish("minhuang/test", sys.argv[1])
else:
    client.publish("minhuang/test", "Hello")

如果想要寫一個可以接收MQTT的Python程式,則可以參考以下這個範例(mqtt_sub.py):

import paho.mqtt.client as mqtt
SERVER = "127.0.0.1"
PORT = 1883
TOPIC = "minhuang/test"

def on_connect(client, userdata, flags, rc):
    client.subscribe(TOPIC)

def on_message(client, userdata, msg):
    print("{}:{}".format(msg.topic,msg.payload.decode("utf-8")))

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(SERVER, PORT, 60)
client.loop_forever()

如果我們想要讓外部的程式可以透過MQTT控制樹莓派上的IO,以下是一個控制LED明滅的範例程式(mqtt_sub_led.py):

import paho.mqtt.client as mqtt
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.OUT)

SERVER = "127.0.0.1"
PORT = 1883
TOPIC = "minhuang/test"

def on_connect(client, userdata, flags, rc):
    client.subscribe(TOPIC)

def on_message(client, userdata, msg):
    data = msg.payload.decode("utf-8")
    print("{}:{}".format(msg.topic,data))
    if data=="1":
        GPIO.output(17, 1)
    elif data == "0":
        GPIO.output(17, 0)


client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(SERVER, PORT, 60)
client.loop_forever()
GPIO.cleanup()

上述這個程式執行之後它會接收指令,如果是0或1的話,就會去開啟或關閉LED。

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s