Azure IoT Hub內建支援MQTT 3.1.1,當設備無法使用IoT Hub SDK時,我們可以透過直接操作MQTT協議對IoT Hub進行操作。
在官方文件中說明了如何使用MQTT存取IoT Hub的各項功能,不過實際上實作的時候可能或多或少還是會遇到一些狀況;這一篇文章我透過Paho這個MQTT Client的UI工具,直接透過MQTT去存取IoT Hub。
準備事項
l 首先建立一個IoT Hub,並使用Device Explorer工具建立一個Device其Id為device001
l 建立完成後,產生一組SAS Token,這組SAS Token看起來會像這樣
HostName=mqttdemo.azure-devices.net;DeviceId=device001;SharedAccessSignature=SharedAccessSignature sr=mqttdemo.azure-devices.net%2Fdevices%2Fdevice001&sig=xxxxxxxxxxxxxxxxxxg%3D&se=1487487603
l 為了要連上IoT Hub收送C2D/D2C訊息,我們需要一組MQTT使用的Username/Password與ClientId;其中
n Username請設定為{iothub-url}/{device id}/api-version=2016-11-14
u 以我的例子,看起來會像這樣子
mqttdemo.azure-devices.net/device001/api-version=2016-11-14
注意!其中的api-version=2016-11-14在官方文件上並沒有特別提到,但是如果你需要直接操作MQTT存取IoT Hub Device Management功能的話,這個後綴是必要的。
n Password為SAS token的黃色highlight處
HostName=mqttdemo.azure-devices.net;DeviceId=device001;SharedAccessSignature=SharedAccessSignature sr=mqttdemo.azure-devices.net%2Fdevices%2Fdevice001&sig=xxxxxxxxxxxxxxxxxxg%3D&se=1487487603
看起來會像這樣
SharedAccessSignature sr=mqttdemo.azure-devices.net%2Fdevices%2Fdevice001&sig=xxxxxxxxxxxxxxxxxxg%3D&se=1487487603
n ClientId即是Device ID
C2D/D2C訊息
l 將Paho配置如下
n 注意Server URI為ssl://<Iot Hub Url>:8883
l 接著,訂閱device001的C2D Topic如下,黃色的部分可以代換成我們自己的device Id
devices/device001/messages/devicebound/#
l 設備發布D2C訊息的topic為:$"devices/{DeviceID}/messages/devicebound/#"
例如:devices/device001/messages/events/
l 打開Device Explorer,針對device001啟動設備訊息監控
l 將Paho Client與IoT Hub連線
l 透過Paho Client對D2C Topic發布一條訊息
l 可以看到Device Explorer上收到了這筆訊息
l 使用Device Explorer對設備發送一條C2D訊息
l 可以看到Paho收到了這條訊息
Device Twin Properties
l 為了要能夠存取Twin Properties,首先我們必須先訂閱這個topic
$iothub/twin/res/#
l 接著要用Paho對下面這個Topic發送一筆空訊息
$iothub/twin/GET/?$rid={request id}
在這裡面,{request id}可以是任何字串;IoT Hub收到這個訊息之後,接下來的回應,都會針對這個rid做回應。
n 發送後,可以看到IoT Hub回應了目前設備的Twin Properties
l 注意這裡的Topic名稱,200表示結果的狀態碼為成功;其他可能的狀態碼可以參考官方文件的說明:https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support
l 接著,我要更新某個Reported Property;將要更新的Reported Property發布到這個Topic:
$iothub/twin/PATCH/properties/reported/?$rid={request id}
l 其訊息格式為Json,其中包含了所要更新的欄位,如果將欄位值設為null,則會將該欄位從IoT Hub中移除,例如:
{
"fanspeed": null,
"temperature": 60
}
l 打開Device Explorer,可以看到確實Reported Property被更新了
Direct Methods
l 首先訂閱$iothub/methods/POST/#以收到IoT Hub的Direct Method call
l 透過Device Explorer呼叫Direct Method時,實際上會將命令(Json文件,或是空值)發佈到$iothub/methods/POST/{method name}/?$rid={request id} 這個Topic;其中,request id為任意格式的字串
l 設備收到Direct Method呼叫之後,將回應發佈到$iothub/methods/res/{status}/?$rid={request id}
其中,request id必須為IoT Hub呼叫時所用的request id,status為狀態值。訊息內容為一個合法的Json文件或是空值