Azure IoT Hub に mosquitto で接続


次のページを参考にしました。
Azure IoT Hubを生MQTTS(mosquitto)やHTTP RESTで使う方法
相違点は、SharedAccessSignature を作成するプログラムを python3 にしたことです。

この例では、
Hub は、iot-aa
Device は pansy
です。

mosuquitto で Publish している画面

mosquitto で Subscribe している画面

AWS Console で Publish する画面

その時の、mosquitto で Subscribe している画面

go_pub.sh
#
#   go_pub.sh
#
mosquitto_pub -d -q 1 --capath /etc/ssl/certs/ -V mqttv311 -p 8883 \
  -h iot-aa.azure-devices.net \
  -i pansy \
  -u "iot-aa.azure-devices.net/pansy/api-version=2018-06-30" \
  -P "SharedAccessSignature sr=iot-aa.azure-devices.net%2Fdevices%2Fpansy&sig=qT%2BsUvazRdvyrTVq0ENZNU%3D&se=1517800537" \
  -t "devices/pansy/messages/events/" \
  -m '{"v":1}'
go_sub.sh
#
mosquitto_sub -d -q 1 --capath /etc/ssl/certs/ -V mqttv311 -p 8883 \
  -h iot-aa.azure-devices.net \
  -i pansy \
  -u "iot-aa.azure-devices.net/pansy/api-version=2018-06-30" \
  -P "SharedAccessSignature sr=iot-aa.azure-devices.net%2Fdevices%2Fpansy&sig=qT%2BsUvazRdvxTVq0ENZNU%3D&se=1517800537" \
  -t "devices/pansy/messages/devicebound/#"
#

注意

mosquitto_subでsubscribeしておきつつ、mosquitto_pubをしても、メッセージの受信はできません。
IoT Hub はフル機能の MQTT ブローカーではないため、MQTT v3.1.1 標準で指定されているすべての動作をサポートしているわけではありません。

SharedAccessSignature を作成するプログラム

generate_sas_token.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#   generate_sas_token.py
#
#                       Feb/05/2018
# ------------------------------------------------------------------
from base64 import b64encode, b64decode
from hashlib import sha256
from time import time
from urllib.parse import quote_plus, urlencode
from hmac import HMAC

# ------------------------------------------------------------------
def generate_sas_token(uri, key, policy_name, expiry=3600):
    ttl = time() + expiry
    sign_key = "%s\n%d" % ((quote_plus(uri)), int(ttl))
    print(sign_key)
    signature = b64encode(HMAC(b64decode(key), sign_key.encode("utf-8"), sha256).digest())

    rawtoken = {
        'sr' :  uri,
        'sig': signature,
        'se' : str(int(ttl))
    }

    if policy_name is not None:
        rawtoken['skn'] = policy_name

    return 'SharedAccessSignature ' + urlencode(rawtoken)

# ------------------------------------------------------------------
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-u", "--uri", dest="uri", help="URI", metavar="URI")
parser.add_option("-k", "--key", dest="key", help="KEY", metavar="KEY")
parser.add_option("-c", "--policy", dest="policy_name", help="Policy Name", metavar="POLICY_NAME")
parser.add_option("-a", "--age", dest="age", help="Age of Token (sec)", metavar="AGE", default=3600)
(options, args) = parser.parse_args()
print(generate_sas_token(options.uri, options.key, options.policy_name, int(options.age)))
# ------------------------------------------------------------------

使い方

./generate_sas_token.py \
  -u iot-aa.azure-devices.net/devices/pansy \
  -k 2eQ2wF5Oabcdeftq6PG3CGJNXF5123456789Z8wtJPu4=

-k の後には、デバイスの詳細で表示される 主キーを入れて下さい。

参考
azure-cli の拡張機能のインストール

az extension add --name azure-cli-iot-ext

sas-token の取得

az iot hub generate-sas-token -n iot-aa

関連ページ
Raspberry Pi で paho-mqtt を使う