parent
1765438bc1
commit
d694464419
4 changed files with 126 additions and 10 deletions
|
|
@ -52,6 +52,7 @@ class MQTTClient(object):
|
||||||
self.on_connect = None
|
self.on_connect = None
|
||||||
self.on_disconnect = None
|
self.on_disconnect = None
|
||||||
self.on_message = None
|
self.on_message = None
|
||||||
|
self.on_subscribe = None
|
||||||
# Initialize MQTT client.
|
# Initialize MQTT client.
|
||||||
self._client = mqtt.Client()
|
self._client = mqtt.Client()
|
||||||
if secure:
|
if secure:
|
||||||
|
|
@ -66,6 +67,7 @@ class MQTTClient(object):
|
||||||
self._client.on_message = self._mqtt_message
|
self._client.on_message = self._mqtt_message
|
||||||
self._connected = False
|
self._connected = False
|
||||||
|
|
||||||
|
|
||||||
def _mqtt_connect(self, client, userdata, flags, rc):
|
def _mqtt_connect(self, client, userdata, flags, rc):
|
||||||
logger.debug('Client on_connect called.')
|
logger.debug('Client on_connect called.')
|
||||||
# Check if the result code is success (0) or some error (non-zero) and
|
# Check if the result code is success (0) or some error (non-zero) and
|
||||||
|
|
@ -75,7 +77,7 @@ class MQTTClient(object):
|
||||||
self._connected = True
|
self._connected = True
|
||||||
print('Connected to Adafruit IO!')
|
print('Connected to Adafruit IO!')
|
||||||
else:
|
else:
|
||||||
# handle RC errors within `errors.py`'s MQTTError class
|
# handle RC errors within MQTTError class
|
||||||
raise MQTTError(rc)
|
raise MQTTError(rc)
|
||||||
# Call the on_connect callback if available.
|
# Call the on_connect callback if available.
|
||||||
if self.on_connect is not None:
|
if self.on_connect is not None:
|
||||||
|
|
@ -88,6 +90,7 @@ class MQTTClient(object):
|
||||||
# log the RC as an error. Continue on to call any disconnect handler
|
# log the RC as an error. Continue on to call any disconnect handler
|
||||||
# so clients can potentially recover gracefully.
|
# so clients can potentially recover gracefully.
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
|
print("Unexpected disconnection.")
|
||||||
raise MQTTError(rc)
|
raise MQTTError(rc)
|
||||||
print('Disconnected from Adafruit IO!')
|
print('Disconnected from Adafruit IO!')
|
||||||
# Call the on_disconnect callback if available.
|
# Call the on_disconnect callback if available.
|
||||||
|
|
@ -99,7 +102,7 @@ class MQTTClient(object):
|
||||||
# Parse out the feed id and call on_message callback.
|
# Parse out the feed id and call on_message callback.
|
||||||
# Assumes topic looks like "username/feeds/id"
|
# Assumes topic looks like "username/feeds/id"
|
||||||
parsed_topic = msg.topic.split('/')
|
parsed_topic = msg.topic.split('/')
|
||||||
if self.on_message is not None and self._username == parsed_topic[0]:
|
if self.on_message is not None:
|
||||||
feed = parsed_topic[2]
|
feed = parsed_topic[2]
|
||||||
payload = '' if msg.payload is None else msg.payload.decode('utf-8')
|
payload = '' if msg.payload is None else msg.payload.decode('utf-8')
|
||||||
elif self.on_message is not None and parsed_topic[0] == 'time':
|
elif self.on_message is not None and parsed_topic[0] == 'time':
|
||||||
|
|
@ -107,6 +110,10 @@ class MQTTClient(object):
|
||||||
payload = msg.payload.decode('utf-8')
|
payload = msg.payload.decode('utf-8')
|
||||||
self.on_message(self, feed, payload)
|
self.on_message(self, feed, payload)
|
||||||
|
|
||||||
|
def _mqtt_subscribe(client, userdata, mid, granted_qos):
|
||||||
|
"""Called when broker responds to a subscribe request."""
|
||||||
|
|
||||||
|
|
||||||
def connect(self, **kwargs):
|
def connect(self, **kwargs):
|
||||||
"""Connect to the Adafruit.IO service. Must be called before any loop
|
"""Connect to the Adafruit.IO service. Must be called before any loop
|
||||||
or publish operations are called. Will raise an exception if a
|
or publish operations are called. Will raise an exception if a
|
||||||
|
|
@ -162,16 +169,24 @@ class MQTTClient(object):
|
||||||
"""
|
"""
|
||||||
self._client.loop(timeout=timeout_sec)
|
self._client.loop(timeout=timeout_sec)
|
||||||
|
|
||||||
def subscribe(self, feed_id):
|
def subscribe(self, feed_id, feed_user=None):
|
||||||
"""Subscribe to changes on the specified feed. When the feed is updated
|
"""Subscribe to changes on the specified feed. When the feed is updated
|
||||||
the on_message function will be called with the feed_id and new value.
|
the on_message function will be called with the feed_id and new value.
|
||||||
|
|
||||||
|
Params:
|
||||||
|
- feed_id: The id of the feed to update.
|
||||||
|
- feed_user (optional): The user id of the feed. Used for feed sharing.
|
||||||
"""
|
"""
|
||||||
self._client.subscribe('{0}/feeds/{1}'.format(self._username, feed_id))
|
if feed_user is not None:
|
||||||
|
(res, mid) = self._client.subscribe('{0}/feeds/{1}'.format(feed_user, feed_id))
|
||||||
|
else:
|
||||||
|
(res, mid) = self._client.subscribe('{0}/feeds/{1}'.format(self._username, feed_id))
|
||||||
|
return res, mid
|
||||||
|
|
||||||
def subscribe_time(self, time):
|
def subscribe_time(self, time):
|
||||||
"""Subscribe to changes on the Adafruit IO time feeds. When the feed is
|
"""Subscribe to changes on the Adafruit IO time feeds. When the feed is
|
||||||
updated, the on_message function will be called and publish a new value:
|
updated, the on_message function will be called and publish a new value:
|
||||||
time =
|
time feeds:
|
||||||
millis: milliseconds
|
millis: milliseconds
|
||||||
seconds: seconds
|
seconds: seconds
|
||||||
iso: ISO-8601 (https://en.wikipedia.org/wiki/ISO_8601)
|
iso: ISO-8601 (https://en.wikipedia.org/wiki/ISO_8601)
|
||||||
|
|
@ -181,15 +196,27 @@ class MQTTClient(object):
|
||||||
elif time == 'iso':
|
elif time == 'iso':
|
||||||
self._client.subscribe('time/ISO-8601')
|
self._client.subscribe('time/ISO-8601')
|
||||||
else:
|
else:
|
||||||
print('ERROR: Invalid time type specified')
|
raise TypeError('Invalid Time Feed Specified.')
|
||||||
return
|
return
|
||||||
|
|
||||||
def publish(self, feed_id, value):
|
def unsubscribe(self, feed_id):
|
||||||
|
"""Unsubscribes from a specified MQTT feed.
|
||||||
|
Note: this does not prevent publishing to a feed, it will unsubscribe
|
||||||
|
from receiving messages via on_message.
|
||||||
|
"""
|
||||||
|
(res, mid) = self._client.unsubscribe('{0}/feeds/{1}'.format(self._username, feed_id))
|
||||||
|
|
||||||
|
def publish(self, feed_id, value=None, feed_user=None):
|
||||||
"""Publish a value to a specified feed.
|
"""Publish a value to a specified feed.
|
||||||
|
|
||||||
Required parameters:
|
Params:
|
||||||
- feed_id: The id of the feed to update.
|
- feed_id: The id of the feed to update.
|
||||||
|
- feed_user (optional): The user id of the feed. Used for feed sharing.
|
||||||
- value: The new value to publish to the feed.
|
- value: The new value to publish to the feed.
|
||||||
"""
|
"""
|
||||||
self._client.publish('{0}/feeds/{1}'.format(self._username, feed_id),
|
if feed_user is not None:
|
||||||
payload=value)
|
(res, self._pub_mid) = self._client.publish('{0}/feeds/{1}'.format(feed_user, feed_id),
|
||||||
|
payload=value)
|
||||||
|
else:
|
||||||
|
(res, self._pub_mid) = self._client.publish('{0}/feeds/{1}'.format(self._username, feed_id),
|
||||||
|
payload=value)
|
||||||
14
docs/feed-sharing.rst
Normal file
14
docs/feed-sharing.rst
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
Feed Sharing
|
||||||
|
------------
|
||||||
|
Feed sharing is a feature of Adafruit IO which allows you to share your feeds with people you specify.
|
||||||
|
|
||||||
|
If you want to share a feed on your Adafruit IO Account with another user, visit the `Sharing a feed page <https://learn.adafruit.com/adafruit-io-basics-feeds/sharing-a-feed>`_
|
||||||
|
on the Adafruit Learning System.
|
||||||
|
|
||||||
|
The Adafruit IO Python client supports Feed Sharing in the mqtt_client.py class.
|
||||||
|
|
||||||
|
Usage Example
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
.. literalinclude:: ../examples/mqtt/mqtt_shared_feeds.py
|
||||||
|
|
@ -22,6 +22,7 @@ Table of Contents
|
||||||
:maxdepth: 6
|
:maxdepth: 6
|
||||||
|
|
||||||
feeds
|
feeds
|
||||||
|
feed-sharing
|
||||||
data
|
data
|
||||||
groups
|
groups
|
||||||
|
|
||||||
|
|
|
||||||
74
examples/mqtt/mqtt_shared_feeds.py
Normal file
74
examples/mqtt/mqtt_shared_feeds.py
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
"""
|
||||||
|
`mqtt_shared_feeds.py`
|
||||||
|
---------------------------------------------------------
|
||||||
|
Example of reading and writing to a shared Adafruit IO Feed.
|
||||||
|
|
||||||
|
learn.adafruit.com/adafruit-io-basics-feeds/sharing-a-feed
|
||||||
|
|
||||||
|
Author: Brent Rubell for Adafruit Industries 2018
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Import standard python modules.
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
|
||||||
|
# Import Adafruit IO MQTT client.
|
||||||
|
from Adafruit_IO import MQTTClient
|
||||||
|
|
||||||
|
# Set to your Adafruit IO key.
|
||||||
|
# Remember, your key is a secret,
|
||||||
|
# so make sure not to publish it when you publish this code!
|
||||||
|
ADAFRUIT_IO_KEY = 'YOUR_AIO_KEY'
|
||||||
|
|
||||||
|
# Set to your Adafruit IO username.
|
||||||
|
# (go to https://accounts.adafruit.com to find your username)
|
||||||
|
ADAFRUIT_IO_USERNAME = 'YOUR_AIO_USERNAME'
|
||||||
|
|
||||||
|
# Shared IO Feed
|
||||||
|
# Make sure you have read AND write access to this feed to publish.
|
||||||
|
IO_FEED = 'SHARED_AIO_FEED_NAME'
|
||||||
|
|
||||||
|
# IO Feed Owner's username
|
||||||
|
IO_FEED_USERNAME = 'SHARED_AIO_FEED_USERNAME'
|
||||||
|
|
||||||
|
|
||||||
|
# Define callback functions which will be called when certain events happen.
|
||||||
|
def connected(client):
|
||||||
|
"""Connected function will be called when the client connects.
|
||||||
|
"""
|
||||||
|
client.subscribe(IO_FEED, IO_FEED_USERNAME)
|
||||||
|
|
||||||
|
def disconnected(client):
|
||||||
|
"""Disconnected function will be called when the client disconnects.
|
||||||
|
"""
|
||||||
|
print('Disconnected from Adafruit IO!')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def message(client, feed_id, payload):
|
||||||
|
"""Message function will be called when a subscribed feed has a new value.
|
||||||
|
The feed_id parameter identifies the feed, and the payload parameter has
|
||||||
|
the new value.
|
||||||
|
"""
|
||||||
|
print('Feed {0} received new value: {1}'.format(feed_id, payload))
|
||||||
|
|
||||||
|
|
||||||
|
# Create an MQTT client instance.
|
||||||
|
client = MQTTClient(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)
|
||||||
|
|
||||||
|
# Setup the callback functions defined above.
|
||||||
|
client.on_connect = connected
|
||||||
|
client.on_disconnect = disconnected
|
||||||
|
client.on_message = message
|
||||||
|
|
||||||
|
# Connect to the Adafruit IO server.
|
||||||
|
client.connect()
|
||||||
|
|
||||||
|
client.loop_background()
|
||||||
|
print('Publishing a new message every 10 seconds (press Ctrl-C to quit)...')
|
||||||
|
|
||||||
|
while True:
|
||||||
|
value = random.randint(0, 100)
|
||||||
|
print('Publishing {0} to {1}.'.format(value, IO_FEED))
|
||||||
|
client.publish(IO_FEED, value, IO_FEED_USERNAME)
|
||||||
|
time.sleep(10)
|
||||||
Loading…
Reference in a new issue