Based on the document "Using the MQTT protocol directly", you need
to download and reference the DigiCert Baltimore Root Certificate. This certificate is the one that Azure uses to secure the connection.
As you did in the publishing process like this:
client.tls_set(ca_certs=path_to_root_cert,
certfile=None, keyfile=None,
cert_reqs=ssl.CERT_REQUIRED,
tls_version=ssl.PROTOCOL_TLSv1,
ciphers=None)
Also, you need set username and password:
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" + device_id, password=sas_token)
At last, you can subscribe like this:
client.subscribe(topic=topic, qos=0)
Sample code for Security Keys authenticated device:
import paho.mqtt.client as mqtt
import ssl, random
from time import sleep
path_to_root_cert = "./certs/digicertbaltimoreroot.cer"
iothub_name = "your hub name"
device_id = "device1"
sas_token = "SharedAccessSignature sr=[your hub name].azure-devices.net%2Fdevices%2Fdevice1&sig=[sig]&se=1526955728"
mqtt_url = "{}.azure-devices.net".format(iothub_name)
mqtt_port = 8883
topic = "devices/{}/messages/devicebound/#".format(device_id)
def error_str(rc):
return "Some error occurred. {}: {}".format(rc, mqtt.error_string(rc))
def on_disconnect(unused_client, unused_userdata, rc):
print("on_disconnect", error_str(rc))
def on_connect(client, userdata, flags, response_code):
print("Connected with status: {0}".format(response_code))
client.subscribe(topic, 1)
def on_subscribe(client, userdata, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_message(client, userdata, msg):
print("Topic: {0} -- Payload: {1}".format(msg.topic, str(msg.payload)))
if __name__ == "__main__":
client = mqtt.Client(device_id, protocol=mqtt.MQTTv311)
client.username_pw_set(username=iothub_name+".azure-devices.net/" + device_id, 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, ciphers=None)
client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect
print("Connecting to Azure IoT Hub...")
client.connect(mqtt_url, mqtt_port, keepalive=60)
client.subscribe(topic=topic, qos=0)
client.loop_forever()
Sample code for x509 authenticated device:
(Need provide device certificate and private key files. No need SAS token as password; just leave it empty. But still need set username.)
import paho.mqtt.client as mqtt
import ssl, random
from time import sleep
root_ca = "./certs/digicertbaltimoreroot.cer"
public_crt = './certs/mydevice-public.pem'
private_key = './certs/mydevice-private.pem'
iothub_name = "your hub name"
device_id = "mydevice"
mqtt_url = "{}.azure-devices.net".format(iothub_name)
mqtt_port = 8883
topic = "devices/{}/messages/devicebound/#".format(device_id)
def error_str(rc):
return "Some error occurred. {}: {}".format(rc, mqtt.error_string(rc))
def on_disconnect(unused_client, unused_userdata, rc):
print("on_disconnect", error_str(rc))
def on_connect(client, userdata, flags, response_code):
print("Connected with status: {0}".format(response_code))
client.subscribe(topic, 1)
def on_subscribe(client, userdata, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_message(client, userdata, msg):
print("Topic: {0} -- Payload: {1}".format(msg.topic, str(msg.payload)))
if __name__ == "__main__":
client = mqtt.Client(device_id, protocol=mqtt.MQTTv311)
client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect
client.username_pw_set(username=iothub_name+".azure-devices.net/" + device_id, password="")
client.tls_set(root_ca,
certfile = public_crt,
keyfile = private_key,
cert_reqs = ssl.CERT_REQUIRED,
tls_version = ssl.PROTOCOL_TLSv1_2,
ciphers = None)
client.tls_insecure_set(False)
print("Connecting to Azure IoT Hub...")
client.connect(mqtt_url, mqtt_port, keepalive=60)
client.subscribe(topic=topic, qos=0)
client.loop_forever()
Note: The topic is "devices/{device-id}/messages/devicebound/#".
How to create device certificate files you can reference here.
Update: These sample code used to receive D2C messages that you can send like this for simple test:
From device explorer:
From azure portal:
Upate: Receive D2C messages:
As I pointed out in my comments, Azure IoT Hub is not generic MQTT brober, so you can't directly subscribe messages sent from the device.
To workaround it, you can use the Event Hubs-compatible endpoint exposed by the IoT Hub like "Read the telemetry from your hub
" part does. But unfortunately, Python doesn't support this way. You can use the iothub-explorer CLI utility or either create a Node.js or a .NET or Java event hub-based console app to read the device-to-cloud messages from IoT Hub.