Merge branch 'api-v2' into v2-examples
This commit is contained in:
commit
66ea1f44eb
27 changed files with 927 additions and 506 deletions
23
.travis.yml
Normal file
23
.travis.yml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# .travis.yml for Adafruit IO Python Client Library
|
||||
|
||||
dist: trusty
|
||||
sudo: false
|
||||
language: python
|
||||
python:
|
||||
- "3.6"
|
||||
|
||||
cache:
|
||||
pip: true
|
||||
|
||||
install:
|
||||
- pip install pylint Sphinx sphinx-rtd-theme
|
||||
|
||||
script:
|
||||
# test adafruit_io_basics examples
|
||||
- pylint --disable=missing-docstring,invalid-name examples/aio_basics/*.py
|
||||
# test API examples
|
||||
pylint --disable=missing-docstring,invalid-name examples/api/*.py
|
||||
# test MQTT examples
|
||||
pylint --disable=missing-docstring,invalid-name examples/aio_basics/*.py
|
||||
# finally, let's build the docs
|
||||
- cd docs && sphinx-build -E -W -b html . _build/html
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2014 Adafruit Industries
|
||||
# Copyright (c) 2018 Adafruit Industries
|
||||
# Authors: Justin Cooper & Tony DiCola
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
|
@ -60,8 +60,11 @@ class Client(object):
|
|||
# constructing the path.
|
||||
self.base_url = base_url.rstrip('/')
|
||||
|
||||
def _compose_url(self, path):
|
||||
return '{0}/api/{1}/{2}/{3}'.format(self.base_url, self.api_version, self.username, path)
|
||||
def _compose_url(self, path, is_time=None):
|
||||
if not is_time:
|
||||
return '{0}/api/{1}/{2}/{3}'.format(self.base_url, self.api_version, self.username, path)
|
||||
else: # return a call to https://io.adafruit.com/api/v2/time/{unit}
|
||||
return '{0}/api/{1}/{2}'.format(self.base_url, self.api_version, path)
|
||||
|
||||
|
||||
def _handle_error(self, response):
|
||||
|
|
@ -78,12 +81,15 @@ class Client(object):
|
|||
headers.update(given)
|
||||
return headers
|
||||
|
||||
def _get(self, path):
|
||||
response = requests.get(self._compose_url(path),
|
||||
def _get(self, path, is_time=None):
|
||||
response = requests.get(self._compose_url(path, is_time),
|
||||
headers=self._headers({'X-AIO-Key': self.key}),
|
||||
proxies=self.proxies)
|
||||
self._handle_error(response)
|
||||
return response.json()
|
||||
if not is_time:
|
||||
return response.json()
|
||||
else: # time doesn't need to serialize into json, just return text
|
||||
return response.text
|
||||
|
||||
def _post(self, path, data):
|
||||
response = requests.post(self._compose_url(path),
|
||||
|
|
@ -130,6 +136,26 @@ class Client(object):
|
|||
"""
|
||||
return self.create_data(feed, Data(value=value))
|
||||
|
||||
def send_location_data(self, feed, value, lat, lon, ele):
|
||||
"""Sends locational data to a feed
|
||||
|
||||
args:
|
||||
- lat: latitude
|
||||
- lon: logitude
|
||||
- ele: elevation
|
||||
- (optional) value: value to send to the feed
|
||||
"""
|
||||
return self.create_data(feed, Data(value = value,lat=lat, lon=lon, ele=ele))
|
||||
|
||||
def receive_time(self, time):
|
||||
"""Returns the time from the Adafruit IO server.
|
||||
|
||||
args:
|
||||
- time (string): millis, seconds, ISO-8601
|
||||
"""
|
||||
timepath = "time/{0}".format(time)
|
||||
return self._get(timepath, is_time=True)
|
||||
|
||||
def receive(self, feed):
|
||||
"""Retrieve the most recent value for the specified feed. Feed can be a
|
||||
feed ID, feed key, or feed name. Returns a Data instance whose value
|
||||
|
|
|
|||
|
|
@ -21,6 +21,14 @@
|
|||
|
||||
import json
|
||||
|
||||
# MQTT RC Error Types
|
||||
MQTT_ERRORS = [ 'Connection successful',
|
||||
'Incorrect protocol version',
|
||||
'Invalid Client ID',
|
||||
'Server unavailable ',
|
||||
'Bad username or password',
|
||||
'Not authorized' ]
|
||||
|
||||
class AdafruitIOError(Exception):
|
||||
"""Base class for all Adafruit IO request failures."""
|
||||
pass
|
||||
|
|
@ -49,3 +57,11 @@ class ThrottlingError(AdafruitIOError):
|
|||
super(ThrottlingError, self).__init__("Exceeded the limit of Adafruit IO " \
|
||||
"requests in a short period of time. Please reduce the rate of requests " \
|
||||
"and try again later.")
|
||||
|
||||
class MQTTError(Exception):
|
||||
"""Handles connection attempt failed errors.
|
||||
"""
|
||||
def __init__(self, response):
|
||||
error = MQTT_ERRORS[response]
|
||||
super(MQTTError, self).__init__(error)
|
||||
pass
|
||||
|
|
@ -36,7 +36,10 @@ DATA_FIELDS = [ 'created_epoch',
|
|||
'feed_id',
|
||||
'expiration',
|
||||
'position',
|
||||
'id' ]
|
||||
'id',
|
||||
'lat',
|
||||
'lon',
|
||||
'ele']
|
||||
|
||||
FEED_FIELDS = [ 'name',
|
||||
'key',
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@
|
|||
import logging
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
import sys
|
||||
from .errors import MQTTError, RequestError
|
||||
|
||||
# How long to wait before sending a keep alive (paho-mqtt configuration).
|
||||
KEEP_ALIVE_SEC = 60 # One minute
|
||||
|
|
@ -34,23 +35,29 @@ class MQTTClient(object):
|
|||
using the MQTT protocol.
|
||||
"""
|
||||
|
||||
def __init__(self, username, key, service_host='io.adafruit.com', service_port=1883):
|
||||
def __init__(self, username, key, service_host='io.adafruit.com', secure=True):
|
||||
"""Create instance of MQTT client.
|
||||
|
||||
Required parameters:
|
||||
- username: The Adafruit.IO username for your account (found on the
|
||||
accounts site https://accounts.adafruit.com/).
|
||||
- key: The Adafruit.IO access key for your account.
|
||||
:param username: Adafruit.IO Username for your account.
|
||||
:param key: Adafruit IO access key (AIO Key) for your account.
|
||||
:param secure: (optional, boolean) Switches secure/insecure connections
|
||||
"""
|
||||
self._username = username
|
||||
self._service_host = service_host
|
||||
self._service_port = service_port
|
||||
if secure:
|
||||
self._service_port = 8883
|
||||
elif not secure:
|
||||
self._service_port = 1883
|
||||
# Initialize event callbacks to be None so they don't fire.
|
||||
self.on_connect = None
|
||||
self.on_disconnect = None
|
||||
self.on_message = None
|
||||
# Initialize MQTT client.
|
||||
self._client = mqtt.Client()
|
||||
if secure:
|
||||
self._client.tls_set_context()
|
||||
elif not secure:
|
||||
print('**THIS CONNECTION IS INSECURE** SSL/TLS not supported for this platform')
|
||||
self._client.username_pw_set(username, key)
|
||||
self._client.on_connect = self._mqtt_connect
|
||||
self._client.on_disconnect = self._mqtt_disconnect
|
||||
|
|
@ -62,11 +69,12 @@ class MQTTClient(object):
|
|||
# Check if the result code is success (0) or some error (non-zero) and
|
||||
# raise an exception if failed.
|
||||
if rc == 0:
|
||||
#raise RequestError(rc)
|
||||
self._connected = True
|
||||
print('Connected to Adafruit IO!')
|
||||
else:
|
||||
# TODO: Make explicit exception classes for these failures:
|
||||
# 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.
|
||||
raise RuntimeError('Error connecting to Adafruit IO with rc: {0}'.format(rc))
|
||||
# handle RC errors within `errors.py`'s MQTTError class
|
||||
raise MQTTError(rc)
|
||||
# Call the on_connect callback if available.
|
||||
if self.on_connect is not None:
|
||||
self.on_connect(self)
|
||||
|
|
@ -78,7 +86,8 @@ class MQTTClient(object):
|
|||
# log the RC as an error. Continue on to call any disconnect handler
|
||||
# so clients can potentially recover gracefully.
|
||||
if rc != 0:
|
||||
logger.debug('Unexpected disconnect with rc: {0}'.format(rc))
|
||||
raise MQTTError(rc)
|
||||
print('Disconnected from Adafruit IO!')
|
||||
# Call the on_disconnect callback if available.
|
||||
if self.on_disconnect is not None:
|
||||
self.on_disconnect(self)
|
||||
|
|
@ -91,7 +100,10 @@ class MQTTClient(object):
|
|||
if self.on_message is not None and self._username == parsed_topic[0]:
|
||||
feed = parsed_topic[2]
|
||||
payload = '' if msg.payload is None else msg.payload.decode('utf-8')
|
||||
self.on_message(self, feed, payload)
|
||||
elif self.on_message is not None and parsed_topic[0] == 'time':
|
||||
feed = parsed_topic[0]
|
||||
payload = msg.payload.decode('utf-8')
|
||||
self.on_message(self, feed, payload)
|
||||
|
||||
def connect(self, **kwargs):
|
||||
"""Connect to the Adafruit.IO service. Must be called before any loop
|
||||
|
|
@ -154,6 +166,22 @@ class MQTTClient(object):
|
|||
"""
|
||||
self._client.subscribe('{0}/feeds/{1}'.format(self._username, feed_id))
|
||||
|
||||
def subscribe_time(self, time):
|
||||
"""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:
|
||||
time =
|
||||
millis: milliseconds
|
||||
seconds: seconds
|
||||
iso: ISO-8601 (https://en.wikipedia.org/wiki/ISO_8601)
|
||||
"""
|
||||
if time == 'millis' or time == 'seconds':
|
||||
self._client.subscribe('time/{0}'.format(time))
|
||||
elif time == 'iso':
|
||||
self._client.subscribe('time/ISO-8601')
|
||||
else:
|
||||
print('ERROR: Invalid time type specified')
|
||||
return
|
||||
|
||||
def publish(self, feed_id, value):
|
||||
"""Publish a value to a specified feed.
|
||||
|
||||
|
|
|
|||
74
CODE_OF_CONDUCT.md
Normal file
74
CODE_OF_CONDUCT.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at support@adafruit.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2014 Adafruit
|
||||
Copyright (c) 2014-2018 Adafruit
|
||||
Author: Justin Cooper and Tony DiCola
|
||||
|
||||
MIT License
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
include README.md
|
||||
include README.rst
|
||||
|
|
|
|||
483
README.md
483
README.md
|
|
@ -1,483 +0,0 @@
|
|||
# adafruit-io
|
||||
|
||||
A [Python](https://www.python.org/) client for use with [io.adafruit.com](https://io.adafruit.com). Compatible with both Python 2.7+ and Python 3.3+.
|
||||
|
||||
## Installation
|
||||
|
||||
### Easy Installation
|
||||
|
||||
If you have [pip installed](https://pip.pypa.io/en/latest/installing.html)
|
||||
(typically with ````apt-get install python-pip```` on a Debian/Ubuntu-based
|
||||
system) then run:
|
||||
|
||||
sudo pip install adafruit-io
|
||||
|
||||
This will automatically install the Adafruit IO Python client code for your
|
||||
Python scripts to use. You might want to examine the examples folder in this
|
||||
GitHub repository to see examples of usage.
|
||||
|
||||
### Manual Installation
|
||||
|
||||
Clone or download the contents of this repository. Then navigate to the folder
|
||||
in a terminal and run the following command:
|
||||
|
||||
sudo python setup.py install
|
||||
|
||||
(on Windows, and some linux-based boards such as the Yun, omit the sudo)
|
||||
|
||||
### Raspberry Pi SSL Note
|
||||
|
||||
On a Raspberry Pi with Python 2.7.3 you might see warnings like:
|
||||
|
||||
InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
|
||||
|
||||
To remove this warning you can install better SSL support for Python by running these
|
||||
commands in a terminal
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y python-pip python-dev build-essential libffi-dev libssl-dev
|
||||
sudo pip install requests[security]
|
||||
|
||||
Restart the Pi and you should see the warnings disappear.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
You must have an [Adafruit IO key](https://learn.adafruit.com/adafruit-io/api-key) to use this library and the Adafruit IO service.
|
||||
Your API key will be provided to the python library so it can authenticate your
|
||||
requests against the Adafruit IO service.
|
||||
|
||||
At a high level the Adafruit IO python client provides two interfaces to the
|
||||
service:
|
||||
|
||||
* A thin wrapper around the REST-based API. This is good for simple request and
|
||||
response applications like logging data.
|
||||
|
||||
* A MQTT client (based on [paho-mqtt](https://pypi.python.org/pypi/paho-mqtt))
|
||||
which can publish and subscribe to feeds so it is immediately alerted of changes.
|
||||
This is good for applications which need to know when something has changed as
|
||||
quickly as possible.
|
||||
|
||||
To use either interface you'll first need to import the python client by adding
|
||||
an import such as the following at the top of your program:
|
||||
|
||||
```python
|
||||
from Adafruit_IO import *
|
||||
```
|
||||
|
||||
Then a REST API client can be created with code like:
|
||||
|
||||
```python
|
||||
aio = Client('xxxxxxxxxxxx')
|
||||
```
|
||||
|
||||
Where 'xxxxxxxxxxxx' is your Adafruit IO API key.
|
||||
|
||||
Alternatively an MQTT client can be created with code like:
|
||||
|
||||
```python
|
||||
mqtt = MQTTClient('xxxxxxxxxxxx')
|
||||
```
|
||||
|
||||
Again where 'xxxxxxxxxxxx' is your Adafruit IO API key.
|
||||
|
||||
Your program can use either or both the REST API client and MQTT client,
|
||||
depending on your needs.
|
||||
|
||||
### Error Handling
|
||||
|
||||
The python client library will raise an exception if it runs into an error it
|
||||
cannot handle. You should be prepared to catch explicit exceptions you know how
|
||||
to handle, or bubble them up to the user as an error. Adafruit IO exceptions
|
||||
generally are children of the base exception type `AdafruitIOError`.
|
||||
|
||||
### Quickstart
|
||||
|
||||
Here's a short example of how to send a new value to a feed, and how to read
|
||||
the most recent value from the feed. This example uses the REST API.
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Send the value 100 to a feed called 'Foo'.
|
||||
aio.send_data('Foo', 100)
|
||||
|
||||
# Retrieve the most recent value from the feed 'Foo'.
|
||||
# Access the value by reading the `value` property on the returned Data object.
|
||||
# Note that all values retrieved from IO are strings so you might need to convert
|
||||
# them to an int or numeric type if you expect a number.
|
||||
data = aio.receive('Foo')
|
||||
print('Received value: {0}'.format(data.value))
|
||||
```
|
||||
|
||||
If you want to be notified of feed changes immediately without polling, consider
|
||||
using the MQTT client. See the [examples\mqtt_client.py](https://github.com/adafruit/io-client-python/blob/master/examples/mqtt_client.py) for an example of using the MQTT client.
|
||||
|
||||
### More Information
|
||||
|
||||
See the details below for more information about using the Adafruit IO python
|
||||
client. You can also print out the documentation on the client and classes by
|
||||
running:
|
||||
|
||||
```
|
||||
pydoc Adafruit_IO.client
|
||||
pydoc Adafruit_IO.mqtt_client
|
||||
pydoc Adafruit_IO.model
|
||||
pydoc Adafruit_IO.errors
|
||||
```
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Feeds](#feeds)
|
||||
* [Create](#feed-creation)
|
||||
* [Read](#feed-retrieval)
|
||||
* [Update](#feed-updating)
|
||||
* [Delete](#feed-deletion)
|
||||
* [Data](#data)
|
||||
* [Create](#data-creation)
|
||||
* [Read](#data-retrieval)
|
||||
* [Update](#data-updating)
|
||||
* [Delete](#data-deletion)
|
||||
* [Helper Methods](#helper-methods)
|
||||
* [Send Data](#send-data)
|
||||
* [Send Batch Data](#send-batch-data)
|
||||
* [Receive](#receive)
|
||||
* [Next](#next)
|
||||
* [Previous](#previous)
|
||||
* [Publishing and Subscribing](#publishing-and-subscribing)
|
||||
* [Groups](#groups)
|
||||
* [Create](#group-creation)
|
||||
* [Read](#group-retrieval)
|
||||
* [Update](#group-updating)
|
||||
* [Delete](#group-deletion)
|
||||
|
||||
### Feeds
|
||||
|
||||
[Feeds](https://learn.adafruit.com/adafruit-io/feeds) are the core of the Adafruit IO system. The feed holds metadata about data
|
||||
that gets pushed, and you will have one feed for each type of data you send to
|
||||
the system. You can have separate feeds for each sensor in a project, or you can
|
||||
use one feed to contain JSON encoded data for all of your sensors.
|
||||
|
||||
#### Feed Creation
|
||||
|
||||
Create a feed by constructing a Feed instance with at least a name specified, and
|
||||
then pass it to the `create_feed(feed)` function:
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client, Feed
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Create Feed object with name 'Foo'.
|
||||
feed = Feed(name='Foo')
|
||||
|
||||
# Send the Feed to IO to create.
|
||||
# The returned object will contain all the details about the created feed.
|
||||
result = aio.create_feed(feed)
|
||||
```
|
||||
|
||||
Note that you can use the [send](#send) function to create a feed and send it a
|
||||
new value in a single call. It's recommended that you use send instead of
|
||||
manually constructing feed instances.
|
||||
|
||||
#### Feed Retrieval
|
||||
|
||||
You can get a list of your feeds by using the `feeds()` method which will return
|
||||
a list of Feed instances:
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get list of feeds.
|
||||
feeds = aio.feeds()
|
||||
|
||||
# Print out the feed names:
|
||||
for f in feeds:
|
||||
print('Feed: {0}'.format(f.name))
|
||||
```
|
||||
|
||||
Alternatively you can retrieve the metadata for a single feed by calling
|
||||
`feeds(feed)` and passing the name, ID, or key of a feed to retrieve:
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get feed 'Foo'
|
||||
feed = aio.feeds('Foo')
|
||||
|
||||
# Print out the feed metadata.
|
||||
print(feed)
|
||||
```
|
||||
|
||||
#### Feed Updating
|
||||
|
||||
TODO: This is not tested in the python client yet, but calling create_feed with
|
||||
a Feed instance should update the feed.
|
||||
|
||||
#### Feed Deletion
|
||||
|
||||
You can delete a feed by ID, key, or name by calling `delete_feed(feed)`.
|
||||
ALL data in the feed will be deleted after calling this API!
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Delete the feed with name 'Test'.
|
||||
aio.delete_feed('Test')
|
||||
```
|
||||
|
||||
### Data
|
||||
|
||||
Data represents the data contained in feeds. You can read, add, modify, and
|
||||
delete data. There are also a few convenient methods for sending data to feeds
|
||||
and selecting certain pieces of data.
|
||||
|
||||
#### Data Creation
|
||||
|
||||
Data can be created [after you create a feed](#data-creation), by using the
|
||||
`create_data(feed, data)` method and passing it a new Data instance a value.
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client, Data
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Create a data item with value 10 in the 'Test' feed.
|
||||
data = Data(value=10)
|
||||
aio.create_data('Test', data)
|
||||
```
|
||||
|
||||
#### Data Retrieval
|
||||
|
||||
You can get all of the data for a feed by using the `data(feed)` method. The
|
||||
result will be an array of all feed data, each returned as an instance of the
|
||||
Data class. Use the value property on each Data instance to get the data value,
|
||||
and remember values are always returned as strings (so you might need to convert
|
||||
to an int or number if you expect a numeric value).
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get an array of all data from feed 'Test'
|
||||
data = aio.data('Test')
|
||||
|
||||
# Print out all the results.
|
||||
for d in data:
|
||||
print('Data value: {0}'.format(d.value))
|
||||
```
|
||||
|
||||
You can also get a specific value by ID by using the `feeds(feed, data_id)`
|
||||
method. This will return a single piece of feed data with the provided data ID
|
||||
if it exists in the feed. The returned object will be an instance of the Data
|
||||
class.
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get a specific value by id.
|
||||
# This example assumes 1 is a valid data ID in the 'Test' feed
|
||||
data = aio.feeds('Test', 1)
|
||||
|
||||
# Print the value.
|
||||
print('Data value: {0}'.format(data.value))
|
||||
```
|
||||
|
||||
#### Data Updating
|
||||
|
||||
TODO: This is not tested in the python client, but calling create_data with a
|
||||
Data instance should update it.
|
||||
|
||||
#### Data Deletion
|
||||
|
||||
Values can be deleted by using the `delete(feed, data_id)` method:
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Delete a data value from feed 'Test' with ID 1.
|
||||
data = aio.delete('Test', 1)
|
||||
```
|
||||
|
||||
#### Helper Methods
|
||||
|
||||
There are a few helper methods that can make interacting with data a bit easier.
|
||||
|
||||
##### Send Data
|
||||
|
||||
You can use the `send_data(feed_name, value)` method to append a new value to a
|
||||
feed. This is the recommended way to send data to Adafruit IO from the Python
|
||||
REST client.
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Add the value 98.6 to the feed 'Temperature'.
|
||||
test = aio.feeds('test')
|
||||
aio.send_data(test.key, 98.6)
|
||||
```
|
||||
|
||||
#### Send Batch Data
|
||||
|
||||
Data can be created [after you create a feed](#data-creation), by using the
|
||||
`send_batch_data(feed, data_list)` method and passing it a new Data list.
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client, Data
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Create a data items in the 'Test' feed.
|
||||
data_list = [Data(value=10), Data(value=11)]
|
||||
aio.create_data('Test', data)
|
||||
```
|
||||
|
||||
##### Receive
|
||||
|
||||
You can get the last inserted value by using the `receive(feed)` method.
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get the last value of the temperature feed.
|
||||
data = aio.receive('Test')
|
||||
|
||||
# Print the value and a message if it's over 100. Notice that the value is
|
||||
# converted from string to int because it always comes back as a string from IO.
|
||||
temp = int(data.value)
|
||||
print('Temperature: {0}'.format(temp))
|
||||
if temp > 100:
|
||||
print 'Hot enough for you?'
|
||||
```
|
||||
|
||||
##### Next
|
||||
|
||||
You can get the first inserted value that has not been processed (read) by using
|
||||
the `receive_next(feed)` method.
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get next unread value from feed 'Test'.
|
||||
data = aio.receive_next('Test')
|
||||
|
||||
# Print the value.
|
||||
print('Data value: {0}'.format(data.value))
|
||||
```
|
||||
|
||||
##### Previous
|
||||
|
||||
You can get the last record that has been processed (read) by using the
|
||||
`receive_previous(feed)` method.
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get previous read value from feed 'Test'.
|
||||
data = aio.receive_previous('Test')
|
||||
|
||||
# Print the value.
|
||||
print('Data value: {0}'.format(data.value))
|
||||
```
|
||||
|
||||
#### Publishing and Subscribing
|
||||
|
||||
You can get a readable stream of live data from your feed using the included
|
||||
MQTT client class.
|
||||
|
||||
TBD: Document using the MQTT client. For now see the [examples\mqtt_client.py](https://github.com/adafruit/io-client-python/blob/master/examples/mqtt_client.py) example which is fully documented with comments.
|
||||
|
||||
### Groups
|
||||
|
||||
[Groups](https://learn.adafruit.com/adafruit-io/groups) allow you to update and retrieve multiple feeds with one request. You can
|
||||
add feeds to multiple groups.
|
||||
|
||||
#### Group Creation
|
||||
|
||||
TBD: Currently group creation doesn't work with the APIs. Groups must be created
|
||||
in the UI.
|
||||
|
||||
#### Group Retrieval
|
||||
|
||||
You can get a list of your groups by using the `groups()` method. This will
|
||||
return a list of Group instances. Each Group instance has metadata about the
|
||||
group, including a `feeds` property which is a tuple of all feeds in the group.
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get list of groups.
|
||||
groups = aio.groups()
|
||||
|
||||
# Print the group names and number of feeds in the group.
|
||||
for g in groups:
|
||||
print('Group {0} has {1} feed(s).'.format(g.name, len(g.feeds)))
|
||||
```
|
||||
|
||||
You can also get a specific group by ID, key, or name by using the
|
||||
`groups(group)` method:
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get group called 'GroupTest'.
|
||||
group = aio.groups('GroupTest')
|
||||
|
||||
# Print the group name and number of feeds in the group.
|
||||
print('Group {0} has {1} feed(s).'.format(group.name, len(group.feeds)))
|
||||
```
|
||||
|
||||
#### Group Updating
|
||||
|
||||
TBD This is not tested in the python client yet, but calling create_group should
|
||||
update a group.
|
||||
|
||||
#### Group Deletion
|
||||
|
||||
You can delete a group by ID, key, or name by using the `delete_group(group)`
|
||||
method:
|
||||
|
||||
```python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Delete group called 'GroupTest'.
|
||||
aio.delete_group('GroupTest')
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork it ( http://github.com/adafruit/io-client-python/fork )
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
4. Push to the branch (`git push origin my-new-feature`)
|
||||
5. Create new Pull Request
|
||||
|
||||
## License
|
||||
Copyright (c) 2014 Adafruit Industries. Licensed under the MIT license.
|
||||
33
README.rst
Normal file
33
README.rst
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
Adafruit IO Python
|
||||
==================
|
||||
|
||||
.. image:: https://readthedocs.org/projects/adafruit-io-python-client/badge/?version=latest
|
||||
:target: https://adafruit-io-python-client.readthedocs.io/en/latest/
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image:: https://img.shields.io/discord/327254708534116352.svg
|
||||
:target: https://discord.gg/nBQh6qu
|
||||
:alt: Chat
|
||||
|
||||
.. image:: https://travis-ci.org/adafruit/io-client-python.svg?branch=master
|
||||
:target: https://travis-ci.org/adafruit/io-client-python
|
||||
:alt: Build Status
|
||||
|
||||
.. image:: https://cdn-learn.adafruit.com/assets/assets/000/057/153/original/adafruit_io_iopython.png?1530802073
|
||||
|
||||
A Python client and examples for use with `io.adafruit.com <https://io.adafruit.com>`_.
|
||||
|
||||
Compatible with Python 3.6+
|
||||
|
||||
Documentation
|
||||
================
|
||||
|
||||
Documentation for this project is `available on the ReadTheDocs <https://adafruit-io-python-client.readthedocs.io/en/latest/>`_.
|
||||
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
Contributions are welcome! Please read our `Code of Conduct
|
||||
<https://github.com/adafruit/CircuitPython_io-client-python/blob/master/CODE_OF_CONDUCT.md>`_
|
||||
before contributing to help this project stay welcoming.
|
||||
BIN
docs/_static/favicon.ico
vendored
Normal file
BIN
docs/_static/favicon.ico
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
0
docs/api-examples.rst
Normal file
0
docs/api-examples.rst
Normal file
160
docs/conf.py
Normal file
160
docs/conf.py
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.napoleon',
|
||||
'sphinx.ext.todo',
|
||||
]
|
||||
|
||||
# TODO: Please Read!
|
||||
# Uncomment the below if you use native CircuitPython modules such as
|
||||
# digitalio, micropython and busio. List the modules you use. Without it, the
|
||||
# autodoc module docs will fail to generate with a warning.
|
||||
# autodoc_mock_imports = ["digitalio", "busio"]
|
||||
|
||||
|
||||
intersphinx_mapping = {'python': ('https://docs.python.org/3.4', None),'CircuitPython': ('https://circuitpython.readthedocs.io/en/latest/', None)}
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'io-client-python'
|
||||
copyright = u'2018 Tony DiCola, Justin Cooper, Adam Bachman, Todd Treece, Brent Rubell'
|
||||
author = u'Tony DiCola, Justin Cooper, Adam Bachman, Todd Treece, Brent Rubell'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = u'2.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = u'2.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This patterns also effect to html_static_path and html_extra_path
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.env', 'CODE_OF_CONDUCT.md']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#
|
||||
default_role = "any"
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#
|
||||
add_function_parentheses = True
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
# If this is True, todo emits a warning for each TODO entries. The default is False.
|
||||
todo_emit_warnings = True
|
||||
|
||||
napoleon_numpy_docstring = False
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
|
||||
if not on_rtd: # only import and set the theme if we're building docs locally
|
||||
try:
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
|
||||
except:
|
||||
html_theme = 'default'
|
||||
html_theme_path = ['.']
|
||||
else:
|
||||
html_theme_path = ['.']
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# The name of an image file (relative to this directory) to use as a favicon of
|
||||
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#
|
||||
html_favicon = '_static/favicon.ico'
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Io-client-pythonLibrarydoc'
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'io-client-pythonLibrary.tex', u'io-client-python Library Documentation',
|
||||
author, 'manual'),
|
||||
]
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'io-client-pythonlibrary', u'io-client-python Library Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'io-client-pythonLibrary', u' io-client-python Library Documentation',
|
||||
author, 'io-client-pythonLibrary', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
144
docs/data.rst
Normal file
144
docs/data.rst
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
Data
|
||||
----
|
||||
Data represents the data contained in feeds. You can read, add, modify, and delete data. There are also a few convenient methods for sending data to feeds and selecting certain pieces of data.
|
||||
|
||||
Data Creation
|
||||
~~~~~~~~~~~~~
|
||||
Data can be created after you create a feed, by using the ``create_data(feed, data)`` method and passing it a new Data instance a value.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client, Data
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Create a data item with value 10 in the 'Test' feed.
|
||||
data = Data(value=10)
|
||||
aio.create_data('Test', data)
|
||||
|
||||
Data Retrieval
|
||||
~~~~~~~~~~~~~
|
||||
You can get all of the data for a feed by using the ``data(feed)`` method. The result will be an array of all feed data, each returned as an instance of the Data class. Use the value property on each Data instance to get the data value, and remember values are always returned as strings (so you might need to convert to an int or number if you expect a numeric value).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get an array of all data from feed 'Test'
|
||||
data = aio.data('Test')
|
||||
|
||||
# Print out all the results.
|
||||
for d in data:
|
||||
print('Data value: {0}'.format(d.value))
|
||||
|
||||
You can also get a specific value by ID by using the ``feeds(feed, data_id)`` method. This will return a single piece of feed data with the provided data ID if it exists in the feed. The returned object will be an instance of the Data class.
|
||||
|
||||
|
||||
Data Deletion
|
||||
~~~~~~~~~~~~~
|
||||
Values can be deleted by using the ``delete(feed, data_id)`` method:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Delete a data value from feed 'Test' with ID 1.
|
||||
data = aio.delete('Test', 1)
|
||||
|
||||
Data Helper methods
|
||||
---------------
|
||||
There are a few helper methods that can make interacting with data a bit easier.
|
||||
|
||||
Send Data
|
||||
~~~~~~~~~
|
||||
You can use the ``send_data(feed_name, value)`` method to append a new value to a feed. This is the recommended way to send data to Adafruit IO from the Python REST client.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Add the value 98.6 to the feed 'Temperature'.
|
||||
test = aio.feeds('test')
|
||||
aio.send_data(test.key, 98.6)
|
||||
|
||||
Send Batch Data
|
||||
~~~~~~~~~~~~~~~
|
||||
Data can be created after you create a feed, by using the ``send_batch_data(feed, data_list)`` method and passing it a new Data list.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client, Data
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Create a data items in the 'Test' feed.
|
||||
data_list = [Data(value=10), Data(value=11)]
|
||||
aio.create_data('Test', data)
|
||||
|
||||
|
||||
Receive Data
|
||||
~~~~~~~~~~~~
|
||||
You can get the last inserted value by using the ``receive(feed)`` method.
|
||||
|
||||
.. code-block:: python
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get the last value of the temperature feed.
|
||||
data = aio.receive('Test')
|
||||
|
||||
# Print the value and a message if it's over 100. Notice that the value is
|
||||
# converted from string to int because it always comes back as a string from IO.
|
||||
temp = int(data.value)
|
||||
print('Temperature: {0}'.format(temp))
|
||||
if temp > 100:
|
||||
print 'Hot enough for you?'
|
||||
|
||||
|
||||
Next Value
|
||||
~~~~~~~~~~
|
||||
You can get the first inserted value that has not been processed (read) by using the ``receive_next(feed)`` method.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get next unread value from feed 'Test'.
|
||||
data = aio.receive_next('Test')
|
||||
|
||||
# Print the value.
|
||||
print('Data value: {0}'.format(data.value))
|
||||
|
||||
|
||||
|
||||
Previous Value
|
||||
~~~~~~~~~~~~~~
|
||||
You can get the last record that has been processed (read) by using the ``receive_previous(feed)`` method.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get previous read value from feed 'Test'.
|
||||
data = aio.receive_previous('Test')
|
||||
|
||||
# Print the value.
|
||||
print('Data value: {0}'.format(data.value))
|
||||
|
||||
|
||||
Publishing and Subscribing
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
You can get a readable stream of live data from your feed using the included MQTT client class:
|
||||
|
||||
.. literalinclude:: ../examples/mqtt/mqtt_subscribe.py
|
||||
0
docs/examples.rst
Normal file
0
docs/examples.rst
Normal file
69
docs/feeds.rst
Normal file
69
docs/feeds.rst
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
Feeds
|
||||
-----
|
||||
Feeds are the core of the Adafruit IO system. The feed holds metadata about data that gets pushed, and you will have one feed for each type of data you send to the system. You can have separate feeds for each sensor in a project, or you can use one feed to contain JSON encoded data for all of your sensors.
|
||||
|
||||
|
||||
Feed Creation
|
||||
~~~~~~~~~~~~~
|
||||
Create a feed by constructing a Feed instance with at least a name specified, and then pass it to the ``create_feed(feed)`` function:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client, Feed
|
||||
aio = Client('YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Create Feed object with name 'Foo'.
|
||||
feed = Feed(name='Foo')
|
||||
|
||||
# Send the Feed to IO to create.
|
||||
# The returned object will contain all the details about the created feed.
|
||||
result = aio.create_feed(feed)
|
||||
|
||||
Note that you can use the send function to create a feed and send it a new value in a single call. It's recommended that you use send instead of manually constructing feed instances.
|
||||
|
||||
Feed Retrieval
|
||||
~~~~~~~~~~~~~~~
|
||||
You can get a list of your feeds by using the ``feeds()`` method which will return a list of Feed instances:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get list of feeds.
|
||||
feeds = aio.feeds()
|
||||
|
||||
# Print out the feed names:
|
||||
for f in feeds:
|
||||
print('Feed: {0}'.format(f.name))
|
||||
|
||||
Alternatively you can retrieve the metadata for a single feed by calling ``feeds(feed)`` and passing the ``name``, ``ID``, or ``key`` of a feed to retrieve:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get feed 'Foo'
|
||||
feed = aio.feeds('Foo')
|
||||
|
||||
# Print out the feed metadata.
|
||||
print(feed)
|
||||
|
||||
|
||||
Feed Deletion
|
||||
~~~~~~~~~~~~~~
|
||||
You can delete a feed by ID, key, or name by calling ``delete_feed(feed)``. ALL data in the feed will be deleted after calling this API!
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Delete the feed with name 'Test'.
|
||||
aio.delete_feed('Test')
|
||||
|
||||
75
docs/groups.rst
Normal file
75
docs/groups.rst
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
Groups
|
||||
-------
|
||||
Groups allow you to update and retrieve multiple feeds with one request. You can add feeds to multiple groups.
|
||||
|
||||
|
||||
Group Creation
|
||||
~~~~~~~~~~~~~~
|
||||
The creation of groups is now supported in API-V2, rejoyce! The process of creating a group is similar to creating a feed.
|
||||
Create a group by constructing a Group instance with at least a name specified, and then pass it to the ``create_group(group)`` function:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client, Group
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Create a group instance
|
||||
group = Group(name="weatherstation")
|
||||
|
||||
# Send the group for IO to create:
|
||||
# The returned object will contain all the details about the created group.
|
||||
group = aio.create_group(group
|
||||
|
||||
|
||||
Group Retrieval
|
||||
~~~~~~~~~~~~~~~
|
||||
You can get a list of your groups by using the ``groups()`` method.
|
||||
This will return a list of Group instances. Each Group instance has metadata about the group, including a ``feeds`` property which is a tuple of all feeds in the group.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get list of groups.
|
||||
groups = aio.groups()
|
||||
|
||||
# Print the group names and number of feeds in the group.
|
||||
for g in groups:
|
||||
print('Group {0} has {1} feed(s).'.format(g.name, len(g.feeds)))
|
||||
|
||||
|
||||
You can also get a specific group by ID, key, or name by using the ``groups(group)`` method:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Get group called 'GroupTest'.
|
||||
group = aio.groups('GroupTest')
|
||||
|
||||
# Print the group name and number of feeds in the group.
|
||||
print('Group {0} has {1} feed(s).'.format(group.name, len(group.feeds)))
|
||||
|
||||
Group Updating
|
||||
~~~~~~~~~~~~~~
|
||||
TODO: Test and example this
|
||||
|
||||
Group Deletion
|
||||
~~~~~~~~~~~~~~
|
||||
You can delete a group by ID, key, or name by using the ``delete_group(group)`` method:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO USERNAME', 'YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Delete group called 'GroupTest'.
|
||||
aio.delete_group('GroupTest')
|
||||
|
||||
50
docs/index.rst
Normal file
50
docs/index.rst
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
.. include:: ../README.rst
|
||||
|
||||
Table of Contents
|
||||
=================
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 5
|
||||
:hidden:
|
||||
|
||||
self
|
||||
|
||||
.. toctree::
|
||||
:caption: IO Python Client Usage
|
||||
:maxdepth: 7
|
||||
|
||||
quickstart
|
||||
io-basics-examples
|
||||
api-examples
|
||||
mqtt-examples
|
||||
|
||||
|
||||
.. toctree::
|
||||
:caption: API Reference
|
||||
:maxdepth: 6
|
||||
|
||||
feeds
|
||||
data
|
||||
groups
|
||||
|
||||
|
||||
|
||||
.. toctree::
|
||||
:caption: Other Links
|
||||
|
||||
Download Library <https://github.com/adafruit/io-client-python/releases/latest>
|
||||
Adafruit IO <https://io.adafruit.com>
|
||||
Welcome to Adafruit IO Learning Guide <https://learn.adafruit.com/welcome-to-adafruit-io>
|
||||
Adafruit IO Support Forum <https://forums.adafruit.com/viewforum.php?f=56>
|
||||
Discord Chat (#adafruit-io) <https://adafru.it/discord>
|
||||
Adafruit Learning System <https://learn.adafruit.com>
|
||||
Adafruit Blog <https://blog.adafruit.com>
|
||||
Adafruit Store <https://www.adafruit.com>
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
0
docs/io-basics-examples.rst
Normal file
0
docs/io-basics-examples.rst
Normal file
0
docs/mqtt-examples.rst
Normal file
0
docs/mqtt-examples.rst
Normal file
64
docs/quickstart.rst
Normal file
64
docs/quickstart.rst
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
Quickstart
|
||||
------------
|
||||
Here's a short example of how to send a new value to a feed (creating the feed if it doesn't exist), and how to read the most recent value from the feed. This example uses the REST API.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Import library and create instance of REST client.
|
||||
from Adafruit_IO import Client
|
||||
aio = Client('YOUR ADAFRUIT IO KEY')
|
||||
|
||||
# Send the value 100 to a feed called 'Foo'.
|
||||
aio.send('Foo', 100)
|
||||
|
||||
# Retrieve the most recent value from the feed 'Foo'.
|
||||
# Access the value by reading the `value` property on the returned Data object.
|
||||
# Note that all values retrieved from IO are strings so you might need to convert
|
||||
# them to an int or numeric type if you expect a number.
|
||||
data = aio.receive('Foo')
|
||||
print('Received value: {0}'.format(data.value))
|
||||
|
||||
If you want to be notified of feed changes immediately without polling, consider using the MQTT client. See the ``examples/mqtt_client.py`` for an example of using the MQTT client.
|
||||
|
||||
Basic Client Usage
|
||||
-------------------
|
||||
|
||||
You must have an Adafruit IO key to use this library and the Adafruit IO service. Your API key will be provided to the python library so it can authenticate your requests against the Adafruit IO service.
|
||||
|
||||
At a high level the Adafruit IO python client provides two interfaces to the service:
|
||||
|
||||
- A thin wrapper around the REST-based API. This is good for simple request and response applications like logging data.
|
||||
|
||||
- A MQTT client (based on paho-mqtt) which can publish and subscribe to feeds so it is immediately alerted of changes. This is good for applications which need to know when something has changed as quickly as possible.
|
||||
|
||||
To use either interface you'll first need to import the python client by adding an import such as the following at the top of your program:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from Adafruit_IO import *
|
||||
|
||||
Then a REST API client can be created with code like:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
aio = Client('xxxxxxxxxxxx')
|
||||
|
||||
Where ``'xxxxxxxxxxxx'`` is your Adafruit IO API key.
|
||||
|
||||
Alternatively an MQTT client can be created with code like:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
mqtt = MQTTClient('xxxxxxxxxxxx')
|
||||
|
||||
Again where ``'xxxxxxxxxxxx'`` is your Adafruit IO API key.
|
||||
|
||||
Your program can use either or both the REST API client and MQTT client, depending on your needs.
|
||||
|
||||
Error Handling
|
||||
---------------
|
||||
The python client library will raise an exception if it runs into an error it cannot handle.
|
||||
You should be prepared to catch explicit exceptions you know how to handle, or bubble them up to the user as an error.
|
||||
Adafruit IO exceptions generally are children of the base exception type AdafruitIOError. There are also three sub-exceptions to handle, depending on which if you're using the REST API
|
||||
or MQTT Client: MQTTError (for the MQTT Client), RequestError (REST Client), and ThrottlingError (REST Client).
|
||||
|
||||
38
examples/aio_basics/adafruitio_17_time.py
Normal file
38
examples/aio_basics/adafruitio_17_time.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
"""
|
||||
adafruitio_17_time.py
|
||||
====================================
|
||||
Don't have a RTC handy and need
|
||||
accurate time measurements?
|
||||
|
||||
Let Adafruit IO serve real-time values!
|
||||
|
||||
Author: Brent Rubell
|
||||
"""
|
||||
# Import Adafruit IO REST client.
|
||||
from Adafruit_IO import Client, Feed, Data, RequestError
|
||||
|
||||
# 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'
|
||||
|
||||
# Create an instance of the REST client.
|
||||
aio = Client(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)
|
||||
|
||||
print('---Adafruit IO REST API Time Helpers---')
|
||||
|
||||
print('Seconds: aio.receive_time(seconds)')
|
||||
secs_val = aio.receive_time('seconds')
|
||||
print('\t' + secs_val)
|
||||
|
||||
print('Milliseconds: aio.receive_time(millis)')
|
||||
ms_val = aio.receive_time('millis')
|
||||
print('\t' + ms_val)
|
||||
|
||||
print('ISO-8601: aio.receive_time(ISO-8601)')
|
||||
iso_val = aio.receive_time('ISO-8601')
|
||||
print('\t' + iso_val)
|
||||
36
examples/api/location.py
Normal file
36
examples/api/location.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
"""
|
||||
'location.py'
|
||||
==================================
|
||||
Example of sending location over an
|
||||
Adafruit IO feed to a Map Dashboard
|
||||
block
|
||||
|
||||
Author(s): Brent Rubell
|
||||
"""
|
||||
|
||||
# Import Adafruit IO REST client.
|
||||
from Adafruit_IO import Client, Feed, RequestError
|
||||
|
||||
# Set to your Adafruit IO key.
|
||||
ADAFRUIT_IO_USERNAME = 'YOUR_AIO_USERNAME'
|
||||
ADAFRUIT_IO_KEY = 'YOUR_AIO_KEY'
|
||||
|
||||
# Create an instance of the REST client.
|
||||
aio = Client(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)
|
||||
|
||||
# Create a location feed
|
||||
try:
|
||||
location = aio.feeds('location')
|
||||
except RequestError:
|
||||
feed = Feed(name="location")
|
||||
location = aio.create_feed(feed)
|
||||
|
||||
|
||||
# Top Secret Adafruit HQ Location
|
||||
value = 1
|
||||
lat = 40.726190
|
||||
lon = -74.005334
|
||||
ele = 6 # elevation above sea level (meters)
|
||||
|
||||
# Send location data to Adafruit IO
|
||||
aio.send_location_data(location.key, value, lat, lon, ele)
|
||||
|
|
@ -19,6 +19,7 @@ ADAFRUIT_IO_KEY = 'YOUR_AIO_KEY'
|
|||
ADAFRUIT_IO_USERNAME = 'YOUR_AIO_USERNAME'
|
||||
|
||||
|
||||
|
||||
# Define callback functions which will be called when certain events happen.
|
||||
def connected(client):
|
||||
# Connected function will be called when the client is connected to Adafruit IO.
|
||||
|
|
|
|||
64
examples/mqtt/mqtt_time.py
Normal file
64
examples/mqtt/mqtt_time.py
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
"""
|
||||
mqtt_time.py
|
||||
============================================
|
||||
example of utilizing MQTT time topics to grab
|
||||
the time from the Adafruit IO server.
|
||||
|
||||
Author: Brent Rubell
|
||||
"""
|
||||
|
||||
# Import standard python modules.
|
||||
import sys
|
||||
import time
|
||||
|
||||
# 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'
|
||||
|
||||
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('\t Feed {0} received new value: {1}'.format(feed_id, payload))
|
||||
|
||||
|
||||
# Create a SECURE MQTT client instance
|
||||
# Note: This client will default to secure, an optional parameter can be added
|
||||
# to make it insecure, comment out the below line
|
||||
# client = MQTTClient(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY, secure=False)
|
||||
client = MQTTClient(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)
|
||||
|
||||
# Setup the callback functions defined above.
|
||||
client.on_disconnect = disconnected
|
||||
client.on_message = message
|
||||
|
||||
# Connect to the Adafruit IO server.
|
||||
client.connect()
|
||||
|
||||
# time per loop
|
||||
loop_time = 2
|
||||
|
||||
client.loop_background()
|
||||
while True:
|
||||
print('* Subscribing to /time/seconds')
|
||||
client.subscribe_time('seconds')
|
||||
time.sleep(loop_time)
|
||||
print('* Subscribing to /time/millis')
|
||||
client.subscribe_time('millis')
|
||||
time.sleep(loop_time)
|
||||
print('* Subscribing to iso-8601')
|
||||
client.subscribe_time('iso')
|
||||
time.sleep(loop_time)
|
||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
3
setup.py
3
setup.py
|
|
@ -18,7 +18,6 @@ classifiers = ['Development Status :: 4 - Beta',
|
|||
'Operating System :: MacOS',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Intended Audience :: Developers',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Topic :: Software Development',
|
||||
'Topic :: Home Automation',
|
||||
|
|
@ -36,6 +35,6 @@ setup(
|
|||
keywords = 'Adafruit IO',
|
||||
classifiers = classifiers,
|
||||
description = 'Client library for Adafruit IO (http://io.adafruit.com/).',
|
||||
long_description = open('README.md').read(),
|
||||
long_description = open('README.rst').read(),
|
||||
install_requires = ["requests", "paho-mqtt"]
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue