Beware that many examples declare some log function, but don’t actually make the Paho MQTT library use it. As Paho tends to swallow many exceptions in callbacks, enabling logging surely helps finding even basic typing errors.
For the above examples, add the last line below:
mqttc = mqtt.Client()
# Assign event callbacks
mqttc.on_connect = on_connect
mqttc.on_message = on_message
# Log all MQTT protocol events, and the exceptions in callbacks
# that have been caught by Paho
mqttc.on_log = on_log
When using Python’s logging, you can convert the log level of the Paho message to Python’s logging level, using:
import logging
...
def on_log(self, client, userdata, level, buf):
"""
Log all MQTT protocol events, and the exceptions in callbacks
that have been caught by Paho.
"""
logging_level = mqtt.LOGGING_LEVEL[level]
logging.log(logging_level, buf)
Note that on_connect
does not guarantee one is indeed connected:
def on_connect(self, client, userdata, flags, rc):
logging.info("MQTT connected: result code=%i", rc)
if rc == 0:
res = client.subscribe("+/devices/+/up")
if res[0] != mqtt.MQTT_ERR_SUCCESS:
raise RuntimeError("the client is not connected")
if rc == 1:
raise RuntimeError("connection failed: incorrect protocol version")
if rc == 2:
raise RuntimeError("connection failed: invalid client identifier")
if rc == 3:
raise RuntimeError("connection failed: server unavailable")
if rc == 4:
raise RuntimeError("connection failed: bad app_id or access_key")
if rc == 5:
raise RuntimeError("connection failed: not authorised")
# 6 - 255: currently unused
Also, you might want to use TLS (and port 8883 rather than the non-TLS 1883). Just replacing the line for mqttc.connect
with the following will do:
# By default, on Python 2.7.9+ or 3.4+, the default certification
# authority of the system is used.
mqttc.tls_set()
mqttc.connect("eu.thethings.network", 8883, 60)
Alternatively, explicitly refer to the Certificate Authority chain as used by the Let’s Encrypt server certificate, which is available in https://console.thethingsnetwork.org/mqtt-ca.pem:
mqttc.tls_set(ca_certs="mqtt-ca.pem")
For all of the above, when looking at the (deprecated) TTN SDK, add something like:
import logging
import paho.mqtt.client as mqtt
...
class MQTTClient:
...
def connect(self):
self.__client.on_log = self._on_log
...
def _on_log(self, client, userdata, level, buf):
"""
Log all MQTT protocol events, and the exceptions in callbacks
that have been caught by Paho.
"""
logging_level = mqtt.LOGGING_LEVEL[level]
logging.log(logging_level, buf)
And for TLS add the following somewhere before self.__client.connect
:
self.__client.tls_set()