-
Notifications
You must be signed in to change notification settings - Fork 31
Add feed callback mechanism #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -100,9 +100,7 @@ def __exit__(self, exception_type, exception_value, traceback): | |
self.disconnect() | ||
|
||
def reconnect(self): | ||
"""Attempts to reconnect to the Adafruit IO MQTT Broker. | ||
|
||
""" | ||
"""Attempts to reconnect to the Adafruit IO MQTT Broker.""" | ||
try: | ||
self._client.reconnect() | ||
except Exception as err: | ||
|
@@ -118,8 +116,7 @@ def connect(self): | |
raise AdafruitIO_MQTTError("Unable to connect to Adafruit IO.") from err | ||
|
||
def disconnect(self): | ||
"""Disconnects from Adafruit IO MQTT Broker. | ||
""" | ||
"""Disconnects from Adafruit IO MQTT Broker.""" | ||
if self._connected: | ||
self._client.disconnect() | ||
|
||
|
@@ -130,8 +127,7 @@ def is_connected(self): | |
|
||
# pylint: disable=not-callable, unused-argument | ||
def _on_connect_mqtt(self, client, userdata, flags, return_code): | ||
"""Runs when the client calls on_connect. | ||
""" | ||
"""Runs when the client calls on_connect.""" | ||
if self._logger: | ||
self._client._logger.debug("Client called on_connect.") | ||
if return_code == 0: | ||
|
@@ -144,8 +140,7 @@ def _on_connect_mqtt(self, client, userdata, flags, return_code): | |
|
||
# pylint: disable=not-callable, unused-argument | ||
def _on_disconnect_mqtt(self, client, userdata, return_code): | ||
"""Runs when the client calls on_disconnect. | ||
""" | ||
"""Runs when the client calls on_disconnect.""" | ||
if self._logger: | ||
self._client._logger.debug("Client called on_disconnect") | ||
self._connected = False | ||
|
@@ -195,22 +190,39 @@ def _on_message_mqtt(self, client, topic, payload): | |
|
||
# pylint: disable=not-callable | ||
def _on_subscribe_mqtt(self, client, user_data, topic, qos): | ||
"""Runs when the client calls on_subscribe. | ||
""" | ||
"""Runs when the client calls on_subscribe.""" | ||
if self._logger: | ||
self._client._logger.debug("Client called on_subscribe") | ||
if self.on_subscribe is not None: | ||
self.on_subscribe(self, user_data, topic, qos) | ||
|
||
# pylint: disable=not-callable | ||
def _on_unsubscribe_mqtt(self, client, user_data, topic, pid): | ||
"""Runs when the client calls on_unsubscribe. | ||
""" | ||
"""Runs when the client calls on_unsubscribe.""" | ||
if self._logger: | ||
self._client._logger.debug("Client called on_unsubscribe") | ||
if self.on_unsubscribe is not None: | ||
self.on_unsubscribe(self, user_data, topic, pid) | ||
|
||
def add_feed_callback(self, feed_key, callback_method): | ||
"""Executes callback_method whenever a message is | ||
received on feed_key. | ||
:param str feed_key: Adafruit IO feed key. | ||
:param str callback_method: Name of callback method. | ||
|
||
""" | ||
self._client.add_topic_callback( | ||
"{0}/feeds/{1}".format(self._user, feed_key), callback_method | ||
) | ||
|
||
def remove_feed_callback(self, feed_key): | ||
"""Removes a previously registered callback method | ||
from executing whenever feed_key receives new data. | ||
:param str feed_key: Adafruit IO feed key. | ||
|
||
""" | ||
self._client.remove_topic_callback("{0}/feeds/{1}".format(self._user, feed_key)) | ||
|
||
def loop(self): | ||
"""Manually process messages from Adafruit IO. | ||
Call this method to check incoming subscription messages. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a sentence here about how it will call the event handlers depending on the type of message. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. addressing this here: #47 |
||
|
@@ -464,16 +476,14 @@ def __init__(self, adafruit_io_username, adafruit_io_key, wifi_manager): | |
|
||
@staticmethod | ||
def _create_headers(io_headers): | ||
"""Creates http request headers. | ||
""" | ||
"""Creates http request headers.""" | ||
headers = CLIENT_HEADERS.copy() | ||
headers.update(io_headers) | ||
return headers | ||
|
||
@staticmethod | ||
def _create_data(data, metadata): | ||
"""Creates JSON data payload | ||
""" | ||
"""Creates JSON data payload""" | ||
if metadata is not None: | ||
return { | ||
"value": data, | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import time | ||
|
||
import board | ||
import busio | ||
from digitalio import DigitalInOut | ||
from adafruit_esp32spi import adafruit_esp32spi | ||
from adafruit_esp32spi import adafruit_esp32spi_wifimanager | ||
import adafruit_esp32spi.adafruit_esp32spi_socket as socket | ||
import neopixel | ||
import adafruit_minimqtt.adafruit_minimqtt as MQTT | ||
from adafruit_io.adafruit_io import IO_MQTT | ||
|
||
### WiFi ### | ||
|
||
# Get wifi details and more from a secrets.py file | ||
try: | ||
from secrets import secrets | ||
except ImportError: | ||
print("WiFi secrets are kept in secrets.py, please add them there!") | ||
raise | ||
|
||
# If you are using a board with pre-defined ESP32 Pins: | ||
esp32_cs = DigitalInOut(board.ESP_CS) | ||
esp32_ready = DigitalInOut(board.ESP_BUSY) | ||
esp32_reset = DigitalInOut(board.ESP_RESET) | ||
|
||
# If you have an externally connected ESP32: | ||
# esp32_cs = DigitalInOut(board.D9) | ||
# esp32_ready = DigitalInOut(board.D10) | ||
# esp32_reset = DigitalInOut(board.D5) | ||
|
||
spi = busio.SPI(board.SCK, board.MOSI, board.MISO) | ||
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) | ||
"""Use below for Most Boards""" | ||
status_light = neopixel.NeoPixel( | ||
board.NEOPIXEL, 1, brightness=0.2 | ||
) # Uncomment for Most Boards | ||
"""Uncomment below for ItsyBitsy M4""" | ||
# status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) | ||
# Uncomment below for an externally defined RGB LED | ||
# import adafruit_rgbled | ||
# from adafruit_esp32spi import PWMOut | ||
# RED_LED = PWMOut.PWMOut(esp, 26) | ||
# GREEN_LED = PWMOut.PWMOut(esp, 27) | ||
# BLUE_LED = PWMOut.PWMOut(esp, 25) | ||
# status_light = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) | ||
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light) | ||
|
||
# Define callback functions which will be called when certain events happen. | ||
# pylint: disable=unused-argument | ||
def connected(client): | ||
# Connected function will be called when the client is connected to Adafruit IO. | ||
# This is a good place to subscribe to feed changes. The client parameter | ||
# passed to this function is the Adafruit IO MQTT client so you can make | ||
# calls against it easily. | ||
print("Connected to Adafruit IO! Listening for DemoFeed changes...") | ||
|
||
|
||
def subscribe(client, userdata, topic, granted_qos): | ||
# This method is called when the client subscribes to a new feed. | ||
print("Subscribed to {0} with QOS level {1}".format(topic, granted_qos)) | ||
|
||
|
||
def unsubscribe(client, userdata, topic, pid): | ||
# This method is called when the client unsubscribes from a feed. | ||
print("Unsubscribed from {0} with PID {1}".format(topic, pid)) | ||
|
||
|
||
# pylint: disable=unused-argument | ||
def disconnected(client): | ||
# Disconnected function will be called when the client disconnects. | ||
print("Disconnected from Adafruit IO!") | ||
|
||
|
||
# pylint: disable=unused-argument | ||
def on_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)) | ||
|
||
|
||
def on_battery_msg(client, topic, message): | ||
# Method called whenever user/feeds/battery has a new value | ||
print("Battery level: {}v".format(message)) | ||
|
||
|
||
# Connect to WiFi | ||
print("Connecting to WiFi...") | ||
wifi.connect() | ||
print("Connected!") | ||
|
||
# Initialize MQTT interface with the esp interface | ||
MQTT.set_socket(socket, esp) | ||
|
||
# Initialize a new MQTT Client object | ||
mqtt_client = MQTT.MQTT( | ||
broker="io.adafruit.com", | ||
username=secrets["aio_username"], | ||
password=secrets["aio_key"], | ||
) | ||
|
||
# Initialize an Adafruit IO MQTT Client | ||
io = IO_MQTT(mqtt_client) | ||
|
||
# Connect the callback methods defined above to Adafruit IO | ||
io.on_connect = connected | ||
io.on_disconnect = disconnected | ||
io.on_subscribe = subscribe | ||
io.on_unsubscribe = unsubscribe | ||
io.on_message = on_message | ||
|
||
# Connect to Adafruit IO | ||
print("Connecting to Adafruit IO...") | ||
io.connect() | ||
|
||
# Set up a message handler for the battery feed | ||
io.add_feed_callback("battery", on_battery_msg) | ||
|
||
# Subscribe to all messages on the battery feed | ||
io.subscribe("battery") | ||
|
||
# Start a blocking loop to check for new messages | ||
while True: | ||
try: | ||
io.loop() | ||
except (ValueError, RuntimeError) as e: | ||
print("Failed to get data, retrying\n", e) | ||
wifi.reset() | ||
io.reconnect() | ||
continue | ||
time.sleep(0.5) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please mention here that the method is called by
loop
.