2121import logging
2222
2323import paho .mqtt .client as mqtt
24-
24+ import sys
25+ from .errors import MQTTError , RequestError
2526
2627# How long to wait before sending a keep alive (paho-mqtt configuration).
2728KEEP_ALIVE_SEC = 60 # One minute
@@ -34,23 +35,29 @@ class MQTTClient(object):
3435 using the MQTT protocol.
3536 """
3637
37- def __init__ (self , username , key , service_host = 'io.adafruit.com' , service_port = 1883 ):
38+ def __init__ (self , username , key , service_host = 'io.adafruit.com' , secure = True ):
3839 """Create instance of MQTT client.
3940
40- Required parameters:
41- - username: The Adafruit.IO username for your account (found on the
42- accounts site https://accounts.adafruit.com/).
43- - key: The Adafruit.IO access key for your account.
41+ :param username: Adafruit.IO Username for your account.
42+ :param key: Adafruit IO access key (AIO Key) for your account.
43+ :param secure: (optional, boolean) Switches secure/insecure connections
4444 """
4545 self ._username = username
4646 self ._service_host = service_host
47- self ._service_port = service_port
47+ if secure :
48+ self ._service_port = 8883
49+ elif not secure :
50+ self ._service_port = 1883
4851 # Initialize event callbacks to be None so they don't fire.
4952 self .on_connect = None
5053 self .on_disconnect = None
5154 self .on_message = None
5255 # Initialize MQTT client.
5356 self ._client = mqtt .Client ()
57+ if secure :
58+ self ._client .tls_set_context ()
59+ elif not secure :
60+ print ('**THIS CONNECTION IS INSECURE** SSL/TLS not supported for this platform' )
5461 self ._client .username_pw_set (username , key )
5562 self ._client .on_connect = self ._mqtt_connect
5663 self ._client .on_disconnect = self ._mqtt_disconnect
@@ -62,11 +69,12 @@ def _mqtt_connect(self, client, userdata, flags, rc):
6269 # Check if the result code is success (0) or some error (non-zero) and
6370 # raise an exception if failed.
6471 if rc == 0 :
72+ #raise RequestError(rc)
6573 self ._connected = True
74+ print ('Connected to Adafruit IO!' )
6675 else :
67- # TODO: Make explicit exception classes for these failures:
68- # 0: Connection successful 1: Connection refused - incorrect protocol version 2: Connection refused - invalid client identifier 3: Connection refused - server unavailable 4: Connection refused - bad username or password 5: Connection refused - not authorised 6-255: Currently unused.
69- raise RuntimeError ('Error connecting to Adafruit IO with rc: {0}' .format (rc ))
76+ # handle RC errors within `errors.py`'s MQTTError class
77+ raise MQTTError (rc )
7078 # Call the on_connect callback if available.
7179 if self .on_connect is not None :
7280 self .on_connect (self )
@@ -78,7 +86,8 @@ def _mqtt_disconnect(self, client, userdata, rc):
7886 # log the RC as an error. Continue on to call any disconnect handler
7987 # so clients can potentially recover gracefully.
8088 if rc != 0 :
81- logger .debug ('Unexpected disconnect with rc: {0}' .format (rc ))
89+ raise MQTTError (rc )
90+ print ('Disconnected from Adafruit IO!' )
8291 # Call the on_disconnect callback if available.
8392 if self .on_disconnect is not None :
8493 self .on_disconnect (self )
@@ -91,7 +100,10 @@ def _mqtt_message(self, client, userdata, msg):
91100 if self .on_message is not None and self ._username == parsed_topic [0 ]:
92101 feed = parsed_topic [2 ]
93102 payload = '' if msg .payload is None else msg .payload .decode ('utf-8' )
94- self .on_message (self , feed , payload )
103+ elif self .on_message is not None and parsed_topic [0 ] == 'time' :
104+ feed = parsed_topic [0 ]
105+ payload = msg .payload .decode ('utf-8' )
106+ self .on_message (self , feed , payload )
95107
96108 def connect (self , ** kwargs ):
97109 """Connect to the Adafruit.IO service. Must be called before any loop
@@ -154,6 +166,22 @@ def subscribe(self, feed_id):
154166 """
155167 self ._client .subscribe ('{0}/feeds/{1}' .format (self ._username , feed_id ))
156168
169+ def subscribe_time (self , time ):
170+ """Subscribe to changes on the Adafruit IO time feeds. When the feed is
171+ updated, the on_message function will be called and publish a new value:
172+ time =
173+ millis: milliseconds
174+ seconds: seconds
175+ iso: ISO-8601 (https://en.wikipedia.org/wiki/ISO_8601)
176+ """
177+ if time == 'millis' or time == 'seconds' :
178+ self ._client .subscribe ('time/{0}' .format (time ))
179+ elif time == 'iso' :
180+ self ._client .subscribe ('time/ISO-8601' )
181+ else :
182+ print ('ERROR: Invalid time type specified' )
183+ return
184+
157185 def publish (self , feed_id , value ):
158186 """Publish a value to a specified feed.
159187
0 commit comments