Azure IoT Hub に paho で publish

Hub は、iot-aa
Device は pansy
と設定されている Azure IoT Hub に paho でpublish するサンプルです。
サンプルは２つあります。

サンプル１

```py3:paho_publish.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
#	paho_publish.py
#
#						Feb/05/2018
# ------------------------------------------------------------------
import	sys
import	ssl
import	paho.mqtt.publish as publish
import	paho.mqtt.client as mqtt

from generate_sas_token import generate_sas_token
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
uri = "iot-aa.azure-devices.net/devices/pansy"
key = "2eQ2wF5OjZLP7tq6PG123456789RTfAnMJbZ8wtJPu4="
policy_name = None
iexpire = 3600
sas_token = generate_sas_token(uri, key, policy_name, iexpire)
auth = {
	'username':"iot-aa.azure-devices.net/pansy/api-version=2018-06-30",
	'password': sas_token
	}

tls = {
	'ca_certs': "/etc/ssl/certs/ca-certificates.crt",
	'tls_version': ssl.PROTOCOL_TLSv1_2
	}
#
msg="Hello World Feb/05/2018"
try:
	publish.single("devices/pansy/messages/events/",
		payload=msg,
		hostname="iot-aa.azure-devices.net",
		client_id="pansy",
		auth=auth,
		tls=tls,
		port=8883,
		protocol=mqtt.MQTTv311)
except Exception as ee:
	sys.stderr.write("*** error *** in publish.single ***\n")
	sys.stderr.write(str(ee) + "\n")
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

サンプル　2

```py3:paho_ex01.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	paho_ex01.py
#
#					Feb/05/2018
# ------------------------------------------------------------------
import	sys
import	ssl
from	paho.mqtt import client as mqtt
from generate_sas_token import generate_sas_token
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
uri = "iot-aa.azure-devices.net/devices/pansy"
key = "2eQ2wF5OjZLP7tq6PG123456789RTfAnMJbZ8wtJPu4="
policy_name = None
iexpire = 3600
sas_token = generate_sas_token(uri, key, policy_name, iexpire)
#
path_to_root_cert = "/etc/ssl/certs/ca-certificates.crt"
#
client = mqtt.Client(client_id="pansy", protocol=mqtt.MQTTv311)

client.username_pw_set(username="iot-aa.azure-devices.net/pansy", password=sas_token)

client.tls_set(ca_certs=path_to_root_cert, certfile=None, keyfile=None, cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)

client.tls_insecure_set(False)
host="iot-aa.azure-devices.net"
sys.stderr.write("host = " + host + "\n")

topic = "devices/pansy/messages/events/"
msg = '{"aa": "Hello","bb": "Good"}'
try:
	client.connect(host, port=8883)
	client.publish(topic, payload=msg)
	client.disconnect()
except Exception as ee:
	sys.stderr.write("*** error *** in client.connect ***\n")
	sys.stderr.write(str(ee) + "\n")
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

sas_token を計算するプログラム

```py3:generate_sas_token.py
# -*- 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))
	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
#
	rvalue = 'SharedAccessSignature ' + urlencode(rawtoken)
#
	return rvalue
#
# ------------------------------------------------------------------
```