From 60d11b761e7acaeda1e8d0bc51dd17fb8a274e95 Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 28 Sep 2020 11:21:27 -0400 Subject: [PATCH 1/3] add example and 2x methods, black and pylinten --- adafruit_io/adafruit_io.py | 44 +++--- .../adafruit_io_feed_callback.py | 128 ++++++++++++++++++ 2 files changed, 155 insertions(+), 17 deletions(-) create mode 100644 examples/adafruit_io_mqtt/adafruit_io_feed_callback.py diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index d74762e..baa0994 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -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,8 +190,7 @@ 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: @@ -204,13 +198,31 @@ def _on_subscribe_mqtt(self, client, 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. @@ -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, diff --git a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py new file mode 100644 index 0000000..956990c --- /dev/null +++ b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py @@ -0,0 +1,128 @@ +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 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 = 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) From 0cf46ebe4bd41ff17d534435b140639a053e6898 Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 28 Sep 2020 11:24:59 -0400 Subject: [PATCH 2/3] Black example --- examples/adafruit_io_mqtt/adafruit_io_feed_callback.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py index 956990c..d810c1d 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py +++ b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py @@ -55,6 +55,7 @@ def connected(client): # 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)) @@ -83,6 +84,7 @@ 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() @@ -93,7 +95,9 @@ def on_battery_msg(client, topic, message): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( - broker="io.adafruit.com", username=secrets["aio_username"], password=secrets["aio_key"], + broker="io.adafruit.com", + username=secrets["aio_username"], + password=secrets["aio_key"], ) # Initialize an Adafruit IO MQTT Client From aff8b4cc13421a703bf72dd9c3f0012d6c2a4cd2 Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 28 Sep 2020 11:36:30 -0400 Subject: [PATCH 3/3] remove redefined message from scope --- examples/adafruit_io_mqtt/adafruit_io_feed_callback.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py index d810c1d..762191e 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py +++ b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py @@ -73,7 +73,7 @@ def disconnected(client): # pylint: disable=unused-argument -def message(client, feed_id, payload): +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. @@ -108,7 +108,7 @@ def on_battery_msg(client, topic, message): io.on_disconnect = disconnected io.on_subscribe = subscribe io.on_unsubscribe = unsubscribe -io.on_message = message +io.on_message = on_message # Connect to Adafruit IO print("Connecting to Adafruit IO...")