Skip to content

Commit 7de8fd6

Browse files
authored
Merge pull request #76 from adafruit/mqtt-group-get
Adding Group Features to mqtt_client.py
2 parents da00252 + 9c5399c commit 7de8fd6

File tree

3 files changed

+123
-24
lines changed

3 files changed

+123
-24
lines changed

Adafruit_IO/_version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "2.0.16"
1+
__version__ = "2.0.17"

Adafruit_IO/mqtt_client.py

+42-23
Original file line numberDiff line numberDiff line change
@@ -99,21 +99,24 @@ def _mqtt_disconnect(self, client, userdata, rc):
9999

100100
def _mqtt_message(self, client, userdata, msg):
101101
logger.debug('Client on_message called.')
102-
# Parse out the feed id and call on_message callback.
103-
# Assumes topic looks like "username/feeds/id"
102+
"""Parse out the topic and call on_message callback
103+
assume topic looks like `username/topic/id`
104+
"""
104105
parsed_topic = msg.topic.split('/')
105106
if self.on_message is not None:
106-
feed = parsed_topic[2]
107+
topic = parsed_topic[2]
107108
payload = '' if msg.payload is None else msg.payload.decode('utf-8')
108109
elif self.on_message is not None and parsed_topic[0] == 'time':
109-
feed = parsed_topic[0]
110+
topic = parsed_topic[0]
111+
payload = msg.payload.decode('utf-8')
112+
elif self.on_message is not None and parsed_topic[1] == 'groups':
113+
topic = parsed_topic[3]
110114
payload = msg.payload.decode('utf-8')
111-
self.on_message(self, feed, payload)
115+
self.on_message(self, topic, payload)
112116

113117
def _mqtt_subscribe(client, userdata, mid, granted_qos):
114118
"""Called when broker responds to a subscribe request."""
115119

116-
117120
def connect(self, **kwargs):
118121
"""Connect to the Adafruit.IO service. Must be called before any loop
119122
or publish operations are called. Will raise an exception if a
@@ -179,15 +182,21 @@ def subscribe(self, feed_id, feed_user=None):
179182
the on_message function will be called with the feed_id and new value.
180183
181184
Params:
182-
- feed_id: The id of the feed to update.
183-
- feed_user (optional): The user id of the feed. Used for feed sharing.
185+
- feed_id: The id of the feed to subscribe to.
186+
- feed_user (optional): The user id of the feed. Used for feed sharing functionality.
184187
"""
185188
if feed_user is not None:
186189
(res, mid) = self._client.subscribe('{0}/feeds/{1}'.format(feed_user, feed_id))
187190
else:
188191
(res, mid) = self._client.subscribe('{0}/feeds/{1}'.format(self._username, feed_id))
189192
return res, mid
190193

194+
def subscribe_group(self, group_id):
195+
"""Subscribe to changes on the specified group. When the group is updated
196+
the on_message function will be called with the group_id and the new value.
197+
"""
198+
self._client.subscribe('{0}/groups/{1}'.format(self._username, group_id))
199+
191200
def subscribe_time(self, time):
192201
"""Subscribe to changes on the Adafruit IO time feeds. When the feed is
193202
updated, the on_message function will be called and publish a new value:
@@ -204,24 +213,34 @@ def subscribe_time(self, time):
204213
raise TypeError('Invalid Time Feed Specified.')
205214
return
206215

207-
def unsubscribe(self, feed_id):
208-
"""Unsubscribes from a specified MQTT feed.
209-
Note: this does not prevent publishing to a feed, it will unsubscribe
210-
from receiving messages via on_message.
211-
"""
212-
(res, mid) = self._client.unsubscribe('{0}/feeds/{1}'.format(self._username, feed_id))
213-
214-
def publish(self, feed_id, value=None, feed_user=None):
216+
def unsubscribe(self, feed_id=None, group_id=None):
217+
"""Unsubscribes from a specified MQTT topic.
218+
Note: this does not prevent publishing to a topic, it will unsubscribe
219+
from receiving messages via on_message.
220+
"""
221+
if feed_id is not None:
222+
self._client.unsubscribe('{0}/feeds/{1}'.format(self._username, feed_id))
223+
elif group_id is not None:
224+
self._client.unsubscribe('{0}/groups/{1}'.format(self._username, group_id))
225+
else:
226+
raise TypeError('Invalid topic type specified.')
227+
return
228+
229+
def publish(self, feed_id, value=None, group_id=None, feed_user=None):
215230
"""Publish a value to a specified feed.
216231
217232
Params:
218233
- feed_id: The id of the feed to update.
219-
- feed_user (optional): The user id of the feed. Used for feed sharing.
220234
- value: The new value to publish to the feed.
235+
- (optional) group_id: The id of the group to update.
236+
- (optional) feed_user: The feed owner's username. Used for Sharing Feeds.
221237
"""
222-
if feed_user is not None:
223-
(res, self._pub_mid) = self._client.publish('{0}/feeds/{1}'.format(feed_user, feed_id),
224-
payload=value)
225-
else:
226-
(res, self._pub_mid) = self._client.publish('{0}/feeds/{1}'.format(self._username, feed_id),
227-
payload=value)
238+
if feed_user is not None: # shared feed
239+
(res, self._pub_mid) = self._client.publish('{0}/feeds/{1}'.format(feed_user, feed_id),
240+
payload=value)
241+
elif group_id is not None: # group-specified feed
242+
self._client.publish('{0}/feeds/{1}.{2}'.format(self._username, group_id, feed_id),
243+
payload=value)
244+
else: # regular feed
245+
(res, self._pub_mid) = self._client.publish('{0}/feeds/{1}'.format(self._username, feed_id),
246+
payload=value)

examples/mqtt/mqtt_groups_pusbsub.py

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Example of subscribing to an Adafruit IO group
2+
# and publishing to the feeds within it
3+
4+
# Author: Brent Rubell for Adafruit Industries, 2018
5+
6+
# Import standard python modules.
7+
import random
8+
import sys
9+
import time
10+
11+
# Import Adafruit IO MQTT client.
12+
from Adafruit_IO import MQTTClient
13+
14+
# Set to your Adafruit IO key.
15+
# Remember, your key is a secret,
16+
# so make sure not to publish it when you publish this code!
17+
ADAFRUIT_IO_KEY = 'YOUR_AIO_KEY'
18+
19+
# Set to your Adafruit IO username.
20+
# (go to https://accounts.adafruit.com to find your username)
21+
ADAFRUIT_IO_USERNAME = 'YOUR_AIO_USERNAME'
22+
23+
# Group Name
24+
group_name = 'grouptest'
25+
26+
# Feeds within the group
27+
group_feed_one = 'one'
28+
group_feed_two = 'two'
29+
30+
# Define callback functions which will be called when certain events happen.
31+
def connected(client):
32+
# Connected function will be called when the client is connected to Adafruit IO.
33+
# This is a good place to subscribe to topic changes. The client parameter
34+
# passed to this function is the Adafruit IO MQTT client so you can make
35+
# calls against it easily.
36+
print('Listening for changes on ', group_name)
37+
# Subscribe to changes on a group, `group_name`
38+
client.subscribe_group(group_name)
39+
40+
def disconnected(client):
41+
# Disconnected function will be called when the client disconnects.
42+
print('Disconnected from Adafruit IO!')
43+
sys.exit(1)
44+
45+
def message(client, topic_id, payload):
46+
# Message function will be called when a subscribed topic has a new value.
47+
# The topic_id parameter identifies the topic, and the payload parameter has
48+
# the new value.
49+
print('Topic {0} received new value: {1}'.format(topic_id, payload))
50+
51+
52+
# Create an MQTT client instance.
53+
client = MQTTClient(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)
54+
55+
# Setup the callback functions defined above.
56+
client.on_connect = connected
57+
client.on_disconnect = disconnected
58+
client.on_message = message
59+
60+
# Connect to the Adafruit IO server.
61+
client.connect()
62+
63+
# Now the program needs to use a client loop function to ensure messages are
64+
# sent and received. There are a few options for driving the message loop,
65+
# depending on what your program needs to do.
66+
67+
# The first option is to run a thread in the background so you can continue
68+
# doing things in your program.
69+
client.loop_background()
70+
# Now send new values every 5 seconds.
71+
print('Publishing a new message every 5 seconds (press Ctrl-C to quit)...')
72+
while True:
73+
value = random.randint(0, 100)
74+
print('Publishing {0} to {1}.{2}.'.format(value, group_name, group_feed_one))
75+
client.publish('one', value, group_name)
76+
77+
value = random.randint(0,100)
78+
print('Publishing {0} to {1}.{2}.'.format(value, group_name, group_feed_two))
79+
client.publish('two', value, group_name)
80+
time.sleep(5)

0 commit comments

Comments
 (0)