From f7b274af8c2c47afb7a8124e7995e92d51aac329 Mon Sep 17 00:00:00 2001 From: brendan <2bndy5@gmail.com> Date: Wed, 5 Aug 2020 18:33:41 -0700 Subject: [PATCH 001/153] remove loop_blocking --- adafruit_io/adafruit_io.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index f8eedf2..afc558a 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -224,12 +224,6 @@ def loop(self): """ self._client.loop() - def loop_blocking(self): - """Starts a blocking loop and to processes messages - from Adafruit IO. Code below this call will not run. - """ - self._client.loop_forever() - # Subscriptions def subscribe(self, feed_key=None, group_key=None, shared_user=None): """Subscribes to your Adafruit IO feed or group. From eceb1ccf00a891e93b2784a8ccc5802ceff9f266 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 6 Aug 2020 09:43:11 -0400 Subject: [PATCH 002/153] fix example directory sourcing --- examples/adafruit_io_mqtt/adafruit_io_groups.py | 2 +- examples/adafruit_io_mqtt/adafruit_io_location.py | 2 +- examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py | 2 +- examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py | 2 +- examples/adafruit_io_mqtt/adafruit_io_time.py | 2 +- examples/adafruit_io_simpletest.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/adafruit_io_mqtt/adafruit_io_groups.py b/examples/adafruit_io_mqtt/adafruit_io_groups.py index 6a7133c..2f278ff 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_groups.py +++ b/examples/adafruit_io_mqtt/adafruit_io_groups.py @@ -11,7 +11,7 @@ import adafruit_esp32spi.adafruit_esp32spi_socket as socket import neopixel from adafruit_io.adafruit_io import IO_MQTT -import adafruit_minimqtt as MQTT +import adafruit_minimqtt.adafruit_minimqtt as MQTT ### WiFi ### diff --git a/examples/adafruit_io_mqtt/adafruit_io_location.py b/examples/adafruit_io_mqtt/adafruit_io_location.py index cd2b862..de1d006 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_location.py +++ b/examples/adafruit_io_mqtt/adafruit_io_location.py @@ -10,7 +10,7 @@ import neopixel -import adafruit_minimqtt as MQTT +import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT ### WiFi ### diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py index 043872e..42ca892 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py @@ -16,7 +16,7 @@ import adafruit_fona.adafruit_fona_socket as cellular_socket from adafruit_io.adafruit_io import IO_MQTT -import adafruit_minimqtt as MQTT +import adafruit_minimqtt.adafruit_minimqtt as MQTT # Get MQTT details and more from a secrets.py file try: diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index 6614fa9..5ddb659 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -14,7 +14,7 @@ from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket from adafruit_io.adafruit_io import IO_MQTT -import adafruit_minimqtt as MQTT +import adafruit_minimqtt.adafruit_minimqtt as MQTT # Get MQTT details and more from a secrets.py file try: diff --git a/examples/adafruit_io_mqtt/adafruit_io_time.py b/examples/adafruit_io_mqtt/adafruit_io_time.py index 6cfdc87..ca80447 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_time.py +++ b/examples/adafruit_io_mqtt/adafruit_io_time.py @@ -10,7 +10,7 @@ import adafruit_esp32spi.adafruit_esp32spi_socket as socket import neopixel -import adafruit_minimqtt as MQTT +import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT ### WiFi ### diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index b11e715..8ad9303 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -16,7 +16,7 @@ import adafruit_esp32spi.adafruit_esp32spi_socket as socket import neopixel from adafruit_io.adafruit_io import IO_MQTT -import adafruit_minimqtt as MQTT +import adafruit_minimqtt.adafruit_minimqtt as MQTT ### WiFi ### From d513f79725049155a934a916e548b8930ae7be53 Mon Sep 17 00:00:00 2001 From: Melissa LeBlanc-Williams Date: Mon, 31 Aug 2020 09:30:58 -0700 Subject: [PATCH 003/153] Added get_all_data and linted --- adafruit_io/adafruit_io.py | 27 +++++++++++++++++++-------- adafruit_io/adafruit_io_errors.py | 6 +++--- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index afc558a..d74762e 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -70,10 +70,10 @@ def __init__(self, mqtt_client): # MiniMQTT's username kwarg is optional, IO requires a username try: self._user = self._client.user - except: + except Exception as err: raise TypeError( "Adafruit IO requires a username, please set one in MiniMQTT" - ) + ) from err # User-defined MQTT callback methods must be init'd to None self.on_connect = None self.on_disconnect = None @@ -105,8 +105,8 @@ def reconnect(self): """ try: self._client.reconnect() - except: - raise AdafruitIO_MQTTError("Unable to reconnect to Adafruit IO.") + except Exception as err: + raise AdafruitIO_MQTTError("Unable to reconnect to Adafruit IO.") from err def connect(self): """Connects to the Adafruit IO MQTT Broker. @@ -114,8 +114,8 @@ def connect(self): """ try: self._client.connect() - except: - raise AdafruitIO_MQTTError("Unable to connect to Adafruit IO.") + except Exception as err: + raise AdafruitIO_MQTTError("Unable to connect to Adafruit IO.") from err def disconnect(self): """Disconnects from Adafruit IO MQTT Broker. @@ -556,11 +556,22 @@ def send_data(self, feed_key, data, metadata=None, precision=None): if precision: try: data = round(data, precision) - except NotImplementedError: # received a non-float value - raise NotImplementedError("Precision requires a floating point value") + except NotImplementedError as err: # received a non-float value + raise NotImplementedError( + "Precision requires a floating point value" + ) from err payload = self._create_data(data, metadata) self._post(path, payload) + def receive_all_data(self, feed_key): + """ + Get all data values from a specified Adafruit IO feed. Data is + returned in reverse order. + :param str feed_key: Adafruit IO feed key + """ + path = self._compose_path("feeds/{0}/data".format(feed_key)) + return self._get(path) + def receive_data(self, feed_key): """ Return the most recent value for the specified feed. diff --git a/adafruit_io/adafruit_io_errors.py b/adafruit_io/adafruit_io_errors.py index 10e0389..3047568 100755 --- a/adafruit_io/adafruit_io_errors.py +++ b/adafruit_io/adafruit_io_errors.py @@ -31,7 +31,7 @@ class AdafruitIO_ThrottleError(Exception): """Adafruit IO request error class for rate-limiting""" def __init__(self): - super(AdafruitIO_ThrottleError, self).__init__( + super().__init__( "Number of Adafruit IO Requests exceeded! \ Please try again in 30 seconds.." ) @@ -43,7 +43,7 @@ class AdafruitIO_RequestError(Exception): def __init__(self, response): response_content = response.json() error = response_content["error"] - super(AdafruitIO_RequestError, self).__init__( + super().__init__( "Adafruit IO Error {0}: {1}".format(response.status_code, error) ) @@ -52,4 +52,4 @@ class AdafruitIO_MQTTError(Exception): """Adafruit IO MQTT error class""" def __init__(self, response): - super(AdafruitIO_MQTTError, self).__init__("MQTT Error: {0}".format(response)) + super().__init__("MQTT Error: {0}".format(response)) From 871dd8b5dc6f7155a47f9b82415e24eb9c84269f Mon Sep 17 00:00:00 2001 From: Melissa LeBlanc-Williams Date: Mon, 31 Aug 2020 09:41:23 -0700 Subject: [PATCH 004/153] Linted examples --- examples/adafruit_io_http/adafruit_io_esp_at.py | 6 +++--- examples/adafruit_io_http/adafruit_io_temperature.py | 6 +++--- examples/adafruit_io_mqtt/adafruit_io_groups.py | 2 +- .../adafruit_io_mqtt/adafruit_io_simpletest_cellular.py | 2 +- examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py | 2 +- examples/adafruit_io_simpletest.py | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_esp_at.py b/examples/adafruit_io_http/adafruit_io_esp_at.py index 2a724c8..cf703b3 100644 --- a/examples/adafruit_io_http/adafruit_io_esp_at.py +++ b/examples/adafruit_io_http/adafruit_io_esp_at.py @@ -10,9 +10,6 @@ import busio from digitalio import DigitalInOut -# Import Adafruit IO HTTP Client -from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError - # ESP32 AT from adafruit_espatcontrol import ( adafruit_espatcontrol, @@ -22,6 +19,9 @@ # Use below for Most Boards import neopixel +# Import Adafruit IO HTTP Client +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError + status_light = neopixel.NeoPixel( board.NEOPIXEL, 1, brightness=0.2 ) # Uncomment for Most Boards diff --git a/examples/adafruit_io_http/adafruit_io_temperature.py b/examples/adafruit_io_http/adafruit_io_temperature.py index 020e54c..f124b48 100644 --- a/examples/adafruit_io_http/adafruit_io_temperature.py +++ b/examples/adafruit_io_http/adafruit_io_temperature.py @@ -17,12 +17,12 @@ # Import NeoPixel Library import neopixel -# Import Adafruit IO HTTP Client -from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError - # Import ADT7410 Library import adafruit_adt7410 +# Import Adafruit IO HTTP Client +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError + # Get wifi details and more from a secrets.py file try: from secrets import secrets diff --git a/examples/adafruit_io_mqtt/adafruit_io_groups.py b/examples/adafruit_io_mqtt/adafruit_io_groups.py index 2f278ff..8077d41 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_groups.py +++ b/examples/adafruit_io_mqtt/adafruit_io_groups.py @@ -10,8 +10,8 @@ from adafruit_esp32spi import adafruit_esp32spi_wifimanager import adafruit_esp32spi.adafruit_esp32spi_socket as socket import neopixel -from adafruit_io.adafruit_io import IO_MQTT import adafruit_minimqtt.adafruit_minimqtt as MQTT +from adafruit_io.adafruit_io import IO_MQTT ### WiFi ### diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py index 42ca892..7fe24e4 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py @@ -15,8 +15,8 @@ from adafruit_fona.adafruit_fona_gsm import GSM import adafruit_fona.adafruit_fona_socket as cellular_socket -from adafruit_io.adafruit_io import IO_MQTT import adafruit_minimqtt.adafruit_minimqtt as MQTT +from adafruit_io.adafruit_io import IO_MQTT # Get MQTT details and more from a secrets.py file try: diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index 5ddb659..abf5827 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -13,8 +13,8 @@ from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket -from adafruit_io.adafruit_io import IO_MQTT import adafruit_minimqtt.adafruit_minimqtt as MQTT +from adafruit_io.adafruit_io import IO_MQTT # Get MQTT details and more from a secrets.py file try: diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index 8ad9303..6d125b1 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -15,8 +15,8 @@ from adafruit_esp32spi import adafruit_esp32spi_wifimanager import adafruit_esp32spi.adafruit_esp32spi_socket as socket import neopixel -from adafruit_io.adafruit_io import IO_MQTT import adafruit_minimqtt.adafruit_minimqtt as MQTT +from adafruit_io.adafruit_io import IO_MQTT ### WiFi ### From 60d11b761e7acaeda1e8d0bc51dd17fb8a274e95 Mon Sep 17 00:00:00 2001 From: brentru Date: Mon, 28 Sep 2020 11:21:27 -0400 Subject: [PATCH 005/153] 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 006/153] 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 007/153] 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...") From 22edebef77942380bdd1d061dfcca2dffbbde04c Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 30 Sep 2020 12:48:32 -0400 Subject: [PATCH 008/153] clarify handlers docstrings --- adafruit_io/adafruit_io.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index baa0994..20cec2c 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -205,8 +205,12 @@ def _on_unsubscribe_mqtt(self, client, user_data, topic, pid): 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. + """Attaches a callback_method to an Adafruit IO feed. + The callback_method function is called when a + new value is written to the feed. + + NOTE: The callback_method registered to this method + will only execute after a call to loop(). :param str feed_key: Adafruit IO feed key. :param str callback_method: Name of callback method. @@ -218,6 +222,9 @@ def add_feed_callback(self, 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. + + If an on_message callback is registered, new messages + will now call on_message instead of the callback_method. :param str feed_key: Adafruit IO feed key. """ From d7072b97ce6afd0dff920c41b604d32dae8dc441 Mon Sep 17 00:00:00 2001 From: Kevin Thomas Date: Fri, 9 Oct 2020 11:32:51 -0400 Subject: [PATCH 009/153] adafruit_io_simpletest.py: fix aio_user to aio_username to match default secrets.py --- examples/adafruit_io_simpletest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index 6d125b1..0af222d 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -100,7 +100,7 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( - broker="io.adafruit.com", username=secrets["aio_user"], password=secrets["aio_key"], + broker="io.adafruit.com", username=secrets["aio_username"], password=secrets["aio_key"], ) From cc6678fb9c842ade726536a44172737608bc5b4f Mon Sep 17 00:00:00 2001 From: Kevin Thomas Date: Fri, 9 Oct 2020 13:21:20 -0400 Subject: [PATCH 010/153] Updated additional aio_username issues and ran black on files --- examples/adafruit_io_mqtt/adafruit_io_groups.py | 4 +++- examples/adafruit_io_mqtt/adafruit_io_location.py | 4 +++- examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py | 4 +++- examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py | 4 +++- examples/adafruit_io_mqtt/adafruit_io_time.py | 4 +++- examples/adafruit_io_simpletest.py | 4 +++- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/examples/adafruit_io_mqtt/adafruit_io_groups.py b/examples/adafruit_io_mqtt/adafruit_io_groups.py index 8077d41..1d45f1a 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_groups.py +++ b/examples/adafruit_io_mqtt/adafruit_io_groups.py @@ -87,7 +87,9 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( - broker="io.adafruit.com", username=secrets["aio_user"], password=secrets["aio_key"], + broker="io.adafruit.com", + username=secrets["aio_username"], + password=secrets["aio_key"], ) # Initialize an Adafruit IO MQTT Client diff --git a/examples/adafruit_io_mqtt/adafruit_io_location.py b/examples/adafruit_io_mqtt/adafruit_io_location.py index de1d006..953a396 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_location.py +++ b/examples/adafruit_io_mqtt/adafruit_io_location.py @@ -86,7 +86,9 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( - broker="io.adafruit.com", username=secrets["aio_user"], password=secrets["aio_key"], + broker="io.adafruit.com", + username=secrets["aio_username"], + password=secrets["aio_key"], ) # Initialize an Adafruit IO MQTT Client diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py index 7fe24e4..b0f038b 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py @@ -85,7 +85,9 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( - broker="io.adafruit.com", username=secrets["aio_user"], password=secrets["aio_key"], + broker="io.adafruit.com", + username=secrets["aio_username"], + password=secrets["aio_key"], ) # Initialize an Adafruit IO MQTT Client diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index abf5827..567c7d8 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -70,7 +70,9 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( - broker="io.adafruit.com", username=secrets["aio_user"], password=secrets["aio_key"], + broker="io.adafruit.com", + username=secrets["aio_username"], + password=secrets["aio_key"], ) # Initialize an Adafruit IO MQTT Client diff --git a/examples/adafruit_io_mqtt/adafruit_io_time.py b/examples/adafruit_io_mqtt/adafruit_io_time.py index ca80447..ee4fadd 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_time.py +++ b/examples/adafruit_io_mqtt/adafruit_io_time.py @@ -100,7 +100,9 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( - broker="io.adafruit.com", username=secrets["aio_user"], password=secrets["aio_key"], + broker="io.adafruit.com", + username=secrets["aio_username"], + password=secrets["aio_key"], ) # Initialize an Adafruit IO MQTT Client diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index 0af222d..ea011a7 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -100,7 +100,9 @@ def message(client, feed_id, payload): # 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"], ) From 710712143d01404dd9f22961a8a6181477c572b2 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 30 Oct 2020 15:56:13 -0400 Subject: [PATCH 011/153] address rewording --- adafruit_io/adafruit_io.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 20cec2c..cf2eba0 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -210,7 +210,7 @@ def add_feed_callback(self, feed_key, callback_method): new value is written to the feed. NOTE: The callback_method registered to this method - will only execute after a call to loop(). + will only execute during loop(). :param str feed_key: Adafruit IO feed key. :param str callback_method: Name of callback method. @@ -223,8 +223,8 @@ def remove_feed_callback(self, feed_key): """Removes a previously registered callback method from executing whenever feed_key receives new data. - If an on_message callback is registered, new messages - will now call on_message instead of the callback_method. + After this method is called, incoming messages + call the shared on_message. :param str feed_key: Adafruit IO feed key. """ From aafdda0e1419dab34eb6d44c6da7a998245ef902 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 13 Nov 2020 16:07:16 -0500 Subject: [PATCH 012/153] handle throttleerrors --- adafruit_io/adafruit_io.py | 2 ++ adafruit_io/adafruit_io_errors.py | 8 +------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index cf2eba0..e270a4a 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -174,6 +174,8 @@ def _on_message_mqtt(self, client, topic, payload): messages.append(payload) topic_name = feeds message = messages + elif topic_name[1] == "throttle": + raise AdafruitIO_ThrottleError(payload) elif topic_name[0] == "time": # Adafruit IO Time Topic topic_name = topic_name[1] diff --git a/adafruit_io/adafruit_io_errors.py b/adafruit_io/adafruit_io_errors.py index 3047568..4043068 100755 --- a/adafruit_io/adafruit_io_errors.py +++ b/adafruit_io/adafruit_io_errors.py @@ -28,13 +28,7 @@ class AdafruitIO_ThrottleError(Exception): - """Adafruit IO request error class for rate-limiting""" - - def __init__(self): - super().__init__( - "Number of Adafruit IO Requests exceeded! \ - Please try again in 30 seconds.." - ) + """Adafruit IO request error class for rate-limiting.""" class AdafruitIO_RequestError(Exception): From 28aa5c2a4e1e8be5a10b3f8478718add7a096011 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 19 Nov 2020 16:39:36 -0500 Subject: [PATCH 013/153] Init with socket pool and sslcontext rather than a wifimanager for non wifi-interfaces --- adafruit_io/adafruit_io.py | 24 ++++---- .../adafruit_io_simpletest.py | 60 +++++++++---------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index e270a4a..9f0882f 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -37,6 +37,8 @@ """ import time import json +import adafruit_requests as requests + from adafruit_io.adafruit_io_errors import ( AdafruitIO_RequestError, AdafruitIO_ThrottleError, @@ -466,18 +468,18 @@ class IO_HTTP: :param str adafruit_io_username: Adafruit IO Username :param str adafruit_io_key: Adafruit IO Key - :param wifi_manager: WiFiManager object from ESPSPI_WiFiManager or ESPAT_WiFiManager + :param socket socket_pool: A pool of socket resources for the provided radio. + :param SSLContext ssl_context: Settings related to SSL that can be applied to a socket by wrapping it. """ - def __init__(self, adafruit_io_username, adafruit_io_key, wifi_manager): + def __init__(self, adafruit_io_username, adafruit_io_key, socket_pool, ssl_context=None): self.username = adafruit_io_username self.key = adafruit_io_key - wifi_type = str(type(wifi_manager)) - if "ESPSPI_WiFiManager" in wifi_type or "ESPAT_WiFiManager" in wifi_type: - self.wifi = wifi_manager - else: - raise TypeError("This library requires a WiFiManager object.") + + # Create new requests Session + self._http = requests.Session(socket_pool, ssl_context) + self._aio_headers = [ {"X-AIO-KEY": self.key, "Content-Type": "application/json"}, {"X-AIO-KEY": self.key}, @@ -519,7 +521,7 @@ def _compose_path(self, path): """Composes a valid API request path. :param str path: Adafruit IO API URL path. """ - return "https://io.adafruit.com/api/v2/{0}/{1}".format(self.username, path) + return "http://io.adafruit.com/api/v2/{0}/{1}".format(self.username, path) # HTTP Requests def _post(self, path, payload): @@ -528,7 +530,7 @@ def _post(self, path, payload): :param str path: Formatted Adafruit IO URL from _compose_path :param json payload: JSON data to send to Adafruit IO """ - response = self.wifi.post( + response = self._http.post( path, json=payload, headers=self._create_headers(self._aio_headers[0]) ) self._handle_error(response) @@ -541,7 +543,7 @@ def _get(self, path): GET data from Adafruit IO :param str path: Formatted Adafruit IO URL from _compose_path """ - response = self.wifi.get( + response = self._http.get( path, headers=self._create_headers(self._aio_headers[1]) ) self._handle_error(response) @@ -554,7 +556,7 @@ def _delete(self, path): DELETE data from Adafruit IO. :param str path: Formatted Adafruit IO URL from _compose_path """ - response = self.wifi.delete( + response = self._http.delete( path, headers=self._create_headers(self._aio_headers[0]) ) self._handle_error(response) diff --git a/examples/adafruit_io_http/adafruit_io_simpletest.py b/examples/adafruit_io_http/adafruit_io_simpletest.py index a347757..cdf1efe 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest.py @@ -1,45 +1,34 @@ -""" -Sending data to Adafruit IO and receiving it. -""" -from random import randint +# adafruit_circuitpython_adafruitio usage with an esp32spi_socket import board import busio from digitalio import DigitalInOut - -# ESP32 SPI -from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager - -# Import NeoPixel Library -import neopixel - -# Import Adafruit IO HTTP Client +import adafruit_esp32spi.adafruit_esp32spi_socket as socket +from adafruit_esp32spi import adafruit_esp32spi from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# Get wifi details and more from a secrets.py file +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order try: from secrets import secrets except ImportError: print("WiFi secrets are kept in secrets.py, please add them there!") raise -# ESP32 Setup -try: - esp32_cs = DigitalInOut(board.ESP_CS) - esp32_ready = DigitalInOut(board.ESP_BUSY) - esp32_reset = DigitalInOut(board.ESP_RESET) -except AttributeError: - esp32_cs = DigitalInOut(board.D9) - esp32_ready = DigitalInOut(board.D10) - esp32_reset = DigitalInOut(board.D5) +# 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) -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) -wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light) + # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, @@ -47,8 +36,19 @@ aio_username = secrets["aio_username"] aio_key = secrets["aio_key"] -# Create an instance of the Adafruit IO HTTP client -io = IO_HTTP(aio_username, aio_key, wifi) +print("Connecting to AP...") +while not esp.is_connected: + try: + esp.connect_AP(secrets["ssid"], secrets["password"]) + except RuntimeError as e: + print("could not connect to AP, retrying: ", e) + continue +print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) + +# Initialize an Adafruit IO HTTP API object with +# a socket and esp32spi interface +socket.set_interface(esp) +io = IO_HTTP(aio_username, aio_key, socket) try: # Get the 'temperature' feed from Adafruit IO From 62bd4e27a6d3ae88ef65d0b0106457724792f6d3 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 19 Nov 2020 17:12:41 -0500 Subject: [PATCH 014/153] allow legacy API and requests sessions to co-exist in wrapper class --- adafruit_io/adafruit_io.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 9f0882f..a3e4ffe 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -469,16 +469,22 @@ class IO_HTTP: :param str adafruit_io_username: Adafruit IO Username :param str adafruit_io_key: Adafruit IO Key :param socket socket_pool: A pool of socket resources for the provided radio. - :param SSLContext ssl_context: Settings related to SSL that can be applied to a socket by wrapping it. - + :param esp: A previously declared network interface object. """ - def __init__(self, adafruit_io_username, adafruit_io_key, socket_pool, ssl_context=None): + def __init__(self, adafruit_io_username, adafruit_io_key, socket_pool, esp=None): self.username = adafruit_io_username self.key = adafruit_io_key - # Create new requests Session - self._http = requests.Session(socket_pool, ssl_context) + if esp: + # Use legacy API + requests.set_socket(socket_pool, esp) + self._http = requests + else: + # Use requests Session API + import ssl + self._http = requests.Session(socket_pool, ssl.create_default_context()) + self._aio_headers = [ {"X-AIO-KEY": self.key, "Content-Type": "application/json"}, @@ -521,7 +527,7 @@ def _compose_path(self, path): """Composes a valid API request path. :param str path: Adafruit IO API URL path. """ - return "http://io.adafruit.com/api/v2/{0}/{1}".format(self.username, path) + return "https://io.adafruit.com/api/v2/{0}/{1}".format(self.username, path) # HTTP Requests def _post(self, path, payload): From ed74b997e84b72731530920a7cff263c40b8faae Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 19 Nov 2020 17:17:03 -0500 Subject: [PATCH 015/153] take in a requests object from user code instead of constructing it in the io interface. --- adafruit_io/adafruit_io.py | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index a3e4ffe..b645743 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -37,7 +37,6 @@ """ import time import json -import adafruit_requests as requests from adafruit_io.adafruit_io_errors import ( AdafruitIO_RequestError, @@ -468,23 +467,13 @@ class IO_HTTP: :param str adafruit_io_username: Adafruit IO Username :param str adafruit_io_key: Adafruit IO Key - :param socket socket_pool: A pool of socket resources for the provided radio. - :param esp: A previously declared network interface object. + :param requests: A passed adafruit_requests module. """ - def __init__(self, adafruit_io_username, adafruit_io_key, socket_pool, esp=None): + def __init__(self, adafruit_io_username, adafruit_io_key, requests): self.username = adafruit_io_username self.key = adafruit_io_key - - if esp: - # Use legacy API - requests.set_socket(socket_pool, esp) - self._http = requests - else: - # Use requests Session API - import ssl - self._http = requests.Session(socket_pool, ssl.create_default_context()) - + self._http = requests self._aio_headers = [ {"X-AIO-KEY": self.key, "Content-Type": "application/json"}, From aaffb61590c64ed5f87afca085fdef11f88b26c1 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 19 Nov 2020 17:18:05 -0500 Subject: [PATCH 016/153] Add new example, remove cruft from old example and match requests example --- .../adafruit_io_simpletest.py | 141 +++++++++--------- 1 file changed, 72 insertions(+), 69 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_simpletest.py b/examples/adafruit_io_http/adafruit_io_simpletest.py index cdf1efe..d3126f4 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest.py @@ -1,69 +1,72 @@ -# adafruit_circuitpython_adafruitio usage with an esp32spi_socket -import board -import busio -from digitalio import DigitalInOut -import adafruit_esp32spi.adafruit_esp32spi_socket as socket -from adafruit_esp32spi import adafruit_esp32spi -from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError - -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -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) - - -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - -print("Connecting to AP...") -while not esp.is_connected: - try: - esp.connect_AP(secrets["ssid"], secrets["password"]) - except RuntimeError as e: - print("could not connect to AP, retrying: ", e) - continue -print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) - -# Initialize an Adafruit IO HTTP API object with -# a socket and esp32spi interface -socket.set_interface(esp) -io = IO_HTTP(aio_username, aio_key, socket) - -try: - # Get the 'temperature' feed from Adafruit IO - temperature_feed = io.get_feed("temperature") -except AdafruitIO_RequestError: - # If no 'temperature' feed exists, create one - temperature_feed = io.create_new_feed("temperature") - -# Send random integer values to the feed -random_value = randint(0, 50) -print("Sending {0} to temperature feed...".format(random_value)) -io.send_data(temperature_feed["key"], random_value) -print("Data sent!") - -# Retrieve data value from the feed -print("Retrieving data from temperature feed...") -received_data = io.receive_data(temperature_feed["key"]) -print("Data from temperature feed: ", received_data["value"]) +# adafruit_circuitpython_adafruitio usage with an esp32spi_socket +from random import randint +import board +import busio +from digitalio import DigitalInOut +import adafruit_esp32spi.adafruit_esp32spi_socket as socket +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_requests as requests +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError + +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order +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) + + +# Set your Adafruit IO Username and Key in secrets.py +# (visit io.adafruit.com if you need to create an account, +# or if you need your Adafruit IO key.) +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + +print("Connecting to AP...") +while not esp.is_connected: + try: + esp.connect_AP(secrets["ssid"], secrets["password"]) + except RuntimeError as e: + print("could not connect to AP, retrying: ", e) + continue +print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) + +socket.set_interface(esp) +requests.set_socket(socket, esp) + +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) + +try: + # Get the 'temperature' feed from Adafruit IO + temperature_feed = io.get_feed("temperature") +except AdafruitIO_RequestError: + # If no 'temperature' feed exists, create one + temperature_feed = io.create_new_feed("temperature") + +# Send random integer values to the feed +random_value = randint(0, 50) +print("Sending {0} to temperature feed...".format(random_value)) +io.send_data(temperature_feed["key"], random_value) +print("Data sent!") + +# Retrieve data value from the feed +print("Retrieving data from temperature feed...") +received_data = io.receive_data(temperature_feed["key"]) +print("Data from temperature feed: ", received_data["value"]) From 6dbcccae0f88215bfda879163bb5ad5c5bc86166 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 19 Nov 2020 17:32:44 -0500 Subject: [PATCH 017/153] add working CPython example --- .../adafruit_io_simpletest_cpython.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 examples/adafruit_io_http/adafruit_io_simpletest_cpython.py diff --git a/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py b/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py new file mode 100644 index 0000000..e2cc823 --- /dev/null +++ b/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py @@ -0,0 +1,45 @@ +# adafruit_circuitpython_adafruitio usage with a CPython socket +import socket +import ssl +from random import randint +import adafruit_requests +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError + +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order +try: + from secrets import secrets +except ImportError: + print("WiFi secrets are kept in secrets.py, please add them there!") + raise + +# Set your Adafruit IO Username and Key in secrets.py +# (visit io.adafruit.com if you need to create an account, +# or if you need your Adafruit IO key.) +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + + +requests = adafruit_requests.Session(socket, ssl.create_default_context()) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) + +try: + # Get the 'temperature' feed from Adafruit IO + temperature_feed = io.get_feed("temperature") +except AdafruitIO_RequestError: + # If no 'temperature' feed exists, create one + temperature_feed = io.create_new_feed("temperature") + +# Send random integer values to the feed +random_value = randint(0, 50) +print("Sending {0} to temperature feed...".format(random_value)) +io.send_data(temperature_feed["key"], random_value) +print("Data sent!") + +# Retrieve data value from the feed +print("Retrieving data from temperature feed...") +received_data = io.receive_data(temperature_feed["key"]) +print("Data from temperature feed: ", received_data["value"]) From a52759be764a8aaec028f1042e111799b879cc5e Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 19 Nov 2020 17:39:14 -0500 Subject: [PATCH 018/153] update feeds example, reorg. code --- .../adafruit_io_http/adafruit_io_feeds.py | 64 ++++++++++--------- .../adafruit_io_simpletest.py | 13 ++-- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_feeds.py b/examples/adafruit_io_http/adafruit_io_feeds.py index 5240957..64a8719 100644 --- a/examples/adafruit_io_http/adafruit_io_feeds.py +++ b/examples/adafruit_io_http/adafruit_io_feeds.py @@ -1,44 +1,48 @@ -""" -Example of interacting with Adafruit IO feeds -""" +# Adafruit IO HTTP API - Feed Interactions +# Documentation: https://io.adafruit.com/api/docs/#feeds +# adafruit_circuitpython_adafruitio with an esp32spi_socket import board import busio from digitalio import DigitalInOut +import adafruit_esp32spi.adafruit_esp32spi_socket as socket +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_requests as requests +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# ESP32 SPI -from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager - -# Import NeoPixel Library -import neopixel - -# Import Adafruit IO HTTP Client -from adafruit_io.adafruit_io import IO_HTTP - -# Get wifi details and more from a secrets.py file +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order try: from secrets import secrets except ImportError: print("WiFi secrets are kept in secrets.py, please add them there!") raise -# ESP32 Setup -try: - esp32_cs = DigitalInOut(board.ESP_CS) - esp32_ready = DigitalInOut(board.ESP_BUSY) - esp32_reset = DigitalInOut(board.ESP_RESET) -except AttributeError: - esp32_cs = DigitalInOut(board.D9) - esp32_ready = DigitalInOut(board.D10) - esp32_reset = DigitalInOut(board.D5) +# 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) -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) -wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light) + +print("Connecting to AP...") +while not esp.is_connected: + try: + esp.connect_AP(secrets["ssid"], secrets["password"]) + except RuntimeError as e: + print("could not connect to AP, retrying: ", e) + continue +print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) + +socket.set_interface(esp) +requests.set_socket(socket, esp) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, @@ -46,8 +50,8 @@ aio_username = secrets["aio_username"] aio_key = secrets["aio_key"] -# Create an instance of the Adafruit IO HTTP client -io = IO_HTTP(aio_username, aio_key, wifi) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) # Create a new 'circuitpython' feed with a description print("Creating new Adafruit IO feed...") diff --git a/examples/adafruit_io_http/adafruit_io_simpletest.py b/examples/adafruit_io_http/adafruit_io_simpletest.py index d3126f4..6444252 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest.py @@ -31,13 +31,6 @@ spi = busio.SPI(board.SCK, board.MOSI, board.MISO) esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) - -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - print("Connecting to AP...") while not esp.is_connected: try: @@ -50,6 +43,12 @@ socket.set_interface(esp) requests.set_socket(socket, esp) +# Set your Adafruit IO Username and Key in secrets.py +# (visit io.adafruit.com if you need to create an account, +# or if you need your Adafruit IO key.) +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) From 1d7e14bb89be945d01d0e025ace6c7ec8db20b7f Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 19 Nov 2020 17:42:56 -0500 Subject: [PATCH 019/153] update groups example for esp32spi --- .../adafruit_io_http/adafruit_io_groups.py | 64 ++++++++++--------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index 436d321..b1d915e 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -1,52 +1,58 @@ -""" -Example of performing group operations -""" +# Adafruit IO HTTP API - Group Interactions +# Documentation: https://io.adafruit.com/api/docs/#groups +# adafruit_circuitpython_adafruitio with an esp32spi_socket import board import busio from digitalio import DigitalInOut +import adafruit_esp32spi.adafruit_esp32spi_socket as socket +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_requests as requests +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# ESP32 SPI -from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager -# Import NeoPixel Library -import neopixel - -# Import Adafruit IO HTTP Client -from adafruit_io.adafruit_io import IO_HTTP - -# Get wifi details and more from a secrets.py file +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order try: from secrets import secrets except ImportError: print("WiFi secrets are kept in secrets.py, please add them there!") raise -# ESP32 Setup -try: - esp32_cs = DigitalInOut(board.ESP_CS) - esp32_ready = DigitalInOut(board.ESP_BUSY) - esp32_reset = DigitalInOut(board.ESP_RESET) -except AttributeError: - esp32_cs = DigitalInOut(board.D9) - esp32_ready = DigitalInOut(board.D10) - esp32_reset = DigitalInOut(board.D5) +# 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) -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) -wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light) + +print("Connecting to AP...") +while not esp.is_connected: + try: + esp.connect_AP(secrets["ssid"], secrets["password"]) + except RuntimeError as e: + print("could not connect to AP, retrying: ", e) + continue +print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) + +socket.set_interface(esp) +requests.set_socket(socket, esp) + # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, # or if you need your Adafruit IO key.) aio_username = secrets["aio_username"] aio_key = secrets["aio_key"] -# Create an instance of the Adafruit IO HTTP client -io = IO_HTTP(aio_username, aio_key, wifi) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) # Create a new group print("Creating a new Adafruit IO Group...") From f5e03240032234203f4968ae8d94c2b9a03ae102 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 19 Nov 2020 17:46:43 -0500 Subject: [PATCH 020/153] update metadata example for esp32s2pi, add line to display feed after its updated --- .../adafruit_io_http/adafruit_io_metadata.py | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_metadata.py b/examples/adafruit_io_http/adafruit_io_metadata.py index dcabe10..00aa3bc 100644 --- a/examples/adafruit_io_http/adafruit_io_metadata.py +++ b/examples/adafruit_io_http/adafruit_io_metadata.py @@ -1,45 +1,47 @@ -""" -Example of attaching metadata -to data sent to Adafruit IO. -""" +# Adafruit IO HTTP API - Sending values with optional metadata +# adafruit_circuitpython_adafruitio with an esp32spi_socket import board import busio from digitalio import DigitalInOut - -# ESP32 SPI -from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager - -# Import NeoPixel Library -import neopixel - -# Import Adafruit IO HTTP Client +import adafruit_esp32spi.adafruit_esp32spi_socket as socket +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_requests as requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# Get wifi details and more from a secrets.py file +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order try: from secrets import secrets except ImportError: print("WiFi secrets are kept in secrets.py, please add them there!") raise -# ESP32 Setup -try: - esp32_cs = DigitalInOut(board.ESP_CS) - esp32_ready = DigitalInOut(board.ESP_BUSY) - esp32_reset = DigitalInOut(board.ESP_RESET) -except AttributeError: - esp32_cs = DigitalInOut(board.D9) - esp32_ready = DigitalInOut(board.D10) - esp32_reset = DigitalInOut(board.D5) +# 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) -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) -wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light) + +print("Connecting to AP...") +while not esp.is_connected: + try: + esp.connect_AP(secrets["ssid"], secrets["password"]) + except RuntimeError as e: + print("could not connect to AP, retrying: ", e) + continue +print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) + +socket.set_interface(esp) +requests.set_socket(socket, esp) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, @@ -47,8 +49,8 @@ aio_username = secrets["aio_username"] aio_key = secrets["aio_key"] -# Create an instance of the Adafruit IO HTTP client -io = IO_HTTP(aio_username, aio_key, wifi) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) try: # Get the 'location' feed from Adafruit IO From c8ef29a4f18a99faba437354fc09482c141cbefc Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 19 Nov 2020 17:51:40 -0500 Subject: [PATCH 021/153] add digital out, TODO: improve example to track LED state --- .../adafruit_io_digital_out.py | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_digital_out.py b/examples/adafruit_io_http/adafruit_io_digital_out.py index 1f57b12..58418e9 100644 --- a/examples/adafruit_io_http/adafruit_io_digital_out.py +++ b/examples/adafruit_io_http/adafruit_io_digital_out.py @@ -1,46 +1,48 @@ -""" -Example of turning on and off a LED -from an Adafruit IO Dashboard. -""" +# Turn on and off a LED from your Adafruit IO Dashboard. +# adafruit_circuitpython_adafruitio with an esp32spi_socket import time import board import busio from digitalio import DigitalInOut, Direction - -# ESP32 SPI -from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager - -# Import NeoPixel Library -import neopixel - -# Import Adafruit IO HTTP Client +import adafruit_esp32spi.adafruit_esp32spi_socket as socket +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_requests as requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# Get wifi details and more from a secrets.py file +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order try: from secrets import secrets except ImportError: print("WiFi secrets are kept in secrets.py, please add them there!") raise -# ESP32 Setup -try: - esp32_cs = DigitalInOut(board.ESP_CS) - esp32_ready = DigitalInOut(board.ESP_BUSY) - esp32_reset = DigitalInOut(board.ESP_RESET) -except AttributeError: - esp32_cs = DigitalInOut(board.D9) - esp32_ready = DigitalInOut(board.D10) - esp32_reset = DigitalInOut(board.D5) +# 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) -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) -wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light) + +print("Connecting to AP...") +while not esp.is_connected: + try: + esp.connect_AP(secrets["ssid"], secrets["password"]) + except RuntimeError as e: + print("could not connect to AP, retrying: ", e) + continue +print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) + +socket.set_interface(esp) +requests.set_socket(socket, esp) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, @@ -48,8 +50,8 @@ aio_username = secrets["aio_username"] aio_key = secrets["aio_key"] -# Create an instance of the Adafruit IO HTTP client -io = IO_HTTP(aio_username, aio_key, wifi) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) try: # Get the 'digital' feed from Adafruit IO From 8db940750faee66cb1651bc41d32cd1679c1302c Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 19 Nov 2020 17:54:26 -0500 Subject: [PATCH 022/153] update analog input example for esp32spi, make it less pyportal-specific --- .../adafruit_io_http/adafruit_io_analog_in.py | 72 ++++++++++--------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_analog_in.py b/examples/adafruit_io_http/adafruit_io_analog_in.py index a1c4c53..6acdbc3 100644 --- a/examples/adafruit_io_http/adafruit_io_analog_in.py +++ b/examples/adafruit_io_http/adafruit_io_analog_in.py @@ -1,48 +1,49 @@ -""" -Example of reading an analog light sensor -and sending the value to Adafruit IO -""" +# Example of publishing the value of an ADC to Adafruit IO +# adafruit_circuitpython_adafruitio with an esp32spi_socket import time import board import busio -from digitalio import DigitalInOut from analogio import AnalogIn -from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager - -# Import NeoPixel Library -import neopixel - -# Import Adafruit IO HTTP Client +from digitalio import DigitalInOut +import adafruit_esp32spi.adafruit_esp32spi_socket as socket +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_requests as requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# Delay between polling and sending light sensor data, in seconds -SENSOR_DELAY = 30 - -# Get wifi details and more from a secrets.py file +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order try: from secrets import secrets except ImportError: print("WiFi secrets are kept in secrets.py, please add them there!") raise -# ESP32 Setup -try: - esp32_cs = DigitalInOut(board.ESP_CS) - esp32_ready = DigitalInOut(board.ESP_BUSY) - esp32_reset = DigitalInOut(board.ESP_RESET) -except AttributeError: - esp32_cs = DigitalInOut(board.D9) - esp32_ready = DigitalInOut(board.D10) - esp32_reset = DigitalInOut(board.D5) +# 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) -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) -wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light) + +print("Connecting to AP...") +while not esp.is_connected: + try: + esp.connect_AP(secrets["ssid"], secrets["password"]) + except RuntimeError as e: + print("could not connect to AP, retrying: ", e) + continue +print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) + +socket.set_interface(esp) +requests.set_socket(socket, esp) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, @@ -50,8 +51,8 @@ aio_username = secrets["aio_username"] aio_key = secrets["aio_key"] -# Create an instance of the Adafruit IO HTTP client -io = IO_HTTP(aio_username, aio_key, wifi) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) try: # Get the 'light' feed from Adafruit IO @@ -60,12 +61,13 @@ # If no 'light' feed exists, create one light_feed = io.create_new_feed("light") -# Set up an analog light sensor on the PyPortal -adc = AnalogIn(board.LIGHT) +# Set up an ADC +adc = AnalogIn(board.A0) +SENSOR_DELAY = 30 while True: light_value = adc.value - print("Light Level: ", light_value) + print("ADC Value: ", light_value) print("Sending to Adafruit IO...") io.send_data(light_feed["key"], light_value) print("Sent!") From 215b5a44bcd4192b9526dd24bcbdffa8a3d05e4d Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 19 Nov 2020 17:59:34 -0500 Subject: [PATCH 023/153] add randomizer service --- .../adafruit_io_randomizer.py | 79 +++++++++---------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_randomizer.py b/examples/adafruit_io_http/adafruit_io_randomizer.py index b2889ed..6c9438b 100644 --- a/examples/adafruit_io_http/adafruit_io_randomizer.py +++ b/examples/adafruit_io_http/adafruit_io_randomizer.py @@ -1,46 +1,48 @@ -""" -Example of using Adafruit IO's -random data service. -""" +# Example for using Adafruit IO's random data (randomizer) service +# adafruit_circuitpython_adafruitio with an esp32spi_socket import time import board import busio from digitalio import DigitalInOut +import adafruit_esp32spi.adafruit_esp32spi_socket as socket +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_requests as requests +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# ESP32 SPI -from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager - -# Import NeoPixel Library -import neopixel - -# Import Adafruit IO HTTP Client -from adafruit_io.adafruit_io import IO_HTTP - -# Get wifi details and more from a secrets.py file +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order try: from secrets import secrets except ImportError: print("WiFi secrets are kept in secrets.py, please add them there!") raise -# ESP32 Setup -try: - esp32_cs = DigitalInOut(board.ESP_CS) - esp32_ready = DigitalInOut(board.ESP_BUSY) - esp32_reset = DigitalInOut(board.ESP_RESET) -except AttributeError: - esp32_cs = DigitalInOut(board.D9) - esp32_ready = DigitalInOut(board.D10) - esp32_reset = DigitalInOut(board.D5) +# 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) -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) -wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light) + +print("Connecting to AP...") +while not esp.is_connected: + try: + esp.connect_AP(secrets["ssid"], secrets["password"]) + except RuntimeError as e: + print("could not connect to AP, retrying: ", e) + continue +print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) + +socket.set_interface(esp) +requests.set_socket(socket, esp) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, @@ -48,8 +50,8 @@ aio_username = secrets["aio_username"] aio_key = secrets["aio_key"] -# Create an instance of the Adafruit IO HTTP client -io = IO_HTTP(aio_username, aio_key, wifi) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) # Random Data ID # (to obtain this value, visit @@ -58,14 +60,9 @@ random_data_id = 1234 while True: - try: - print("Fetching random data from Adafruit IO...") - random_data = io.receive_random_data(random_data_id) - print("Random Data: ", random_data["value"]) - print("Data Seed: ", random_data["seed"]) - print("Waiting 1 minute to fetch new randomized data...") - except (ValueError, RuntimeError) as e: - print("Failed to get data, retrying\n", e) - wifi.reset() - continue + print("Fetching random data from Adafruit IO...") + random_data = io.receive_random_data(random_data_id) + print("Random Data: ", random_data["value"]) + print("Data Seed: ", random_data["seed"]) + print("Waiting 1 minute to fetch new randomized data...") time.sleep(60) From f95ce6a9ab9e2052dde04761f1eefa5db2265d27 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 19 Nov 2020 18:03:40 -0500 Subject: [PATCH 024/153] add weather service --- .../adafruit_io_http/adafruit_io_weather.py | 65 ++++++++++--------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_weather.py b/examples/adafruit_io_http/adafruit_io_weather.py index 33fc0f4..cd2b593 100644 --- a/examples/adafruit_io_http/adafruit_io_weather.py +++ b/examples/adafruit_io_http/adafruit_io_weather.py @@ -4,44 +4,49 @@ NOTE: This example is for Adafruit IO Plus subscribers only. """ +import time import board import busio from digitalio import DigitalInOut +import adafruit_esp32spi.adafruit_esp32spi_socket as socket +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_requests as requests +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# ESP32 SPI -from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager - -# Import NeoPixel Library -import neopixel - -# Import Adafruit IO HTTP Client -from adafruit_io.adafruit_io import IO_HTTP - -# Get wifi details and more from a secrets.py file +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order try: from secrets import secrets except ImportError: print("WiFi secrets are kept in secrets.py, please add them there!") raise -# ESP32 Setup -try: - esp32_cs = DigitalInOut(board.ESP_CS) - esp32_ready = DigitalInOut(board.ESP_BUSY) - esp32_reset = DigitalInOut(board.ESP_RESET) -except AttributeError: - esp32_cs = DigitalInOut(board.D9) - esp32_ready = DigitalInOut(board.D10) - esp32_reset = DigitalInOut(board.D5) +# 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) -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) -wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light) + +print("Connecting to AP...") +while not esp.is_connected: + try: + esp.connect_AP(secrets["ssid"], secrets["password"]) + except RuntimeError as e: + print("could not connect to AP, retrying: ", e) + continue +print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) + +socket.set_interface(esp) +requests.set_socket(socket, esp) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, @@ -49,17 +54,17 @@ aio_username = secrets["aio_username"] aio_key = secrets["aio_key"] -# Create an instance of the Adafruit IO HTTP client -io = IO_HTTP(aio_username, aio_key, wifi) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) # Weather Location ID # (to obtain this value, visit # https://io.adafruit.com/services/weather # and copy over the location ID) -location_id = 1234 +location_id = 2127 -print("Getting weather record from IO...") -# Get the specified weather record with current weather +print("Getting forecast from IO...") +# Fetch the specified record with current weather # and all available forecast information. forecast = io.receive_weather(location_id) From ed1f9d4032f5cb99a401ebaff536fad0fc621467 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 20 Nov 2020 10:34:08 -0500 Subject: [PATCH 025/153] add temp sensor, weather --- .../adafruit_io_temperature.py | 70 +++++++++---------- .../adafruit_io_http/adafruit_io_weather.py | 8 +-- 2 files changed, 35 insertions(+), 43 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_temperature.py b/examples/adafruit_io_http/adafruit_io_temperature.py index f124b48..aaf3420 100644 --- a/examples/adafruit_io_http/adafruit_io_temperature.py +++ b/examples/adafruit_io_http/adafruit_io_temperature.py @@ -1,53 +1,49 @@ -""" -Example of sending temperature -values to an Adafruit IO feed. - -Dependencies: - * CircuitPython_ADT7410 - https://github.com/adafruit/Adafruit_CircuitPython_ADT7410 -""" +# Example of sending ADT7410 sensor temperature values to IO +# adafruit_circuitpython_adafruitio with an esp32spi_socket import time import board import busio from digitalio import DigitalInOut - -# ESP32 SPI -from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager - -# Import NeoPixel Library -import neopixel - -# Import ADT7410 Library -import adafruit_adt7410 - -# Import Adafruit IO HTTP Client +import adafruit_esp32spi.adafruit_esp32spi_socket as socket +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_requests as requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError +import adafruit_adt7410 -# Get wifi details and more from a secrets.py file +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order try: from secrets import secrets except ImportError: print("WiFi secrets are kept in secrets.py, please add them there!") raise -# ESP32 Setup -try: - esp32_cs = DigitalInOut(board.ESP_CS) - esp32_ready = DigitalInOut(board.ESP_BUSY) - esp32_reset = DigitalInOut(board.ESP_RESET) -except AttributeError: - esp32_cs = DigitalInOut(board.D9) - esp32_ready = DigitalInOut(board.D10) - esp32_reset = DigitalInOut(board.D5) +# 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) -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) -wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light) + +print("Connecting to AP...") +while not esp.is_connected: + try: + esp.connect_AP(secrets["ssid"], secrets["password"]) + except RuntimeError as e: + print("could not connect to AP, retrying: ", e) + continue +print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) + +socket.set_interface(esp) +requests.set_socket(socket, esp) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, @@ -55,8 +51,8 @@ aio_username = secrets["aio_username"] aio_key = secrets["aio_key"] -# Create an instance of the Adafruit IO HTTP client -io = IO_HTTP(aio_username, aio_key, wifi) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) try: # Get the 'temperature' feed from Adafruit IO diff --git a/examples/adafruit_io_http/adafruit_io_weather.py b/examples/adafruit_io_http/adafruit_io_weather.py index cd2b593..42e394b 100644 --- a/examples/adafruit_io_http/adafruit_io_weather.py +++ b/examples/adafruit_io_http/adafruit_io_weather.py @@ -1,9 +1,5 @@ -""" -Example of getting weather -from the Adafruit IO Weather Service -NOTE: This example is for Adafruit IO -Plus subscribers only. -""" +# Example of using the Adafruit IO+ Weather Service +# adafruit_circuitpython_adafruitio with an esp32spi_socket import time import board import busio From cb346e6439218a987e6b3eafb58b0bf970b0791e Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 20 Nov 2020 10:36:58 -0500 Subject: [PATCH 026/153] remove atcontrol example --- .../adafruit_io_http/adafruit_io_esp_at.py | 91 ------------------- 1 file changed, 91 deletions(-) delete mode 100644 examples/adafruit_io_http/adafruit_io_esp_at.py diff --git a/examples/adafruit_io_http/adafruit_io_esp_at.py b/examples/adafruit_io_http/adafruit_io_esp_at.py deleted file mode 100644 index cf703b3..0000000 --- a/examples/adafruit_io_http/adafruit_io_esp_at.py +++ /dev/null @@ -1,91 +0,0 @@ -""" -Usage example of the ESP32 over UART -using the CircuitPython ESP_ATControl library. - -Dependencies: - * https://github.com/adafruit/Adafruit_CircuitPython_ESP_ATcontrol -""" -from random import randint -import board -import busio -from digitalio import DigitalInOut - -# ESP32 AT -from adafruit_espatcontrol import ( - adafruit_espatcontrol, - adafruit_espatcontrol_wifimanager, -) - -# Use below for Most Boards -import neopixel - -# Import Adafruit IO HTTP Client -from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError - -status_light = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards - -# Uncomment below for ItsyBitsy M4# -# import adafruit_dotstar as dotstar -# status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) - -# Uncomment below for Particle Argon# -# status_light = None - -# 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 - -# With a Metro or Feather M4 -uart = busio.UART(board.TX, board.RX, timeout=0.1) -resetpin = DigitalInOut(board.D5) -rtspin = DigitalInOut(board.D6) - -# With a Particle Argon -""" -RX = board.ESP_TX -TX = board.ESP_RX -resetpin = DigitalInOut(board.ESP_WIFI_EN) -rtspin = DigitalInOut(board.ESP_CTS) -uart = busio.UART(TX, RX, timeout=0.1) -esp_boot = DigitalInOut(board.ESP_BOOT_MODE) -from digitalio import Direction -esp_boot.direction = Direction.OUTPUT -esp_boot.value = True -""" - -esp = adafruit_espatcontrol.ESP_ATcontrol( - uart, 115200, reset_pin=resetpin, rts_pin=rtspin, debug=False -) -wifi = adafruit_espatcontrol_wifimanager.ESPAT_WiFiManager(esp, secrets, status_light) - -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - -# Create an instance of the Adafruit IO HTTP client -io = IO_HTTP(aio_username, aio_key, wifi) - -try: - # Get the 'temperature' feed from Adafruit IO - temperature_feed = io.get_feed("temperature") -except AdafruitIO_RequestError: - # If no 'temperature' feed exists, create one - temperature_feed = io.create_new_feed("temperature") - -# Send random integer values to the feed -random_value = randint(0, 50) -print("Sending {0} to temperature feed...".format(random_value)) -io.send_data(temperature_feed["key"], random_value) -print("Data sent!") - -# Retrieve data value from the feed -print("Retrieving data from temperature feed...") -received_data = io.receive_data(temperature_feed["key"]) -print("Data from temperature feed: ", received_data["value"]) From db78907790baef8972380bd7a32e28f323f20487 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 20 Nov 2020 11:03:44 -0500 Subject: [PATCH 027/153] add exampel for native wifi networking --- .../adafruit_io_simpletest_wifi.py | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 examples/adafruit_io_http/adafruit_io_simpletest_wifi.py diff --git a/examples/adafruit_io_http/adafruit_io_simpletest_wifi.py b/examples/adafruit_io_http/adafruit_io_simpletest_wifi.py new file mode 100644 index 0000000..7bdd44c --- /dev/null +++ b/examples/adafruit_io_http/adafruit_io_simpletest_wifi.py @@ -0,0 +1,51 @@ +# adafruit_circuitpython_adafruitio usage with native wifi networking +import ssl +from random import randint +import adafruit_requests +import socketpool +import wifi +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError + +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order +try: + from secrets import secrets +except ImportError: + print("WiFi secrets are kept in secrets.py, please add them there!") + raise + +# Set your Adafruit IO Username and Key in secrets.py +# (visit io.adafruit.com if you need to create an account, +# or if you need your Adafruit IO key.) +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + +print("Connecting to %s"%secrets["ssid"]) +wifi.radio.connect(secrets["ssid"], secrets["password"]) +print("Connected to %s!"%secrets["ssid"]) + + +pool = socketpool.SocketPool(wifi.radio) +requests = adafruit_requests.Session(pool, ssl.create_default_context()) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) + +try: + # Get the 'temperature' feed from Adafruit IO + temperature_feed = io.get_feed("temperature") +except AdafruitIO_RequestError: + # If no 'temperature' feed exists, create one + temperature_feed = io.create_new_feed("temperature") + +# Send random integer values to the feed +random_value = randint(0, 50) +print("Sending {0} to temperature feed...".format(random_value)) +io.send_data(temperature_feed["key"], random_value) +print("Data sent!") + +# Retrieve data value from the feed +print("Retrieving data from temperature feed...") +received_data = io.receive_data(temperature_feed["key"]) +print("Data from temperature feed: ", received_data["value"]) From 1ebad058e17b93ea051b1975171d7e7acd7fe10b Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 20 Nov 2020 11:39:53 -0500 Subject: [PATCH 028/153] reorganize examples, 1st class native networking --- .../adafruit_io_http/adafruit_io_feeds.py | 2 +- .../adafruit_io_http/adafruit_io_groups.py | 2 +- .../adafruit_io_randomizer.py | 2 +- .../adafruit_io_simpletest.py | 122 ++++++++---------- .../adafruit_io_simpletest_wifi.py | 51 -------- .../adafruit_io_temperature.py | 21 ++- .../adafruit_io_http/adafruit_io_weather.py | 3 +- 7 files changed, 63 insertions(+), 140 deletions(-) delete mode 100644 examples/adafruit_io_http/adafruit_io_simpletest_wifi.py diff --git a/examples/adafruit_io_http/adafruit_io_feeds.py b/examples/adafruit_io_http/adafruit_io_feeds.py index 64a8719..d70819e 100644 --- a/examples/adafruit_io_http/adafruit_io_feeds.py +++ b/examples/adafruit_io_http/adafruit_io_feeds.py @@ -7,7 +7,7 @@ import adafruit_esp32spi.adafruit_esp32spi_socket as socket from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests as requests -from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError +from adafruit_io.adafruit_io import IO_HTTP # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and # "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index b1d915e..e894dff 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -7,7 +7,7 @@ import adafruit_esp32spi.adafruit_esp32spi_socket as socket from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests as requests -from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError +from adafruit_io.adafruit_io import IO_HTTP # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and diff --git a/examples/adafruit_io_http/adafruit_io_randomizer.py b/examples/adafruit_io_http/adafruit_io_randomizer.py index 6c9438b..96e4039 100644 --- a/examples/adafruit_io_http/adafruit_io_randomizer.py +++ b/examples/adafruit_io_http/adafruit_io_randomizer.py @@ -7,7 +7,7 @@ import adafruit_esp32spi.adafruit_esp32spi_socket as socket from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests as requests -from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError +from adafruit_io.adafruit_io import IO_HTTP # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and # "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other diff --git a/examples/adafruit_io_http/adafruit_io_simpletest.py b/examples/adafruit_io_http/adafruit_io_simpletest.py index 6444252..26749d1 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest.py @@ -1,71 +1,51 @@ -# adafruit_circuitpython_adafruitio usage with an esp32spi_socket -from random import randint -import board -import busio -from digitalio import DigitalInOut -import adafruit_esp32spi.adafruit_esp32spi_socket as socket -from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests as requests -from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError - -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -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) - -print("Connecting to AP...") -while not esp.is_connected: - try: - esp.connect_AP(secrets["ssid"], secrets["password"]) - except RuntimeError as e: - print("could not connect to AP, retrying: ", e) - continue -print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) - -socket.set_interface(esp) -requests.set_socket(socket, esp) - -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - -# Initialize an Adafruit IO HTTP API object -io = IO_HTTP(aio_username, aio_key, requests) - -try: - # Get the 'temperature' feed from Adafruit IO - temperature_feed = io.get_feed("temperature") -except AdafruitIO_RequestError: - # If no 'temperature' feed exists, create one - temperature_feed = io.create_new_feed("temperature") - -# Send random integer values to the feed -random_value = randint(0, 50) -print("Sending {0} to temperature feed...".format(random_value)) -io.send_data(temperature_feed["key"], random_value) -print("Data sent!") - -# Retrieve data value from the feed -print("Retrieving data from temperature feed...") -received_data = io.receive_data(temperature_feed["key"]) -print("Data from temperature feed: ", received_data["value"]) +# adafruit_circuitpython_adafruitio usage with native wifi networking +import ssl +from random import randint +import adafruit_requests +import socketpool +import wifi +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError + +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order +try: + from secrets import secrets +except ImportError: + print("WiFi secrets are kept in secrets.py, please add them there!") + raise + +# Set your Adafruit IO Username and Key in secrets.py +# (visit io.adafruit.com if you need to create an account, +# or if you need your Adafruit IO key.) +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + +print("Connecting to %s" % secrets["ssid"]) +wifi.radio.connect(secrets["ssid"], secrets["password"]) +print("Connected to %s!" % secrets["ssid"]) + + +pool = socketpool.SocketPool(wifi.radio) +requests = adafruit_requests.Session(pool, ssl.create_default_context()) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) + +try: + # Get the 'temperature' feed from Adafruit IO + temperature_feed = io.get_feed("temperature") +except AdafruitIO_RequestError: + # If no 'temperature' feed exists, create one + temperature_feed = io.create_new_feed("temperature") + +# Send random integer values to the feed +random_value = randint(0, 50) +print("Sending {0} to temperature feed...".format(random_value)) +io.send_data(temperature_feed["key"], random_value) +print("Data sent!") + +# Retrieve data value from the feed +print("Retrieving data from temperature feed...") +received_data = io.receive_data(temperature_feed["key"]) +print("Data from temperature feed: ", received_data["value"]) diff --git a/examples/adafruit_io_http/adafruit_io_simpletest_wifi.py b/examples/adafruit_io_http/adafruit_io_simpletest_wifi.py deleted file mode 100644 index 7bdd44c..0000000 --- a/examples/adafruit_io_http/adafruit_io_simpletest_wifi.py +++ /dev/null @@ -1,51 +0,0 @@ -# adafruit_circuitpython_adafruitio usage with native wifi networking -import ssl -from random import randint -import adafruit_requests -import socketpool -import wifi -from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError - -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise - -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - -print("Connecting to %s"%secrets["ssid"]) -wifi.radio.connect(secrets["ssid"], secrets["password"]) -print("Connected to %s!"%secrets["ssid"]) - - -pool = socketpool.SocketPool(wifi.radio) -requests = adafruit_requests.Session(pool, ssl.create_default_context()) -# Initialize an Adafruit IO HTTP API object -io = IO_HTTP(aio_username, aio_key, requests) - -try: - # Get the 'temperature' feed from Adafruit IO - temperature_feed = io.get_feed("temperature") -except AdafruitIO_RequestError: - # If no 'temperature' feed exists, create one - temperature_feed = io.create_new_feed("temperature") - -# Send random integer values to the feed -random_value = randint(0, 50) -print("Sending {0} to temperature feed...".format(random_value)) -io.send_data(temperature_feed["key"], random_value) -print("Data sent!") - -# Retrieve data value from the feed -print("Retrieving data from temperature feed...") -received_data = io.receive_data(temperature_feed["key"]) -print("Data from temperature feed: ", received_data["value"]) diff --git a/examples/adafruit_io_http/adafruit_io_temperature.py b/examples/adafruit_io_http/adafruit_io_temperature.py index aaf3420..0d25f05 100644 --- a/examples/adafruit_io_http/adafruit_io_temperature.py +++ b/examples/adafruit_io_http/adafruit_io_temperature.py @@ -7,8 +7,8 @@ import adafruit_esp32spi.adafruit_esp32spi_socket as socket from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests as requests -from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError import adafruit_adt7410 +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and # "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other @@ -67,17 +67,12 @@ adt.high_resolution = True while True: - try: - temperature = adt.temperature - # set temperature value to two precision points - temperature = "%0.2f" % (temperature) + temperature = adt.temperature + # set temperature value to two precision points + temperature = "%0.2f" % (temperature) - print("Current Temperature: {0}*C".format(temperature)) - print("Sending to Adafruit IO...") - io.send_data(temperature_feed["key"], temperature) - print("Data sent!") - except (ValueError, RuntimeError) as e: - print("Failed to get data, retrying\n", e) - wifi.reset() - continue + print("Current Temperature: {0}*C".format(temperature)) + print("Sending to Adafruit IO...") + io.send_data(temperature_feed["key"], temperature) + print("Data sent!") time.sleep(0.5) diff --git a/examples/adafruit_io_http/adafruit_io_weather.py b/examples/adafruit_io_http/adafruit_io_weather.py index 42e394b..6239d24 100644 --- a/examples/adafruit_io_http/adafruit_io_weather.py +++ b/examples/adafruit_io_http/adafruit_io_weather.py @@ -1,13 +1,12 @@ # Example of using the Adafruit IO+ Weather Service # adafruit_circuitpython_adafruitio with an esp32spi_socket -import time import board import busio from digitalio import DigitalInOut import adafruit_esp32spi.adafruit_esp32spi_socket as socket from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests as requests -from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError +from adafruit_io.adafruit_io import IO_HTTP # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and # "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other From c4a32eeca9aee980b53b749f16e39a97954ffc3b Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 20 Nov 2020 13:59:26 -0500 Subject: [PATCH 029/153] add esp32spi simpletest to match cpython, native socket --- .../adafruit_io_simpletest_esp32spi.py | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py diff --git a/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py b/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py new file mode 100644 index 0000000..86f8b8c --- /dev/null +++ b/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py @@ -0,0 +1,71 @@ +# adafruit_circuitpython_adafruitio usage with an esp32spi_socket +from random import randint +import board +import busio +from digitalio import DigitalInOut +import adafruit_esp32spi.adafruit_esp32spi_socket as socket +from adafruit_esp32spi import adafruit_esp32spi +import adafruit_requests as requests +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError + +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order +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) + +print("Connecting to AP...") +while not esp.is_connected: + try: + esp.connect_AP(secrets["ssid"], secrets["password"]) + except RuntimeError as e: + print("could not connect to AP, retrying: ", e) + continue +print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) + +socket.set_interface(esp) +requests.set_socket(socket, esp) + +# Set your Adafruit IO Username and Key in secrets.py +# (visit io.adafruit.com if you need to create an account, +# or if you need your Adafruit IO key.) +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) + +try: + # Get the 'temperature' feed from Adafruit IO + temperature_feed = io.get_feed("temperature") +except AdafruitIO_RequestError: + # If no 'temperature' feed exists, create one + temperature_feed = io.create_new_feed("temperature") + +# Send random integer values to the feed +random_value = randint(0, 50) +print("Sending {0} to temperature feed...".format(random_value)) +io.send_data(temperature_feed["key"], random_value) +print("Data sent!") + +# Retrieve data value from the feed +print("Retrieving data from temperature feed...") +received_data = io.receive_data(temperature_feed["key"]) +print("Data from temperature feed: ", received_data["value"]) From 2a8edfec39d153c616e40589aa5ccf2991472a27 Mon Sep 17 00:00:00 2001 From: Doug Burke Date: Sun, 22 Nov 2020 13:06:03 -0500 Subject: [PATCH 030/153] Fix a typo in feed argument of IO_MQTT.get method To be honest I don't know if this is an actual typo, but all other accesses use `{0}/feeds/{1}` so it looks like a typo. --- adafruit_io/adafruit_io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index b645743..959b48d 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -457,7 +457,7 @@ def get(self, feed_key): io.get('temperature') """ - self._client.publish("{0}/feeds{1}/get".format(self._user, feed_key), "\0") + self._client.publish("{0}/feeds/{1}/get".format(self._user, feed_key), "\0") class IO_HTTP: From 9a2dbbdb102df04fba79246a111f88deb8a8678d Mon Sep 17 00:00:00 2001 From: dherrada Date: Mon, 11 Jan 2021 15:06:44 -0500 Subject: [PATCH 031/153] Added pre-commit and SPDX copyright Signed-off-by: dherrada --- .github/workflows/build.yml | 28 ++++++++++++++++++++++++---- .github/workflows/release.yml | 4 ++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b6977a9..59baa53 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries +# +# SPDX-License-Identifier: MIT + name: Build CI on: [pull_request, push] @@ -38,20 +42,36 @@ jobs: # (e.g. - apt-get: gettext, etc; pip: circuitpython-build-tools, requirements.txt; etc.) run: | source actions-ci/install.sh - - name: Pip install pylint, black, & Sphinx + - name: Pip install pylint, Sphinx, pre-commit run: | - pip install --force-reinstall pylint black==19.10b0 Sphinx sphinx-rtd-theme + pip install --force-reinstall pylint Sphinx sphinx-rtd-theme pre-commit - name: Library version run: git describe --dirty --always --tags - - name: Check formatting + - name: Pre-commit hooks run: | - black --check --target-version=py35 . + pre-commit run --all-files - name: PyLint run: | pylint $( find . -path './adafruit*.py' ) ([[ ! -d "examples" ]] || pylint --disable=missing-docstring,invalid-name,bad-whitespace $( find . -path "./examples/*.py" )) - name: Build assets run: circuitpython-build-bundles --filename_prefix ${{ steps.repo-name.outputs.repo-name }} --library_location . + - name: Archive bundles + uses: actions/upload-artifact@v2 + with: + name: bundles + path: ${{ github.workspace }}/bundles/ - name: Build docs working-directory: docs run: sphinx-build -E -W -b html . _build/html + - name: Check For setup.py + id: need-pypi + run: | + echo ::set-output name=setup-py::$( find . -wholename './setup.py' ) + - name: Build Python package + if: contains(steps.need-pypi.outputs.setup-py, 'setup.py') + run: | + pip install --upgrade setuptools wheel twine readme_renderer testresources + python setup.py sdist + python setup.py bdist_wheel --universal + twine check dist/* diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 18efb9c..6d0015a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries +# +# SPDX-License-Identifier: MIT + name: Release Actions on: From 27752f8fc18def58e21a804ccecd6b100091f498 Mon Sep 17 00:00:00 2001 From: dherrada Date: Mon, 11 Jan 2021 16:06:47 -0500 Subject: [PATCH 032/153] Added pre-commit-config file Signed-off-by: dherrada --- .pre-commit-config.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..aab5f1c --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: 2020 Diego Elio Pettenò +# +# SPDX-License-Identifier: Unlicense + +repos: +- repo: https://github.com/python/black + rev: stable + hooks: + - id: black +- repo: https://github.com/fsfe/reuse-tool + rev: latest + hooks: + - id: reuse +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace From 042f33571a2e29ea766a4837a926cec5e0789c86 Mon Sep 17 00:00:00 2001 From: dherrada Date: Thu, 14 Jan 2021 12:45:42 -0500 Subject: [PATCH 033/153] Ran pre-commit, added licenses --- .gitignore | 6 +- .pylintrc | 4 + .readthedocs.yml | 4 + CODE_OF_CONDUCT.md | 14 +- LICENSES/CC-BY-4.0.txt | 324 ++++++++++++++++++ LICENSES/MIT.txt | 19 + LICENSES/Unlicense.txt | 20 ++ README.rst | 2 +- README.rst.license | 3 + adafruit_io/adafruit_io.py | 23 +- adafruit_io/adafruit_io_errors.py | 23 +- docs/_static/favicon.ico.license | 3 + docs/api.rst.license | 3 + docs/conf.py | 4 + docs/examples.rst.license | 3 + docs/index.rst.license | 3 + .../adafruit_io_http/adafruit_io_analog_in.py | 3 + .../adafruit_io_digital_out.py | 3 + .../adafruit_io_http/adafruit_io_feeds.py | 3 + .../adafruit_io_http/adafruit_io_groups.py | 3 + .../adafruit_io_http/adafruit_io_metadata.py | 3 + .../adafruit_io_randomizer.py | 3 + .../adafruit_io_simpletest.py | 3 + .../adafruit_io_simpletest_cpython.py | 3 + .../adafruit_io_simpletest_esp32spi.py | 3 + .../adafruit_io_temperature.py | 3 + .../adafruit_io_http/adafruit_io_weather.py | 3 + .../adafruit_io_feed_callback.py | 3 + .../adafruit_io_mqtt/adafruit_io_groups.py | 3 + .../adafruit_io_mqtt/adafruit_io_location.py | 3 + .../adafruit_io_simpletest_cellular.py | 3 + .../adafruit_io_simpletest_eth.py | 3 + examples/adafruit_io_mqtt/adafruit_io_time.py | 3 + examples/adafruit_io_simpletest.py | 3 + requirements.txt | 4 + setup.py | 4 + 36 files changed, 474 insertions(+), 46 deletions(-) create mode 100644 LICENSES/CC-BY-4.0.txt create mode 100644 LICENSES/MIT.txt create mode 100644 LICENSES/Unlicense.txt create mode 100644 README.rst.license create mode 100644 docs/_static/favicon.ico.license create mode 100644 docs/api.rst.license create mode 100644 docs/examples.rst.license create mode 100644 docs/index.rst.license diff --git a/.gitignore b/.gitignore index c83f8b7..9647e71 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# +# SPDX-License-Identifier: Unlicense + *.mpy .idea __pycache__ @@ -8,4 +12,4 @@ bundles *.DS_Store .eggs dist -**/*.egg-info \ No newline at end of file +**/*.egg-info diff --git a/.pylintrc b/.pylintrc index d8f0ee8..5c31f66 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# +# SPDX-License-Identifier: Unlicense + [MASTER] # A comma-separated list of package or module names from where C extensions may diff --git a/.readthedocs.yml b/.readthedocs.yml index f4243ad..ffa84c4 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# +# SPDX-License-Identifier: Unlicense + python: version: 3 requirements_file: requirements.txt diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 134d510..8a55c07 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,3 +1,9 @@ + + # Adafruit Community Code of Conduct ## Our Pledge @@ -43,7 +49,7 @@ Examples of unacceptable behavior by participants include: The goal of the standards and moderation guidelines outlined here is to build and maintain a respectful community. We ask that you don’t just aim to be -"technically unimpeachable", but rather try to be your best self. +"technically unimpeachable", but rather try to be your best self. We value many things beyond technical expertise, including collaboration and supporting others within our community. Providing a positive experience for @@ -74,9 +80,9 @@ You may report in the following ways: In any situation, you may send an email to . On the Adafruit Discord, you may send an open message from any channel -to all Community Moderators by tagging @community moderators. You may -also send an open message from any channel, or a direct message to -@kattni#1507, @tannewt#4653, @Dan Halbert#1614, @cater#2442, +to all Community Moderators by tagging @community moderators. You may +also send an open message from any channel, or a direct message to +@kattni#1507, @tannewt#4653, @Dan Halbert#1614, @cater#2442, @sommersoft#0222, @Mr. Certainly#0472 or @Andon#8175. Email and direct message reports will be kept confidential. diff --git a/LICENSES/CC-BY-4.0.txt b/LICENSES/CC-BY-4.0.txt new file mode 100644 index 0000000..3f92dfc --- /dev/null +++ b/LICENSES/CC-BY-4.0.txt @@ -0,0 +1,324 @@ +Creative Commons Attribution 4.0 International Creative Commons Corporation +("Creative Commons") is not a law firm and does not provide legal services +or legal advice. Distribution of Creative Commons public licenses does not +create a lawyer-client or other relationship. Creative Commons makes its licenses +and related information available on an "as-is" basis. Creative Commons gives +no warranties regarding its licenses, any material licensed under their terms +and conditions, or any related information. Creative Commons disclaims all +liability for damages resulting from their use to the fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and conditions +that creators and other rights holders may use to share original works of +authorship and other material subject to copyright and certain other rights +specified in the public license below. The following considerations are for +informational purposes only, are not exhaustive, and do not form part of our +licenses. + +Considerations for licensors: Our public licenses are intended for use by +those authorized to give the public permission to use material in ways otherwise +restricted by copyright and certain other rights. Our licenses are irrevocable. +Licensors should read and understand the terms and conditions of the license +they choose before applying it. Licensors should also secure all rights necessary +before applying our licenses so that the public can reuse the material as +expected. Licensors should clearly mark any material not subject to the license. +This includes other CC-licensed material, or material used under an exception +or limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors + +Considerations for the public: By using one of our public licenses, a licensor +grants the public permission to use the licensed material under specified +terms and conditions. If the licensor's permission is not necessary for any +reason–for example, because of any applicable exception or limitation to copyright–then +that use is not regulated by the license. Our licenses grant only permissions +under copyright and certain other rights that a licensor has authority to +grant. Use of the licensed material may still be restricted for other reasons, +including because others have copyright or other rights in the material. A +licensor may make special requests, such as asking that all changes be marked +or described. Although not required by our licenses, you are encouraged to +respect those requests where reasonable. More considerations for the public +: wiki.creativecommons.org/Considerations_for_licensees Creative Commons Attribution +4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree to +be bound by the terms and conditions of this Creative Commons Attribution +4.0 International Public License ("Public License"). To the extent this Public +License may be interpreted as a contract, You are granted the Licensed Rights +in consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the Licensor +receives from making the Licensed Material available under these terms and +conditions. + +Section 1 – Definitions. + +a. Adapted Material means material subject to Copyright and Similar Rights +that is derived from or based upon the Licensed Material and in which the +Licensed Material is translated, altered, arranged, transformed, or otherwise +modified in a manner requiring permission under the Copyright and Similar +Rights held by the Licensor. For purposes of this Public License, where the +Licensed Material is a musical work, performance, or sound recording, Adapted +Material is always produced where the Licensed Material is synched in timed +relation with a moving image. + +b. Adapter's License means the license You apply to Your Copyright and Similar +Rights in Your contributions to Adapted Material in accordance with the terms +and conditions of this Public License. + +c. Copyright and Similar Rights means copyright and/or similar rights closely +related to copyright including, without limitation, performance, broadcast, +sound recording, and Sui Generis Database Rights, without regard to how the +rights are labeled or categorized. For purposes of this Public License, the +rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. + +d. Effective Technological Measures means those measures that, in the absence +of proper authority, may not be circumvented under laws fulfilling obligations +under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, +and/or similar international agreements. + +e. Exceptions and Limitations means fair use, fair dealing, and/or any other +exception or limitation to Copyright and Similar Rights that applies to Your +use of the Licensed Material. + +f. Licensed Material means the artistic or literary work, database, or other +material to which the Licensor applied this Public License. + +g. Licensed Rights means the rights granted to You subject to the terms and +conditions of this Public License, which are limited to all Copyright and +Similar Rights that apply to Your use of the Licensed Material and that the +Licensor has authority to license. + +h. Licensor means the individual(s) or entity(ies) granting rights under this +Public License. + +i. Share means to provide material to the public by any means or process that +requires permission under the Licensed Rights, such as reproduction, public +display, public performance, distribution, dissemination, communication, or +importation, and to make material available to the public including in ways +that members of the public may access the material from a place and at a time +individually chosen by them. + +j. Sui Generis Database Rights means rights other than copyright resulting +from Directive 96/9/EC of the European Parliament and of the Council of 11 +March 1996 on the legal protection of databases, as amended and/or succeeded, +as well as other essentially equivalent rights anywhere in the world. + +k. You means the individual or entity exercising the Licensed Rights under +this Public License. Your has a corresponding meaning. + +Section 2 – Scope. + + a. License grant. + +1. Subject to the terms and conditions of this Public License, the Licensor +hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, +irrevocable license to exercise the Licensed Rights in the Licensed Material +to: + + A. reproduce and Share the Licensed Material, in whole or in part; and + + B. produce, reproduce, and Share Adapted Material. + +2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions +and Limitations apply to Your use, this Public License does not apply, and +You do not need to comply with its terms and conditions. + + 3. Term. The term of this Public License is specified in Section 6(a). + +4. Media and formats; technical modifications allowed. The Licensor authorizes +You to exercise the Licensed Rights in all media and formats whether now known +or hereafter created, and to make technical modifications necessary to do +so. The Licensor waives and/or agrees not to assert any right or authority +to forbid You from making technical modifications necessary to exercise the +Licensed Rights, including technical modifications necessary to circumvent +Effective Technological Measures. For purposes of this Public License, simply +making modifications authorized by this Section 2(a)(4) never produces Adapted +Material. + + 5. Downstream recipients. + +A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed +Material automatically receives an offer from the Licensor to exercise the +Licensed Rights under the terms and conditions of this Public License. + +B. No downstream restrictions. You may not offer or impose any additional +or different terms or conditions on, or apply any Effective Technological +Measures to, the Licensed Material if doing so restricts exercise of the Licensed +Rights by any recipient of the Licensed Material. + +6. No endorsement. Nothing in this Public License constitutes or may be construed +as permission to assert or imply that You are, or that Your use of the Licensed +Material is, connected with, or sponsored, endorsed, or granted official status +by, the Licensor or others designated to receive attribution as provided in +Section 3(a)(1)(A)(i). + + b. Other rights. + +1. Moral rights, such as the right of integrity, are not licensed under this +Public License, nor are publicity, privacy, and/or other similar personality +rights; however, to the extent possible, the Licensor waives and/or agrees +not to assert any such rights held by the Licensor to the limited extent necessary +to allow You to exercise the Licensed Rights, but not otherwise. + +2. Patent and trademark rights are not licensed under this Public License. + +3. To the extent possible, the Licensor waives any right to collect royalties +from You for the exercise of the Licensed Rights, whether directly or through +a collecting society under any voluntary or waivable statutory or compulsory +licensing scheme. In all other cases the Licensor expressly reserves any right +to collect such royalties. + +Section 3 – License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the following +conditions. + + a. Attribution. + +1. If You Share the Licensed Material (including in modified form), You must: + +A. retain the following if it is supplied by the Licensor with the Licensed +Material: + +i. identification of the creator(s) of the Licensed Material and any others +designated to receive attribution, in any reasonable manner requested by the +Licensor (including by pseudonym if designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of warranties; + +v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; + +B. indicate if You modified the Licensed Material and retain an indication +of any previous modifications; and + +C. indicate the Licensed Material is licensed under this Public License, and +include the text of, or the URI or hyperlink to, this Public License. + +2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner +based on the medium, means, and context in which You Share the Licensed Material. +For example, it may be reasonable to satisfy the conditions by providing a +URI or hyperlink to a resource that includes the required information. + +3. If requested by the Licensor, You must remove any of the information required +by Section 3(a)(1)(A) to the extent reasonably practicable. + +4. If You Share Adapted Material You produce, the Adapter's License You apply +must not prevent recipients of the Adapted Material from complying with this +Public License. + +Section 4 – Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that apply to +Your use of the Licensed Material: + +a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, +reuse, reproduce, and Share all or a substantial portion of the contents of +the database; + +b. if You include all or a substantial portion of the database contents in +a database in which You have Sui Generis Database Rights, then the database +in which You have Sui Generis Database Rights (but not its individual contents) +is Adapted Material; and + +c. You must comply with the conditions in Section 3(a) if You Share all or +a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not replace +Your obligations under this Public License where the Licensed Rights include +other Copyright and Similar Rights. + +Section 5 – Disclaimer of Warranties and Limitation of Liability. + +a. Unless otherwise separately undertaken by the Licensor, to the extent possible, +the Licensor offers the Licensed Material as-is and as-available, and makes +no representations or warranties of any kind concerning the Licensed Material, +whether express, implied, statutory, or other. This includes, without limitation, +warranties of title, merchantability, fitness for a particular purpose, non-infringement, +absence of latent or other defects, accuracy, or the presence or absence of +errors, whether or not known or discoverable. Where disclaimers of warranties +are not allowed in full or in part, this disclaimer may not apply to You. + +b. To the extent possible, in no event will the Licensor be liable to You +on any legal theory (including, without limitation, negligence) or otherwise +for any direct, special, indirect, incidental, consequential, punitive, exemplary, +or other losses, costs, expenses, or damages arising out of this Public License +or use of the Licensed Material, even if the Licensor has been advised of +the possibility of such losses, costs, expenses, or damages. Where a limitation +of liability is not allowed in full or in part, this limitation may not apply +to You. + +c. The disclaimer of warranties and limitation of liability provided above +shall be interpreted in a manner that, to the extent possible, most closely +approximates an absolute disclaimer and waiver of all liability. + +Section 6 – Term and Termination. + +a. This Public License applies for the term of the Copyright and Similar Rights +licensed here. However, if You fail to comply with this Public License, then +Your rights under this Public License terminate automatically. + +b. Where Your right to use the Licensed Material has terminated under Section +6(a), it reinstates: + +1. automatically as of the date the violation is cured, provided it is cured +within 30 days of Your discovery of the violation; or + + 2. upon express reinstatement by the Licensor. + +c. For the avoidance of doubt, this Section 6(b) does not affect any right +the Licensor may have to seek remedies for Your violations of this Public +License. + +d. For the avoidance of doubt, the Licensor may also offer the Licensed Material +under separate terms or conditions or stop distributing the Licensed Material +at any time; however, doing so will not terminate this Public License. + + e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. + +Section 7 – Other Terms and Conditions. + +a. The Licensor shall not be bound by any additional or different terms or +conditions communicated by You unless expressly agreed. + +b. Any arrangements, understandings, or agreements regarding the Licensed +Material not stated herein are separate from and independent of the terms +and conditions of this Public License. + +Section 8 – Interpretation. + +a. For the avoidance of doubt, this Public License does not, and shall not +be interpreted to, reduce, limit, restrict, or impose conditions on any use +of the Licensed Material that could lawfully be made without permission under +this Public License. + +b. To the extent possible, if any provision of this Public License is deemed +unenforceable, it shall be automatically reformed to the minimum extent necessary +to make it enforceable. If the provision cannot be reformed, it shall be severed +from this Public License without affecting the enforceability of the remaining +terms and conditions. + +c. No term or condition of this Public License will be waived and no failure +to comply consented to unless expressly agreed to by the Licensor. + +d. Nothing in this Public License constitutes or may be interpreted as a limitation +upon, or waiver of, any privileges and immunities that apply to the Licensor +or You, including from the legal processes of any jurisdiction or authority. + +Creative Commons is not a party to its public licenses. Notwithstanding, Creative +Commons may elect to apply one of its public licenses to material it publishes +and in those instances will be considered the "Licensor." The text of the +Creative Commons public licenses is dedicated to the public domain under the +CC0 Public Domain Dedication. Except for the limited purpose of indicating +that material is shared under a Creative Commons public license or as otherwise +permitted by the Creative Commons policies published at creativecommons.org/policies, +Creative Commons does not authorize the use of the trademark "Creative Commons" +or any other trademark or logo of Creative Commons without its prior written +consent including, without limitation, in connection with any unauthorized +modifications to any of its public licenses or any other arrangements, understandings, +or agreements concerning use of licensed material. For the avoidance of doubt, +this paragraph does not form part of the public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt new file mode 100644 index 0000000..204b93d --- /dev/null +++ b/LICENSES/MIT.txt @@ -0,0 +1,19 @@ +MIT License Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/LICENSES/Unlicense.txt b/LICENSES/Unlicense.txt new file mode 100644 index 0000000..24a8f90 --- /dev/null +++ b/LICENSES/Unlicense.txt @@ -0,0 +1,20 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or distribute +this software, either in source code form or as a compiled binary, for any +purpose, commercial or non-commercial, and by any means. + +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and +to the detriment of our heirs and successors. We intend this dedication to +be an overt act of relinquishment in perpetuity of all present and future +rights to this software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, +please refer to diff --git a/README.rst b/README.rst index 116f66e..f9b41e0 100644 --- a/README.rst +++ b/README.rst @@ -51,7 +51,7 @@ To install in a virtual environment in your current project: python3 -m venv .env source .env/bin/activate pip3 install adafruit-circuitpython-adafruitio - + Usage Example ============= diff --git a/README.rst.license b/README.rst.license new file mode 100644 index 0000000..11cd75d --- /dev/null +++ b/README.rst.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries + +SPDX-License-Identifier: MIT diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 959b48d..50ba54e 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -1,24 +1,7 @@ -# The MIT License (MIT) +# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries # -# Copyright (c) 2019 Brent Rubell for Adafruit Industries -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# SPDX-License-Identifier: MIT + """ `adafruit_io` ================================================================================ diff --git a/adafruit_io/adafruit_io_errors.py b/adafruit_io/adafruit_io_errors.py index 4043068..c35c836 100755 --- a/adafruit_io/adafruit_io_errors.py +++ b/adafruit_io/adafruit_io_errors.py @@ -1,24 +1,7 @@ -# The MIT License (MIT) +# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries # -# Copyright (c) 2019 Brent Rubell for Adafruit -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# SPDX-License-Identifier: MIT + """ `adafruit_io_errors.py` ====================================================== diff --git a/docs/_static/favicon.ico.license b/docs/_static/favicon.ico.license new file mode 100644 index 0000000..86a3fbf --- /dev/null +++ b/docs/_static/favicon.ico.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2018 Phillip Torrone for Adafruit Industries + +SPDX-License-Identifier: CC-BY-4.0 diff --git a/docs/api.rst.license b/docs/api.rst.license new file mode 100644 index 0000000..9aae48d --- /dev/null +++ b/docs/api.rst.license @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2020 ladyada for Adafruit Industries +# +# SPDX-License-Identifier: MIT diff --git a/docs/conf.py b/docs/conf.py index 5e840c8..dd4cec9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,9 @@ # -*- coding: utf-8 -*- +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import os import sys diff --git a/docs/examples.rst.license b/docs/examples.rst.license new file mode 100644 index 0000000..9aae48d --- /dev/null +++ b/docs/examples.rst.license @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2020 ladyada for Adafruit Industries +# +# SPDX-License-Identifier: MIT diff --git a/docs/index.rst.license b/docs/index.rst.license new file mode 100644 index 0000000..9aae48d --- /dev/null +++ b/docs/index.rst.license @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2020 ladyada for Adafruit Industries +# +# SPDX-License-Identifier: MIT diff --git a/examples/adafruit_io_http/adafruit_io_analog_in.py b/examples/adafruit_io_http/adafruit_io_analog_in.py index 6acdbc3..7aafb8b 100644 --- a/examples/adafruit_io_http/adafruit_io_analog_in.py +++ b/examples/adafruit_io_http/adafruit_io_analog_in.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Example of publishing the value of an ADC to Adafruit IO # adafruit_circuitpython_adafruitio with an esp32spi_socket import time diff --git a/examples/adafruit_io_http/adafruit_io_digital_out.py b/examples/adafruit_io_http/adafruit_io_digital_out.py index 58418e9..c8b1d82 100644 --- a/examples/adafruit_io_http/adafruit_io_digital_out.py +++ b/examples/adafruit_io_http/adafruit_io_digital_out.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Turn on and off a LED from your Adafruit IO Dashboard. # adafruit_circuitpython_adafruitio with an esp32spi_socket import time diff --git a/examples/adafruit_io_http/adafruit_io_feeds.py b/examples/adafruit_io_http/adafruit_io_feeds.py index d70819e..160a540 100644 --- a/examples/adafruit_io_http/adafruit_io_feeds.py +++ b/examples/adafruit_io_http/adafruit_io_feeds.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Adafruit IO HTTP API - Feed Interactions # Documentation: https://io.adafruit.com/api/docs/#feeds # adafruit_circuitpython_adafruitio with an esp32spi_socket diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index e894dff..daefd1e 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Adafruit IO HTTP API - Group Interactions # Documentation: https://io.adafruit.com/api/docs/#groups # adafruit_circuitpython_adafruitio with an esp32spi_socket diff --git a/examples/adafruit_io_http/adafruit_io_metadata.py b/examples/adafruit_io_http/adafruit_io_metadata.py index 00aa3bc..7bfb933 100644 --- a/examples/adafruit_io_http/adafruit_io_metadata.py +++ b/examples/adafruit_io_http/adafruit_io_metadata.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Adafruit IO HTTP API - Sending values with optional metadata # adafruit_circuitpython_adafruitio with an esp32spi_socket import board diff --git a/examples/adafruit_io_http/adafruit_io_randomizer.py b/examples/adafruit_io_http/adafruit_io_randomizer.py index 96e4039..d68f2e5 100644 --- a/examples/adafruit_io_http/adafruit_io_randomizer.py +++ b/examples/adafruit_io_http/adafruit_io_randomizer.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Example for using Adafruit IO's random data (randomizer) service # adafruit_circuitpython_adafruitio with an esp32spi_socket import time diff --git a/examples/adafruit_io_http/adafruit_io_simpletest.py b/examples/adafruit_io_http/adafruit_io_simpletest.py index 26749d1..836e0be 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # adafruit_circuitpython_adafruitio usage with native wifi networking import ssl from random import randint diff --git a/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py b/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py index e2cc823..52f5031 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # adafruit_circuitpython_adafruitio usage with a CPython socket import socket import ssl diff --git a/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py b/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py index 86f8b8c..fb80f1a 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # adafruit_circuitpython_adafruitio usage with an esp32spi_socket from random import randint import board diff --git a/examples/adafruit_io_http/adafruit_io_temperature.py b/examples/adafruit_io_http/adafruit_io_temperature.py index 0d25f05..b779a50 100644 --- a/examples/adafruit_io_http/adafruit_io_temperature.py +++ b/examples/adafruit_io_http/adafruit_io_temperature.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Example of sending ADT7410 sensor temperature values to IO # adafruit_circuitpython_adafruitio with an esp32spi_socket import time diff --git a/examples/adafruit_io_http/adafruit_io_weather.py b/examples/adafruit_io_http/adafruit_io_weather.py index 6239d24..e65c654 100644 --- a/examples/adafruit_io_http/adafruit_io_weather.py +++ b/examples/adafruit_io_http/adafruit_io_weather.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Example of using the Adafruit IO+ Weather Service # adafruit_circuitpython_adafruitio with an esp32spi_socket import board diff --git a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py index 762191e..8bc36a7 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py +++ b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + import time import board diff --git a/examples/adafruit_io_mqtt/adafruit_io_groups.py b/examples/adafruit_io_mqtt/adafruit_io_groups.py index 1d45f1a..5ed80b7 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_groups.py +++ b/examples/adafruit_io_mqtt/adafruit_io_groups.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Subscribing to an Adafruit IO Group # and Publishing to the feeds in the group import time diff --git a/examples/adafruit_io_mqtt/adafruit_io_location.py b/examples/adafruit_io_mqtt/adafruit_io_location.py index 953a396..0890fe0 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_location.py +++ b/examples/adafruit_io_mqtt/adafruit_io_location.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Example of tagging data with location values # and sending it to an Adafruit IO feed. import time diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py index b0f038b..d710a84 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Example of using the Adafruit IO CircuitPython MQTT client # to subscribe to an Adafruit IO feed and publish random data # to be received by the feed. diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index 567c7d8..592adcb 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Example of using the Adafruit IO CircuitPython MQTT client # to subscribe to an Adafruit IO feed and publish random data # to be received by the feed. diff --git a/examples/adafruit_io_mqtt/adafruit_io_time.py b/examples/adafruit_io_mqtt/adafruit_io_time.py index ee4fadd..bc5ad09 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_time.py +++ b/examples/adafruit_io_mqtt/adafruit_io_time.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Adafruit IO provides some built-in MQTT topics # for obtaining the current server time, if you don't have # access to a RTC module. diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index ea011a7..a880a6d 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT + # Example of using the Adafruit IO CircuitPython MQTT client # to subscribe to an Adafruit IO feed and publish random data # to be received by the feed. diff --git a/requirements.txt b/requirements.txt index 377afe7..f772f7b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,6 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# +# SPDX-License-Identifier: Unlicense + Adafruit-Blinka Adafruit_CircuitPython_ESP32SPI diff --git a/setup.py b/setup.py index e60db09..d3563e3 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """A setuptools based setup module. See: From 9baaba58684a96309fd80a71d515692a47472aed Mon Sep 17 00:00:00 2001 From: dherrada Date: Fri, 15 Jan 2021 12:40:18 -0500 Subject: [PATCH 034/153] Corrected licenses --- .../adafruit_io_mqtt/adafruit_io_simpletest_cellular.py | 6 ++---- examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py | 7 ++----- examples/adafruit_io_simpletest.py | 7 ++----- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py index d710a84..f54c842 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py @@ -1,12 +1,10 @@ -# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-FileCopyrightText: Tony DiCola for Adafruit Industries +# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries # SPDX-License-Identifier: MIT # Example of using the Adafruit IO CircuitPython MQTT client # to subscribe to an Adafruit IO feed and publish random data # to be received by the feed. -# -# Example by Tony DiCola for Adafruit Industries -# Modified by Brent Rubell for Adafruit Industries, 2019 import time from random import randint diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index 592adcb..b1dcb33 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -1,13 +1,10 @@ -# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-FileCopyrightText: Tony DiCola for Adafruit Industries +# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries # SPDX-License-Identifier: MIT # Example of using the Adafruit IO CircuitPython MQTT client # to subscribe to an Adafruit IO feed and publish random data # to be received by the feed. -# -# Example by Tony DiCola for Adafruit Industries -# Modified by Brent Rubell for Adafruit Industries, 2019 -import time from random import randint import board diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index a880a6d..472463c 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -1,13 +1,10 @@ -# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-FileCopyrightText: Tony DiCola for Adafruit Industries +# SPDX-FileCopyrightText: 2019 Adafruit Industries for Adafruit Industries # SPDX-License-Identifier: MIT # Example of using the Adafruit IO CircuitPython MQTT client # to subscribe to an Adafruit IO feed and publish random data # to be received by the feed. -# -# Example by Tony DiCola for Adafruit Industries -# Modified by Brent Rubell for Adafruit Industries, 2019 -import time from random import randint From 60ec4d96a888f157bd0a88cf113ed71f8d8b087c Mon Sep 17 00:00:00 2001 From: dherrada Date: Fri, 15 Jan 2021 12:47:28 -0500 Subject: [PATCH 035/153] Fixed time imports that were accidentally removed --- examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py | 1 + examples/adafruit_io_simpletest.py | 1 + 2 files changed, 2 insertions(+) diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index b1dcb33..653fa79 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -5,6 +5,7 @@ # Example of using the Adafruit IO CircuitPython MQTT client # to subscribe to an Adafruit IO feed and publish random data # to be received by the feed. +import time from random import randint import board diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index 472463c..d73fe34 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -5,6 +5,7 @@ # Example of using the Adafruit IO CircuitPython MQTT client # to subscribe to an Adafruit IO feed and publish random data # to be received by the feed. +import time from random import randint From 4c17dec9243f91010f240b7a0bd57ecdebba85bd Mon Sep 17 00:00:00 2001 From: Rodrigo Argumedo <7613139+rodrigoargumedo@users.noreply.github.com> Date: Mon, 25 Jan 2021 13:13:49 -0600 Subject: [PATCH 036/153] Update broken link in index This link should redirect to the correct link location. --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index cac5a94..50dc1e3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -30,7 +30,7 @@ Table of Contents .. toctree:: :caption: Other Links - Download + Download CircuitPython Reference Documentation CircuitPython Support Forum Discord Chat From 389191827ceb4f7803401d6e78330209ef38904e Mon Sep 17 00:00:00 2001 From: Rodrigo Argumedo <7613139+rodrigoargumedo@users.noreply.github.com> Date: Mon, 25 Jan 2021 14:10:53 -0600 Subject: [PATCH 037/153] Append /latest into index --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 50dc1e3..fd9f01d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -30,7 +30,7 @@ Table of Contents .. toctree:: :caption: Other Links - Download + Download CircuitPython Reference Documentation CircuitPython Support Forum Discord Chat From f35e2d0fe2cfbd091fee2e2470399d186f1a99e9 Mon Sep 17 00:00:00 2001 From: askpatricw <4002194+askpatrickw@users.noreply.github.com> Date: Tue, 26 Jan 2021 16:19:44 -0800 Subject: [PATCH 038/153] fix URL typos --- README.rst | 2 +- adafruit_io/adafruit_io.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index f9b41e0..446435b 100644 --- a/README.rst +++ b/README.rst @@ -63,7 +63,7 @@ Contributing ============ Contributions are welcome! Please read our `Code of Conduct -`_ +`_ before contributing to help this project stay welcoming. Documentation diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 50ba54e..56f9d7d 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -28,7 +28,7 @@ ) __version__ = "0.0.0-auto.0" -__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Adafruit_IO.git" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_AdafruitIO.git" CLIENT_HEADERS = {"User-Agent": "AIO-CircuitPython/{0}".format(__version__)} From 024192a080c0228e63e65f192c430678a29dec79 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 29 Jan 2021 11:30:33 -0500 Subject: [PATCH 039/153] use small feed names, tested --- adafruit_io/adafruit_io.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 56f9d7d..5d6c6a0 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -202,7 +202,7 @@ def add_feed_callback(self, feed_key, callback_method): """ self._client.add_topic_callback( - "{0}/feeds/{1}".format(self._user, feed_key), callback_method + "{0}/f/{1}".format(self._user, feed_key), callback_method ) def remove_feed_callback(self, feed_key): @@ -214,7 +214,7 @@ def remove_feed_callback(self, feed_key): :param str feed_key: Adafruit IO feed key. """ - self._client.remove_topic_callback("{0}/feeds/{1}".format(self._user, feed_key)) + self._client.remove_topic_callback("{0}/f/{1}".format(self._user, feed_key)) def loop(self): """Manually process messages from Adafruit IO. @@ -251,11 +251,11 @@ def subscribe(self, feed_key=None, group_key=None, shared_user=None): client.subscribe([('temperature'), ('humidity')]) """ if shared_user is not None and feed_key is not None: - self._client.subscribe("{0}/feeds/{1}".format(shared_user, feed_key)) + self._client.subscribe("{0}/f/{1}".format(shared_user, feed_key)) elif group_key is not None: - self._client.subscribe("{0}/groups/{1}".format(self._user, group_key)) + self._client.subscribe("{0}/g/{1}".format(self._user, group_key)) elif feed_key is not None: - self._client.subscribe("{0}/feeds/{1}".format(self._user, feed_key)) + self._client.subscribe("{0}/f/{1}".format(self._user, feed_key)) else: raise AdafruitIO_MQTTError("Must provide a feed_key or group_key.") @@ -332,11 +332,11 @@ def unsubscribe(self, feed_key=None, group_key=None, shared_user=None): """ if shared_user is not None and feed_key is not None: - self._client.unsubscribe("{0}/feeds/{1}".format(shared_user, feed_key)) + self._client.unsubscribe("{0}/f/{1}".format(shared_user, feed_key)) elif group_key is not None: - self._client.unsubscribe("{0}/groups/{1}".format(self._user, feed_key)) + self._client.unsubscribe("{0}/g/{1}".format(self._user, feed_key)) elif feed_key is not None: - self._client.unsubscribe("{0}/feeds/{1}".format(self._user, feed_key)) + self._client.unsubscribe("{0}/f/{1}".format(self._user, feed_key)) else: raise AdafruitIO_MQTTError("Must provide a feed_key or group_key.") @@ -416,18 +416,18 @@ def publish(self, feed_key, data, metadata=None, shared_user=None, is_group=Fals """ if is_group: - self._client.publish("{0}/groups/{1}".format(self._user, feed_key), data) + self._client.publish("{0}/g/{1}".format(self._user, feed_key), data) if shared_user is not None: - self._client.publish("{0}/feeds/{1}".format(shared_user, feed_key), data) + self._client.publish("{0}/f/{1}".format(shared_user, feed_key), data) if metadata is not None: if isinstance(data, int or float): data = str(data) csv_string = data + "," + metadata self._client.publish( - "{0}/feeds/{1}/csv".format(self._user, feed_key), csv_string + "{0}/f/{1}/csv".format(self._user, feed_key), csv_string ) else: - self._client.publish("{0}/feeds/{1}".format(self._user, feed_key), data) + self._client.publish("{0}/f/{1}".format(self._user, feed_key), data) def get(self, feed_key): """Calling this method will make Adafruit IO publish the most recent @@ -440,7 +440,7 @@ def get(self, feed_key): io.get('temperature') """ - self._client.publish("{0}/feeds/{1}/get".format(self._user, feed_key), "\0") + self._client.publish("{0}/f/{1}/get".format(self._user, feed_key), "\0") class IO_HTTP: From 9cae89da4c187b21c3656f6784a5279352678685 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 29 Jan 2021 11:41:10 -0500 Subject: [PATCH 040/153] add create_feed_in_group --- adafruit_io/adafruit_io.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 56f9d7d..f25a0dd 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -589,16 +589,6 @@ def delete_data(self, feed_key, data_id): return self._delete(path) # Groups - def add_feed_to_group(self, group_key, feed_key): - """ - Adds an existing feed to a group - :param str group_key: Group - :param str feed_key: Feed to add to the group - """ - path = self._compose_path("groups/{0}/add".format(group_key)) - payload = {"feed_key": feed_key} - return self._post(path, payload) - def create_new_group(self, group_key, group_description): """ Creates a new Adafruit IO Group. @@ -625,6 +615,26 @@ def get_group(self, group_key): path = self._compose_path("groups/{0}".format(group_key)) return self._get(path) + def create_feed_in_group(self, group_key, feed_name): + """Creates a new feed in an existing group. + :param str group_key: Group name. + :param str feed_name: Name of new feed. + + """ + path = self._compose_path("groups/{0}/feeds".format(group_key)) + payload = {"feed": {"name": feed_name}} + return self._post(path, payload) + + def add_feed_to_group(self, group_key, feed_key): + """ + Adds an existing feed to a group + :param str group_key: Group + :param str feed_key: Feed to add to the group + """ + path = self._compose_path("groups/{0}/add".format(group_key)) + payload = {"feed_key": feed_key} + return self._post(path, payload) + # Feeds def get_feed(self, feed_key, detailed=False): """ From 9d5a4a6f87030dae557b87adfe35024eb5f910b2 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 3 Feb 2021 15:32:56 -0500 Subject: [PATCH 041/153] updated library, added simpletest for s2 --- README.rst | 1 + adafruit_io/adafruit_io.py | 19 +--- .../adafruit_io_simpletest_esp32s2.py | 107 ++++++++++++++++++ 3 files changed, 110 insertions(+), 17 deletions(-) create mode 100644 examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py diff --git a/README.rst b/README.rst index 446435b..e714edf 100644 --- a/README.rst +++ b/README.rst @@ -22,6 +22,7 @@ Dependencies This driver depends on: * `Adafruit CircuitPython `_ +* `Adafruit CircuitPython MiniMQTT `_ Please ensure that all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 5120c60..cfc62aa 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -51,9 +51,9 @@ def __init__(self, mqtt_client): raise TypeError( "This class requires a MiniMQTT client object, please create one." ) - # MiniMQTT's username kwarg is optional, IO requires a username + # Adafruit IO MQTT API MUST require a username try: - self._user = self._client.user + self._user = self._client._username except Exception as err: raise TypeError( "Adafruit IO requires a username, please set one in MiniMQTT" @@ -70,11 +70,6 @@ def __init__(self, mqtt_client): self._client.on_message = self._on_message_mqtt self._client.on_subscribe = self._on_subscribe_mqtt self._client.on_unsubscribe = self._on_unsubscribe_mqtt - self._logger = False - # Write to the MiniMQTT logger, if avaliable. - if self._client.logger is not None: - self._logger = True - self._client.set_logger_level("DEBUG") self._connected = False def __enter__(self): @@ -112,8 +107,6 @@ 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.""" - if self._logger: - self._client._logger.debug("Client called on_connect.") if return_code == 0: self._connected = True else: @@ -125,8 +118,6 @@ 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.""" - if self._logger: - self._client._logger.debug("Client called on_disconnect") self._connected = False # Call the user-defined on_disconnect callblack if defined if self.on_disconnect is not None: @@ -140,8 +131,6 @@ def _on_message_mqtt(self, client, topic, payload): :param str topic: MQTT topic response from Adafruit IO. :param str payload: MQTT payload data response from Adafruit IO. """ - if self._logger: - self._client._logger.debug("Client called on_message.") if self.on_message is not None: # Parse the MQTT topic string topic_name = topic.split("/") @@ -177,16 +166,12 @@ 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.""" - 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.""" - 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) diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py new file mode 100644 index 0000000..ef9e78d --- /dev/null +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py @@ -0,0 +1,107 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-License-Identifier: MIT +import time +from random import randint + +import ssl +import socketpool +import wifi +import adafruit_minimqtt.adafruit_minimqtt as MQTT +from adafruit_io.adafruit_io import IO_MQTT + +### WiFi ### + +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order +try: + from secrets import secrets +except ImportError: + print("WiFi secrets are kept in secrets.py, please add them there!") + raise + +# Set your Adafruit IO Username and Key in secrets.py +# (visit io.adafruit.com if you need to create an account, +# or if you need your Adafruit IO key.) +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + +print("Connecting to %s" % secrets["ssid"]) +wifi.radio.connect(secrets["ssid"], secrets["password"]) +print("Connected to %s!" % secrets["ssid"]) + +# 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...") + # Subscribe to changes on a feed named DemoFeed. + client.subscribe("DemoFeed") + + +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)) + + +# Create a socket pool +pool = socketpool.SocketPool(wifi.radio) + +# Initialize a new MQTT Client object +mqtt_client = MQTT.MQTT( + broker="io.adafruit.com", + username=secrets["aio_username"], + password=secrets["aio_key"], + socket_pool=pool, + ssl_context=ssl.create_default_context(), +) + +# 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() + +# Below is an example of manually publishing a new value to Adafruit IO. +last = 0 +print("Publishing a new message every 10 seconds...") +while True: + # Explicitly pump the message loop. + io.loop() + # Send a new message every 10 seconds. + if (time.monotonic() - last) >= 5: + value = randint(0, 100) + print("Publishing {0} to DemoFeed.".format(value)) + io.publish("DemoFeed", value) + last = time.monotonic() From dac995db724c29a004aee77448a7a92f63144364 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 3 Feb 2021 15:37:15 -0500 Subject: [PATCH 042/153] remove minimqtt dep, its not dep. --- README.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/README.rst b/README.rst index e714edf..446435b 100644 --- a/README.rst +++ b/README.rst @@ -22,7 +22,6 @@ Dependencies This driver depends on: * `Adafruit CircuitPython `_ -* `Adafruit CircuitPython MiniMQTT `_ Please ensure that all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading From b95428e92404b139205b965b638e6a85e12b3ec5 Mon Sep 17 00:00:00 2001 From: dherrada Date: Wed, 3 Feb 2021 16:38:51 -0500 Subject: [PATCH 043/153] Hardcoded Black and REUSE versions Signed-off-by: dherrada --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index aab5f1c..07f886c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,11 +4,11 @@ repos: - repo: https://github.com/python/black - rev: stable + rev: 20.8b1 hooks: - id: black - repo: https://github.com/fsfe/reuse-tool - rev: latest + rev: v0.12.1 hooks: - id: reuse - repo: https://github.com/pre-commit/pre-commit-hooks From f74d0cd57423ec87bf5e626568874bcbdfc18394 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 25 Feb 2021 15:30:20 -0500 Subject: [PATCH 044/153] refactor create_data --- adafruit_io/adafruit_io.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index cfc62aa..161120d 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -457,16 +457,16 @@ def _create_headers(io_headers): @staticmethod def _create_data(data, metadata): - """Creates JSON data payload""" - if metadata is not None: - return { - "value": data, - "lat": metadata["lat"], - "lon": metadata["lon"], - "ele": metadata["ele"], - "created_at": metadata["created_at"], - } - return {"value": data} + """Returns a data payload as expected by the Adafruit IO HTTP API + :param data: Payload value. + :param dict metadata: Payload metadata. + + """ + payload = {"value": data} + if metadata: # metadata is expected as a dict, append key/vals + for k, val in metadata.items(): + payload[k] = val + return payload @staticmethod def _handle_error(response): From 49e54bf82f765d55ddaf5c6397981f919c0c9461 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 25 Feb 2021 15:46:06 -0500 Subject: [PATCH 045/153] eval time sub. differently for pylint --- adafruit_io/adafruit_io.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 161120d..bb8d1f4 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -282,12 +282,10 @@ def subscribe_to_time(self, time_type): Information about these topics can be found on the Adafruit IO MQTT API Docs.: https://io.adafruit.com/api/docs/mqtt.html#time-topics """ - if "seconds" or "millis" or "hours" in time_type: - self._client.subscribe("time/" + time_type) - elif time_type == "iso": + if time_type == "iso": self._client.subscribe("time/ISO-8601") else: - raise TypeError("Invalid time feed type specified") + self._client.subscribe("time/" + time_type) def unsubscribe(self, feed_key=None, group_key=None, shared_user=None): """Unsubscribes from an Adafruit IO feed or group. From 0e30d791a2a2232849c946ebb50530aff14a7bfb Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 25 Feb 2021 16:01:23 -0500 Subject: [PATCH 046/153] patch in new precommit, workflow build from cookiecutter --- .github/workflows/build.yml | 9 +++++---- .pre-commit-config.yaml | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 59baa53..fd99fee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,10 +50,6 @@ jobs: - name: Pre-commit hooks run: | pre-commit run --all-files - - name: PyLint - run: | - pylint $( find . -path './adafruit*.py' ) - ([[ ! -d "examples" ]] || pylint --disable=missing-docstring,invalid-name,bad-whitespace $( find . -path "./examples/*.py" )) - name: Build assets run: circuitpython-build-bundles --filename_prefix ${{ steps.repo-name.outputs.repo-name }} --library_location . - name: Archive bundles @@ -61,7 +57,12 @@ jobs: with: name: bundles path: ${{ github.workspace }}/bundles/ + - name: Check For docs folder + id: need-docs + run: | + echo ::set-output name=docs::$( find . -wholename './docs' ) - name: Build docs + if: contains(steps.need-docs.outputs.docs, 'docs') working-directory: docs run: sphinx-build -E -W -b html . _build/html - name: Check For setup.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 07f886c..354c761 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,3 +17,18 @@ repos: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace +- repo: https://github.com/pycqa/pylint + rev: pylint-2.7.1 + hooks: + - id: pylint + name: pylint (library code) + types: [python] + exclude: "^(docs/|examples/|setup.py$)" +- repo: local + hooks: + - id: pylint_examples + name: pylint (examples code) + description: Run pylint rules on "examples/*.py" files + entry: /usr/bin/env bash -c + args: ['([[ ! -d "examples" ]] || for example in $(find . -path "./examples/*.py"); do pylint --disable=missing-docstring,invalid-name $example; done)'] + language: system From 17f84b12612141ff042993688ee4d584a5944c76 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Wed, 3 Mar 2021 07:33:00 -0600 Subject: [PATCH 047/153] ignore imports in pylintrc --- .pylintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pylintrc b/.pylintrc index 5c31f66..9ed669e 100644 --- a/.pylintrc +++ b/.pylintrc @@ -250,7 +250,7 @@ ignore-comments=yes ignore-docstrings=yes # Ignore imports when computing similarities. -ignore-imports=no +ignore-imports=yes # Minimum lines number of a similarity. min-similarity-lines=4 From 60e8dfb572c8e0fe07e0fdcfcdecbbff019e3099 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 5 Mar 2021 15:29:19 -0500 Subject: [PATCH 048/153] add rp2040 publish/sub example for guide --- .../adafruit_io_pubsub_rp2040.py | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py diff --git a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py new file mode 100644 index 0000000..fb94188 --- /dev/null +++ b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py @@ -0,0 +1,121 @@ +# SPDX-FileCopyrightText: Brent Rubell for Adafruit Industries +# SPDX-License-Identifier: MIT + +import time +from microcontroller import cpu +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 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 + +# Raspberry Pi RP2040 +esp32_cs = DigitalInOut(board.GP13) +esp32_ready = DigitalInOut(board.GP14) +esp32_reset = DigitalInOut(board.GP15) + +spi = busio.SPI(board.GP10, board.GP11, board.GP12) +esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) + +wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets) + +# Configure the RP2040 Pico LED Pin as an output +led_pin = DigitalInOut(board.LED) +led_pin.switch_to_output() + +# 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. + print("Connected to Adafruit IO! ") + + +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)) + + +# pylint: disable=unused-argument +def disconnected(client): + # Disconnected function will be called when the client disconnects. + print("Disconnected from Adafruit IO!") + + +def on_led_msg(client, topic, message): + # Method called whenever user/feeds/led has a new value + print("New message on topic {0}: {1} ".format(topic, message)) + if message == "ON": + led_pin.value = True + elif message == "OFF": + led_pin.value = False + else: + print("Unexpected message on LED feed.") + + +# 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 + +# Set up a callback for the led feed +io.add_feed_callback("led", on_led_msg) + +# Connect to Adafruit IO +print("Connecting to Adafruit IO...") +io.connect() + +# Subscribe to all messages on the led feed +io.subscribe("led") + +refresh_time = 0.0 +while True: + # Poll for incoming messages + try: + io.loop() + except (ValueError, RuntimeError) as e: + print("Failed to get data, retrying\n", e) + wifi.reset() + io.reconnect() + continue + # Send a new temperature reading to IO every 30 seconds + if (time.monotonic() - refresh_time) > 30: + # take the cpu's temperature + cpu_temp = cpu.temperature + # truncate to two decimal points + cpu_temp = str(cpu_temp)[:5] + print("CPU temperature is %s degrees C" % cpu_temp) + # publish it to io + print("Publishing %s to temperature feed..." % cpu_temp) + io.publish("temperature", cpu_temp) + print("Published!") + refresh_time = time.monotonic() From 2fb8eaec0662ecc161e7f701dce6194a7266c133 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 5 Mar 2021 15:36:30 -0500 Subject: [PATCH 049/153] change var name --- examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py index fb94188..a5ce569 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py +++ b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py @@ -97,7 +97,7 @@ def on_led_msg(client, topic, message): # Subscribe to all messages on the led feed io.subscribe("led") -refresh_time = 0.0 +prv_refresh_time = 0.0 while True: # Poll for incoming messages try: @@ -108,7 +108,7 @@ def on_led_msg(client, topic, message): io.reconnect() continue # Send a new temperature reading to IO every 30 seconds - if (time.monotonic() - refresh_time) > 30: + if (time.monotonic() - prv_refresh_time) > 30: # take the cpu's temperature cpu_temp = cpu.temperature # truncate to two decimal points @@ -118,4 +118,4 @@ def on_led_msg(client, topic, message): print("Publishing %s to temperature feed..." % cpu_temp) io.publish("temperature", cpu_temp) print("Published!") - refresh_time = time.monotonic() + prv_refresh_time = time.monotonic() From 1c34a8fc74fc7624065460358cdd898c0f698f21 Mon Sep 17 00:00:00 2001 From: dherrada Date: Fri, 19 Mar 2021 13:48:22 -0400 Subject: [PATCH 050/153] "Increase duplicate code check threshold " --- .pylintrc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.pylintrc b/.pylintrc index 9ed669e..0238b90 100644 --- a/.pylintrc +++ b/.pylintrc @@ -22,8 +22,7 @@ ignore-patterns= #init-hook= # Use multiple processes to speed up Pylint. -# jobs=1 -jobs=2 +jobs=1 # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. @@ -253,7 +252,7 @@ ignore-docstrings=yes ignore-imports=yes # Minimum lines number of a similarity. -min-similarity-lines=4 +min-similarity-lines=12 [BASIC] From 1e3d458ccbe86dade80ce3005a41ffed5d50b864 Mon Sep 17 00:00:00 2001 From: brentru Date: Fri, 26 Mar 2021 15:36:04 -0400 Subject: [PATCH 051/153] validate feed keys used, test --- adafruit_io/adafruit_io.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index bb8d1f4..5443727 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -20,6 +20,7 @@ """ import time import json +import re from adafruit_io.adafruit_io_errors import ( AdafruitIO_RequestError, @@ -33,6 +34,18 @@ CLIENT_HEADERS = {"User-Agent": "AIO-CircuitPython/{0}".format(__version__)} +def validate_feed_key(feed_key): + """Validates a provided feed key against Adafruit IO's system rules. + https://learn.adafruit.com/naming-things-in-adafruit-io/the-two-feed-identifiers + """ + if len(feed_key) > 128: # validate feed key length + raise ValueError("Feed key must be less than 128 characters.") + if not bool(re.match("^[a-z0-9-]+$", feed_key)): # validate key naming scheme + raise TypeError( + "Feed key must contain lower case English letters, numbers, and dash." + ) + + class IO_MQTT: """ Client for interacting with Adafruit IO MQTT API. @@ -186,6 +199,7 @@ def add_feed_callback(self, feed_key, callback_method): :param str callback_method: Name of callback method. """ + validate_feed_key(feed_key) self._client.add_topic_callback( "{0}/f/{1}".format(self._user, feed_key), callback_method ) @@ -199,6 +213,7 @@ def remove_feed_callback(self, feed_key): :param str feed_key: Adafruit IO feed key. """ + validate_feed_key(feed_key) self._client.remove_topic_callback("{0}/f/{1}".format(self._user, feed_key)) def loop(self): @@ -235,6 +250,7 @@ def subscribe(self, feed_key=None, group_key=None, shared_user=None): client.subscribe([('temperature'), ('humidity')]) """ + validate_feed_key(feed_key) if shared_user is not None and feed_key is not None: self._client.subscribe("{0}/f/{1}".format(shared_user, feed_key)) elif group_key is not None: @@ -314,6 +330,7 @@ def unsubscribe(self, feed_key=None, group_key=None, shared_user=None): client.unsubscribe('temperature', shared_user='adabot') """ + validate_feed_key(feed_key) if shared_user is not None and feed_key is not None: self._client.unsubscribe("{0}/f/{1}".format(shared_user, feed_key)) elif group_key is not None: @@ -398,6 +415,7 @@ def publish(self, feed_key, data, metadata=None, shared_user=None, is_group=Fals io.publish("location-feed", data, metadata) """ + validate_feed_key(feed_key) if is_group: self._client.publish("{0}/g/{1}".format(self._user, feed_key), data) if shared_user is not None: @@ -423,6 +441,7 @@ def get(self, feed_key): io.get('temperature') """ + validate_feed_key(feed_key) self._client.publish("{0}/f/{1}/get".format(self._user, feed_key), "\0") @@ -534,6 +553,7 @@ def send_data(self, feed_key, data, metadata=None, precision=None): :param dict metadata: Optional metadata associated with the data :param int precision: Optional amount of precision points to send with floating point data """ + validate_feed_key(feed_key) path = self._compose_path("feeds/{0}/data".format(feed_key)) if precision: try: @@ -551,6 +571,7 @@ def receive_all_data(self, feed_key): returned in reverse order. :param str feed_key: Adafruit IO feed key """ + validate_feed_key(feed_key) path = self._compose_path("feeds/{0}/data".format(feed_key)) return self._get(path) @@ -559,6 +580,7 @@ def receive_data(self, feed_key): Return the most recent value for the specified feed. :param string feed_key: Adafruit IO feed key """ + validate_feed_key(feed_key) path = self._compose_path("feeds/{0}/data/last".format(feed_key)) return self._get(path) @@ -568,6 +590,7 @@ def delete_data(self, feed_key, data_id): :param string feed: Adafruit IO feed key :param string data_id: Data point to delete from the feed """ + validate_feed_key(feed_key) path = self._compose_path("feeds/{0}/data/{1}".format(feed_key, data_id)) return self._delete(path) @@ -614,6 +637,7 @@ def add_feed_to_group(self, group_key, feed_key): :param str group_key: Group :param str feed_key: Feed to add to the group """ + validate_feed_key(feed_key) path = self._compose_path("groups/{0}/add".format(group_key)) payload = {"feed_key": feed_key} return self._post(path, payload) @@ -625,6 +649,7 @@ def get_feed(self, feed_key, detailed=False): :param str feed_key: Adafruit IO Feed Key :param bool detailed: Returns a more verbose feed record """ + validate_feed_key(feed_key) if detailed: path = self._compose_path("feeds/{0}/details".format(feed_key)) else: @@ -638,6 +663,7 @@ def create_new_feed(self, feed_key, feed_desc=None, feed_license=None): :param str feed_desc: Optional description of feed :param str feed_license: Optional feed license """ + validate_feed_key(feed_key) path = self._compose_path("feeds") payload = {"name": feed_key, "description": feed_desc, "license": feed_license} return self._post(path, payload) @@ -647,6 +673,7 @@ def delete_feed(self, feed_key): Deletes an existing feed. :param str feed_key: Valid feed key """ + validate_feed_key(feed_key) path = self._compose_path("feeds/{0}".format(feed_key)) return self._delete(path) From d030d22d589662ac9eaa01cd9a165b1a91d8c76f Mon Sep 17 00:00:00 2001 From: Rodrigo Argumedo Date: Fri, 30 Apr 2021 08:52:34 -0500 Subject: [PATCH 052/153] Create send_batch_data method Additionally, Define the data variable as an empty array. --- adafruit_io/adafruit_io.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 5443727..2d72023 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -565,6 +565,26 @@ def send_data(self, feed_key, data, metadata=None, precision=None): payload = self._create_data(data, metadata) self._post(path, payload) + def send_batch_data(self, feed_key, data, metadata=None, precision=None): + """ + Sends a batch array of data to a specified Adafruit IO feed + :param str feed_key: Adafruit IO feed key + :param str data: Data to send + :param dict metadata: Optional metadata associated with the data + :param int precision: Optional amount of precision points to send with floating point data + """ + data = [] + path = self._compose_path("feeds/{0}/data/batch".format(feed_key)) + if precision: + try: + data = round(data, precision) + except NotImplementedError as err: + raise NotImplementedError( + "Precision requires a floating point value" + ) from err + payload = self._create_data(data, metadata) + self._post(path, payload) + def receive_all_data(self, feed_key): """ Get all data values from a specified Adafruit IO feed. Data is From 9392e29603b507293a41cadb89e71e7926d39441 Mon Sep 17 00:00:00 2001 From: Flavio Fernandes Date: Sun, 2 May 2021 18:23:09 -0400 Subject: [PATCH 053/153] validate feed keys used needs to allow periods The recently introduced validate_feed_key [0] function needs to account for cases when feed_id includes a group. For example: "sign-quotes.signtext" Fixes adafruit/Adafruit_CircuitPython_AdafruitIO#71 [0]: https://github.com/adafruit/Adafruit_CircuitPython_AdafruitIO/commit/1e3d458ccbe86dade80ce3005a41ffed5d50b864 --- adafruit_io/adafruit_io.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 5443727..32b3abc 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -40,9 +40,11 @@ def validate_feed_key(feed_key): """ if len(feed_key) > 128: # validate feed key length raise ValueError("Feed key must be less than 128 characters.") - if not bool(re.match("^[a-z0-9-]+$", feed_key)): # validate key naming scheme + if not bool( + re.match(r"^[a-z0-9-]+(\.[a-z0-9-]+)?$", feed_key) + ): # validate key naming scheme raise TypeError( - "Feed key must contain lower case English letters, numbers, and dash." + "Feed key must contain lower case English letters, numbers, dash, and one period." ) From 340d57336cbd0956a60761107fd5bc18c3517873 Mon Sep 17 00:00:00 2001 From: Rodrigo Argumedo Date: Mon, 3 May 2021 20:30:26 -0500 Subject: [PATCH 054/153] Strip unnecessary parameters and reformat code --- adafruit_io/adafruit_io.py | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 2d72023..4410875 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -565,25 +565,16 @@ def send_data(self, feed_key, data, metadata=None, precision=None): payload = self._create_data(data, metadata) self._post(path, payload) - def send_batch_data(self, feed_key, data, metadata=None, precision=None): + def send_batch_data(self, feed, data_list): """ Sends a batch array of data to a specified Adafruit IO feed :param str feed_key: Adafruit IO feed key - :param str data: Data to send - :param dict metadata: Optional metadata associated with the data - :param int precision: Optional amount of precision points to send with floating point data + :param list Data: Data list to send """ - data = [] - path = self._compose_path("feeds/{0}/data/batch".format(feed_key)) - if precision: - try: - data = round(data, precision) - except NotImplementedError as err: - raise NotImplementedError( - "Precision requires a floating point value" - ) from err - payload = self._create_data(data, metadata) - self._post(path, payload) + validate_feed_key(feed) + path = "feeds/{0}/data/batch".format(feed) + data_dict = type(data_list)((data._asdict() for data in data_list)) + self._post(path, {"data": data_dict}) def receive_all_data(self, feed_key): """ From 363a3fd05670dc93d9324dccdd84e031ece556f6 Mon Sep 17 00:00:00 2001 From: Rodrigo Argumedo Date: Wed, 5 May 2021 19:46:28 -0500 Subject: [PATCH 055/153] Match feed_key parameters and variables in send_batch_data --- adafruit_io/adafruit_io.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 4410875..f8eb476 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -565,14 +565,14 @@ def send_data(self, feed_key, data, metadata=None, precision=None): payload = self._create_data(data, metadata) self._post(path, payload) - def send_batch_data(self, feed, data_list): + def send_batch_data(self, feed_key, data_list): """ Sends a batch array of data to a specified Adafruit IO feed :param str feed_key: Adafruit IO feed key :param list Data: Data list to send """ - validate_feed_key(feed) - path = "feeds/{0}/data/batch".format(feed) + validate_feed_key(feed_key) + path = "feeds/{0}/data/batch".format(feed_key) data_dict = type(data_list)((data._asdict() for data in data_list)) self._post(path, {"data": data_dict}) From 401f442775ae6e7d595f30aa55fb5416705abbb2 Mon Sep 17 00:00:00 2001 From: dherrada Date: Wed, 19 May 2021 13:32:42 -0400 Subject: [PATCH 056/153] Added pull request template Signed-off-by: dherrada --- .../adafruit_circuitpython_pr.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE/adafruit_circuitpython_pr.md diff --git a/.github/PULL_REQUEST_TEMPLATE/adafruit_circuitpython_pr.md b/.github/PULL_REQUEST_TEMPLATE/adafruit_circuitpython_pr.md new file mode 100644 index 0000000..71ef8f8 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/adafruit_circuitpython_pr.md @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2021 Adafruit Industries +# +# SPDX-License-Identifier: MIT + +Thank you for contributing! Before you submit a pull request, please read the following. + +Make sure any changes you're submitting are in line with the CircuitPython Design Guide, available here: https://circuitpython.readthedocs.io/en/latest/docs/design_guide.html + +If your changes are to documentation, please verify that the documentation builds locally by following the steps found here: https://adafru.it/build-docs + +Before submitting the pull request, make sure you've run Pylint and Black locally on your code. You can do this manually or using pre-commit. Instructions are available here: https://adafru.it/check-your-code + +Please remove all of this text before submitting. Include an explanation or list of changes included in your PR, as well as, if applicable, a link to any related issues. From cefc4dc9898a7db91edadb73cc1ba5bfd31b232f Mon Sep 17 00:00:00 2001 From: dherrada Date: Wed, 19 May 2021 13:35:18 -0400 Subject: [PATCH 057/153] Added help text and problem matcher Signed-off-by: dherrada --- .github/workflows/build.yml | 2 ++ .github/workflows/failure-help-text.yml | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 .github/workflows/failure-help-text.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fd99fee..dfa946b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,3 +76,5 @@ jobs: python setup.py sdist python setup.py bdist_wheel --universal twine check dist/* + - name: Setup problem matchers + uses: adafruit/circuitpython-action-library-ci-problem-matchers@v1 diff --git a/.github/workflows/failure-help-text.yml b/.github/workflows/failure-help-text.yml new file mode 100644 index 0000000..0b1194f --- /dev/null +++ b/.github/workflows/failure-help-text.yml @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: 2021 Scott Shawcroft for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +name: Failure help text + +on: + workflow_run: + workflows: ["Build CI"] + types: + - completed + +jobs: + post-help: + runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.event == 'pull_request' }} + steps: + - name: Post comment to help + uses: adafruit/circuitpython-action-library-ci-failed@v1 From f9a2da8cfac38cc6f2d6ffdb0e0fdc09784806d5 Mon Sep 17 00:00:00 2001 From: dherrada Date: Mon, 24 May 2021 09:54:31 -0400 Subject: [PATCH 058/153] Moved CI to Python 3.7 Signed-off-by: dherrada --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dfa946b..000844b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,10 +22,10 @@ jobs: awk -F '\/' '{ print tolower($2) }' | tr '_' '-' ) - - name: Set up Python 3.6 + - name: Set up Python 3.7 uses: actions/setup-python@v1 with: - python-version: 3.6 + python-version: 3.7 - name: Versions run: | python3 --version From 0f6b389a8db3b6324dbe5ba13930004eb5dd63cb Mon Sep 17 00:00:00 2001 From: dherrada Date: Wed, 2 Jun 2021 14:12:16 -0400 Subject: [PATCH 059/153] Moved default branch to main --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 446435b..38abbc9 100644 --- a/README.rst +++ b/README.rst @@ -63,7 +63,7 @@ Contributing ============ Contributions are welcome! Please read our `Code of Conduct -`_ +`_ before contributing to help this project stay welcoming. Documentation From 3e54af32b01f5b5d0fb5852ea842baaac3e79c15 Mon Sep 17 00:00:00 2001 From: dherrada Date: Thu, 10 Jun 2021 11:09:21 -0400 Subject: [PATCH 060/153] Modified regex to accept uppercase characters and a forward slash --- adafruit_io/adafruit_io.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index e91c5d9..26fcf3a 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -41,10 +41,10 @@ def validate_feed_key(feed_key): if len(feed_key) > 128: # validate feed key length raise ValueError("Feed key must be less than 128 characters.") if not bool( - re.match(r"^[a-z0-9-]+(\.[a-z0-9-]+)?$", feed_key) + re.match(r"^[a-zA-Z0-9-]+((\/|\.)[a-zA-Z0-9-]+)?$", feed_key) ): # validate key naming scheme raise TypeError( - "Feed key must contain lower case English letters, numbers, dash, and one period." + "Feed key must contain English letters, numbers, dash, and one period or one forward slash." ) From fff49a23d7c199c4b6347448e8da65eaae590455 Mon Sep 17 00:00:00 2001 From: dherrada Date: Thu, 10 Jun 2021 11:10:49 -0400 Subject: [PATCH 061/153] Fixed line-too-long --- adafruit_io/adafruit_io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 26fcf3a..0df4a78 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -44,7 +44,7 @@ def validate_feed_key(feed_key): re.match(r"^[a-zA-Z0-9-]+((\/|\.)[a-zA-Z0-9-]+)?$", feed_key) ): # validate key naming scheme raise TypeError( - "Feed key must contain English letters, numbers, dash, and one period or one forward slash." + "Feed key must contain English letters, numbers, dash, and a period or a forward slash." ) From 8d23a54f78cd6b4da830fa0f24034ec38b2d9c48 Mon Sep 17 00:00:00 2001 From: dherrada Date: Thu, 10 Jun 2021 12:04:24 -0400 Subject: [PATCH 062/153] Added ability to set loop timeout --- adafruit_io/adafruit_io.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index e91c5d9..d33f5e5 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -218,7 +218,7 @@ def remove_feed_callback(self, feed_key): validate_feed_key(feed_key) self._client.remove_topic_callback("{0}/f/{1}".format(self._user, feed_key)) - def loop(self): + def loop(self, timeout=1): """Manually process messages from Adafruit IO. Call this method to check incoming subscription messages. @@ -229,7 +229,7 @@ def loop(self): while True: io.loop() """ - self._client.loop() + self._client.loop(timeout) # Subscriptions def subscribe(self, feed_key=None, group_key=None, shared_user=None): From 9b177456fc19c76267efb08079c9a6f8c5706b1d Mon Sep 17 00:00:00 2001 From: dherrada Date: Thu, 10 Jun 2021 12:26:03 -0400 Subject: [PATCH 063/153] Added :param: --- adafruit_io/adafruit_io.py | 1 + 1 file changed, 1 insertion(+) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index d33f5e5..9b51d34 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -221,6 +221,7 @@ def remove_feed_callback(self, feed_key): def loop(self, timeout=1): """Manually process messages from Adafruit IO. Call this method to check incoming subscription messages. + :param int timeout: Socket timeout, in seconds. Example usage of polling the message queue using loop. From 5d687cbdaf880c20b997229107297a68af3ba340 Mon Sep 17 00:00:00 2001 From: aerialist Date: Sat, 10 Jul 2021 19:01:44 +0900 Subject: [PATCH 064/153] Call wifi.connect() after wifi.reset() Need to explicitly call connect method after reset when WiFi manager is used with MQTT. https://github.com/adafruit/Adafruit_CircuitPython_ESP32SPI/issues/100 --- examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py index a5ce569..fae9b0b 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py +++ b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py @@ -105,6 +105,7 @@ def on_led_msg(client, topic, message): except (ValueError, RuntimeError) as e: print("Failed to get data, retrying\n", e) wifi.reset() + wifi.connect() io.reconnect() continue # Send a new temperature reading to IO every 30 seconds From 51d65c33118d3f6adb82aeeff8c20ae4a1a41789 Mon Sep 17 00:00:00 2001 From: Ryan Hartlage Date: Sat, 17 Jul 2021 16:52:34 -0400 Subject: [PATCH 065/153] Allow group feeds to be subscribed to `IO_MQTT#subscribe` always checks `feed_key` even though it is not required. When `group_key` is provided instead of `feed_key`, `feed_key` should not be required to be valid. This change only validates `feed_key` when one is provided and adds validation for `group_key` when it is provided. --- adafruit_io/adafruit_io.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 943f23f..d2f638f 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -253,12 +253,14 @@ def subscribe(self, feed_key=None, group_key=None, shared_user=None): client.subscribe([('temperature'), ('humidity')]) """ - validate_feed_key(feed_key) if shared_user is not None and feed_key is not None: + validate_feed_key(feed_key) self._client.subscribe("{0}/f/{1}".format(shared_user, feed_key)) elif group_key is not None: + validate_feed_key(group_key) self._client.subscribe("{0}/g/{1}".format(self._user, group_key)) elif feed_key is not None: + validate_feed_key(feed_key) self._client.subscribe("{0}/f/{1}".format(self._user, feed_key)) else: raise AdafruitIO_MQTTError("Must provide a feed_key or group_key.") From 8749175f393c0ef86880174f0436416e5b4d8e33 Mon Sep 17 00:00:00 2001 From: Ryan Hartlage Date: Sat, 17 Jul 2021 17:20:19 -0400 Subject: [PATCH 066/153] Allow groups to be unsubscribed from --- adafruit_io/adafruit_io.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index d2f638f..ab43d0b 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -335,12 +335,14 @@ def unsubscribe(self, feed_key=None, group_key=None, shared_user=None): client.unsubscribe('temperature', shared_user='adabot') """ - validate_feed_key(feed_key) if shared_user is not None and feed_key is not None: + validate_feed_key(feed_key) self._client.unsubscribe("{0}/f/{1}".format(shared_user, feed_key)) elif group_key is not None: + validate_feed_key(group_key) self._client.unsubscribe("{0}/g/{1}".format(self._user, feed_key)) elif feed_key is not None: + validate_feed_key(feed_key) self._client.unsubscribe("{0}/f/{1}".format(self._user, feed_key)) else: raise AdafruitIO_MQTTError("Must provide a feed_key or group_key.") From a699ce4566efb17b40e4a375d8e618299a6d08f3 Mon Sep 17 00:00:00 2001 From: dherrada Date: Thu, 23 Sep 2021 17:52:55 -0400 Subject: [PATCH 067/153] Globally disabled consider-using-f-string pylint check Signed-off-by: dherrada --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 354c761..8810708 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,5 +30,5 @@ repos: name: pylint (examples code) description: Run pylint rules on "examples/*.py" files entry: /usr/bin/env bash -c - args: ['([[ ! -d "examples" ]] || for example in $(find . -path "./examples/*.py"); do pylint --disable=missing-docstring,invalid-name $example; done)'] + args: ['([[ ! -d "examples" ]] || for example in $(find . -path "./examples/*.py"); do pylint --disable=missing-docstring,invalid-name,consider-using-f-string $example; done)'] language: system From 40d5a5ff39871313b4a34c0500208933e327be22 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Mon, 25 Oct 2021 11:25:32 -0500 Subject: [PATCH 068/153] add docs link to readme --- README.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.rst b/README.rst index 38abbc9..3d4dfba 100644 --- a/README.rst +++ b/README.rst @@ -59,6 +59,11 @@ Usage examples for the Adafruit IO HTTP API are within the examples/http folder. Usage examples for the Adafruit IO MQTT API are within the examples/mqtt folder. +Documentation +============= + +API documentation for this library can be found on `Read the Docs `_. + Contributing ============ From 93e7913ab640556691209b9469e40a05dcf90a4e Mon Sep 17 00:00:00 2001 From: dherrada Date: Wed, 3 Nov 2021 14:40:16 -0400 Subject: [PATCH 069/153] PATCH Pylint and readthedocs patch test Signed-off-by: dherrada --- .github/workflows/build.yml | 4 ++-- .pre-commit-config.yaml | 26 +++++++++++++++++--------- .pylintrc | 2 +- .readthedocs.yml | 2 +- docs/requirements.txt | 5 +++++ 5 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 docs/requirements.txt diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 000844b..860cc36 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,9 +42,9 @@ jobs: # (e.g. - apt-get: gettext, etc; pip: circuitpython-build-tools, requirements.txt; etc.) run: | source actions-ci/install.sh - - name: Pip install pylint, Sphinx, pre-commit + - name: Pip install Sphinx, pre-commit run: | - pip install --force-reinstall pylint Sphinx sphinx-rtd-theme pre-commit + pip install --force-reinstall Sphinx sphinx-rtd-theme pre-commit - name: Library version run: git describe --dirty --always --tags - name: Pre-commit hooks diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8810708..1b9fadc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,17 +18,25 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/pycqa/pylint - rev: pylint-2.7.1 + rev: v2.11.1 hooks: - id: pylint name: pylint (library code) types: [python] - exclude: "^(docs/|examples/|setup.py$)" -- repo: local - hooks: - - id: pylint_examples - name: pylint (examples code) + args: + - --disable=consider-using-f-string + exclude: "^(docs/|examples/|tests/|setup.py$)" + - id: pylint + name: pylint (example code) description: Run pylint rules on "examples/*.py" files - entry: /usr/bin/env bash -c - args: ['([[ ! -d "examples" ]] || for example in $(find . -path "./examples/*.py"); do pylint --disable=missing-docstring,invalid-name,consider-using-f-string $example; done)'] - language: system + types: [python] + files: "^examples/" + args: + - --disable=missing-docstring,invalid-name,consider-using-f-string,duplicate-code + - id: pylint + name: pylint (test code) + description: Run pylint rules on "tests/*.py" files + types: [python] + files: "^tests/" + args: + - --disable=missing-docstring,consider-using-f-string,duplicate-code diff --git a/.pylintrc b/.pylintrc index 0238b90..e78bad2 100644 --- a/.pylintrc +++ b/.pylintrc @@ -252,7 +252,7 @@ ignore-docstrings=yes ignore-imports=yes # Minimum lines number of a similarity. -min-similarity-lines=12 +min-similarity-lines=4 [BASIC] diff --git a/.readthedocs.yml b/.readthedocs.yml index ffa84c4..49dcab3 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -4,4 +4,4 @@ python: version: 3 -requirements_file: requirements.txt +requirements_file: docs/requirements.txt diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..88e6733 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries +# +# SPDX-License-Identifier: Unlicense + +sphinx>=4.0.0 From 734ce7807ef6fd6cf24fa4e5d938a3f3b309141d Mon Sep 17 00:00:00 2001 From: dherrada Date: Fri, 5 Nov 2021 14:49:30 -0400 Subject: [PATCH 070/153] Disabled unspecified-encoding pylint check Signed-off-by: dherrada --- .pylintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pylintrc b/.pylintrc index e78bad2..cfd1c41 100644 --- a/.pylintrc +++ b/.pylintrc @@ -55,7 +55,7 @@ confidence= # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" # disable=import-error,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call -disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,bad-continuation +disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,bad-continuation,unspecified-encoding # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option From 0d2266a368f0c819c04f318ef49f45ab7df1f135 Mon Sep 17 00:00:00 2001 From: dherrada Date: Tue, 9 Nov 2021 13:31:14 -0500 Subject: [PATCH 071/153] Updated readthedocs file Signed-off-by: dherrada --- .readthedocs.yaml | 15 +++++++++++++++ .readthedocs.yml | 7 ------- 2 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 .readthedocs.yaml delete mode 100644 .readthedocs.yml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..95ec218 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# +# SPDX-License-Identifier: Unlicense + +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +python: + version: "3.6" + install: + - requirements: docs/requirements.txt + - requirements: requirements.txt diff --git a/.readthedocs.yml b/.readthedocs.yml deleted file mode 100644 index 49dcab3..0000000 --- a/.readthedocs.yml +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries -# -# SPDX-License-Identifier: Unlicense - -python: - version: 3 -requirements_file: docs/requirements.txt From e6d4b01e061329d4dc0d5d77acc53126416f6e38 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 23 Nov 2021 13:11:23 -0600 Subject: [PATCH 072/153] update rtd py version --- .readthedocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 95ec218..1335112 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -9,7 +9,7 @@ version: 2 python: - version: "3.6" + version: "3.7" install: - requirements: docs/requirements.txt - requirements: requirements.txt From be123828d2e87b92c3191503afb9400b4c03e374 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 1 Dec 2021 12:23:36 -0500 Subject: [PATCH 073/153] add __init__.py to example folders to make proper packages --- examples/adafruit_io_http/__init__.py | 0 examples/adafruit_io_mqtt/__init__.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/adafruit_io_http/__init__.py create mode 100644 examples/adafruit_io_mqtt/__init__.py diff --git a/examples/adafruit_io_http/__init__.py b/examples/adafruit_io_http/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/adafruit_io_mqtt/__init__.py b/examples/adafruit_io_mqtt/__init__.py new file mode 100644 index 0000000..e69de29 From 5c356b1752659de705cb8cacef697feb909603e1 Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Tue, 7 Dec 2021 12:02:29 -0500 Subject: [PATCH 074/153] Add create_and_get_feed --- adafruit_io/adafruit_io.py | 18 +++++++ .../adafruit_io_create_and_get_feed.py | 47 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 examples/adafruit_io_http/adafruit_io_create_and_get_feed.py diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index ab43d0b..53efb66 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -686,6 +686,24 @@ def create_new_feed(self, feed_key, feed_desc=None, feed_license=None): payload = {"name": feed_key, "description": feed_desc, "license": feed_license} return self._post(path, payload) + def create_and_get_feed( + self, feed_key, detailed=False, feed_desc=None, feed_license=None + ): + """ + Attempts to return a feed; if the feed does not exist, it is created, and then returned. + :param str feed_key: Adafruit IO Feed Key + :param bool detailed: Returns a more verbose existing feed record + :param str feed_desc: Optional description of feed to be created + :param str feed_license: Optional feed license to be created + """ + try: + return self.get_feed(feed_key, detailed=detailed) + except AdafruitIO_RequestError: + self.create_new_feed( + feed_key, feed_desc=feed_desc, feed_license=feed_license + ) + return self.get_feed(feed_key, detailed=detailed) + def delete_feed(self, feed_key): """ Deletes an existing feed. diff --git a/examples/adafruit_io_http/adafruit_io_create_and_get_feed.py b/examples/adafruit_io_http/adafruit_io_create_and_get_feed.py new file mode 100644 index 0000000..7b687f6 --- /dev/null +++ b/examples/adafruit_io_http/adafruit_io_create_and_get_feed.py @@ -0,0 +1,47 @@ +# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries +# SPDX-License-Identifier: MIT +""" +Example using create_and_get_feed. Creates a new feed if it does not exist and sends to it, or +sends to an existing feed once it has been created. +""" +import ssl +import adafruit_requests +import socketpool +import wifi +import microcontroller +from adafruit_io.adafruit_io import IO_HTTP + +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials, and "aio_username" and "aio_key" keys with your +# Adafruit IO credentials, DO NOT share that file or commit it into Git or other +# source control. +# pylint: disable=no-name-in-module,wrong-import-order +try: + from secrets import secrets +except ImportError: + print( + "WiFi and Adafruit IO credentials are kept in secrets.py, please add them there!" + ) + raise + +# Connect to Wi-Fi using credentials from secrets.py +wifi.radio.connect(secrets["ssid"], secrets["password"]) +print("Connected to {}!".format(secrets["ssid"])) +print("IP:", wifi.radio.ipv4_address) + +pool = socketpool.SocketPool(wifi.radio) +requests = adafruit_requests.Session(pool, ssl.create_default_context()) + +# Obtain Adafruit IO credentials from secrets.py +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) + +# Create temperature variable using the CPU temperature and print the current value. +temperature = microcontroller.cpu.temperature +print("Current CPU temperature: {0} C".format(temperature)) + +# Create and get feed. +io.send_data(io.create_and_get_feed("cpu-temperature-feed")["key"], temperature) From d7c302fb98cfa34810c06ffc21216dd8edf6a40c Mon Sep 17 00:00:00 2001 From: dherrada Date: Thu, 13 Jan 2022 16:27:30 -0500 Subject: [PATCH 075/153] First part of patch Signed-off-by: dherrada --- .../PULL_REQUEST_TEMPLATE/adafruit_circuitpython_pr.md | 2 +- .github/workflows/build.yml | 6 +++--- .github/workflows/release.yml | 8 ++++---- .readthedocs.yaml | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE/adafruit_circuitpython_pr.md b/.github/PULL_REQUEST_TEMPLATE/adafruit_circuitpython_pr.md index 71ef8f8..8de294e 100644 --- a/.github/PULL_REQUEST_TEMPLATE/adafruit_circuitpython_pr.md +++ b/.github/PULL_REQUEST_TEMPLATE/adafruit_circuitpython_pr.md @@ -4,7 +4,7 @@ Thank you for contributing! Before you submit a pull request, please read the following. -Make sure any changes you're submitting are in line with the CircuitPython Design Guide, available here: https://circuitpython.readthedocs.io/en/latest/docs/design_guide.html +Make sure any changes you're submitting are in line with the CircuitPython Design Guide, available here: https://docs.circuitpython.org/en/latest/docs/design_guide.html If your changes are to documentation, please verify that the documentation builds locally by following the steps found here: https://adafru.it/build-docs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 860cc36..140d2d9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,10 +22,10 @@ jobs: awk -F '\/' '{ print tolower($2) }' | tr '_' '-' ) - - name: Set up Python 3.7 - uses: actions/setup-python@v1 + - name: Set up Python 3.x + uses: actions/setup-python@v2 with: - python-version: 3.7 + python-version: "3.x" - name: Versions run: | python3 --version diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6d0015a..a65e5de 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,10 +24,10 @@ jobs: awk -F '\/' '{ print tolower($2) }' | tr '_' '-' ) - - name: Set up Python 3.6 - uses: actions/setup-python@v1 + - name: Set up Python 3.x + uses: actions/setup-python@v2 with: - python-version: 3.6 + python-version: "3.x" - name: Versions run: | python3 --version @@ -67,7 +67,7 @@ jobs: echo ::set-output name=setup-py::$( find . -wholename './setup.py' ) - name: Set up Python if: contains(steps.need-pypi.outputs.setup-py, 'setup.py') - uses: actions/setup-python@v1 + uses: actions/setup-python@v2 with: python-version: '3.x' - name: Install dependencies diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 1335112..f8b2891 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -9,7 +9,7 @@ version: 2 python: - version: "3.7" + version: "3.x" install: - requirements: docs/requirements.txt - requirements: requirements.txt From 818f890f213cd9de4f61a691951ea5572be111eb Mon Sep 17 00:00:00 2001 From: dherrada Date: Mon, 24 Jan 2022 16:15:28 -0500 Subject: [PATCH 076/153] Updated docs link, updated python docs link, updated setup.py --- README.rst | 4 ++-- docs/conf.py | 4 ++-- docs/index.rst | 2 +- setup.py | 2 -- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index 3d4dfba..12dd624 100644 --- a/README.rst +++ b/README.rst @@ -2,7 +2,7 @@ Adafruit_CircuitPython_AdafruitIO ================================= .. image:: https://readthedocs.org/projects/adafruit-circuitpython-adafruitio/badge/?version=latest - :target: https://circuitpython.readthedocs.io/projects/adafruitio/en/latest/ + :target: https://docs.circuitpython.org/projects/adafruitio/en/latest/ :alt: Documentation Status .. image:: https://img.shields.io/discord/327254708534116352.svg @@ -62,7 +62,7 @@ Usage examples for the Adafruit IO MQTT API are within the examples/mqtt folder. Documentation ============= -API documentation for this library can be found on `Read the Docs `_. +API documentation for this library can be found on `Read the Docs `_. Contributing ============ diff --git a/docs/conf.py b/docs/conf.py index dd4cec9..181c912 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,8 +22,8 @@ ] intersphinx_mapping = { - "python": ("https://docs.python.org/3.4", None), - "CircuitPython": ("https://circuitpython.readthedocs.io/en/latest/", None), + "python": ("https://docs.python.org/3", None), + "CircuitPython": ("https://docs.circuitpython.org/en/latest/", None), } # Add any paths that contain templates here, relative to this directory. diff --git a/docs/index.rst b/docs/index.rst index fd9f01d..2096b02 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -31,7 +31,7 @@ Table of Contents :caption: Other Links Download - CircuitPython Reference Documentation + CircuitPython Reference Documentation CircuitPython Support Forum Discord Chat Adafruit Learning System diff --git a/setup.py b/setup.py index d3563e3..8120854 100644 --- a/setup.py +++ b/setup.py @@ -44,8 +44,6 @@ "Topic :: System :: Hardware", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", ], # What does your project relate to? keywords="adafruit blinka circuitpython micropython adafruit_io adafruit-io rest api iot " From 0cb67757cd3db103aee57fa7f4a8084efb2723ec Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Thu, 10 Feb 2022 09:34:38 -0500 Subject: [PATCH 077/153] Consolidate Documentation sections of README --- README.rst | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 12dd624..8abe6db 100644 --- a/README.rst +++ b/README.rst @@ -64,14 +64,11 @@ Documentation API documentation for this library can be found on `Read the Docs `_. +For information on building library documentation, please check out `this guide `_. + Contributing ============ Contributions are welcome! Please read our `Code of Conduct `_ before contributing to help this project stay welcoming. - -Documentation -============= - -For information on building library documentation, please check out `this guide `_. From 41c8ec54438507657b83fccd0f24e28b85b9a2ef Mon Sep 17 00:00:00 2001 From: dherrada Date: Mon, 14 Feb 2022 15:35:02 -0500 Subject: [PATCH 078/153] Fixed readthedocs build Signed-off-by: dherrada --- .readthedocs.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index f8b2891..33c2a61 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -8,8 +8,12 @@ # Required version: 2 +build: + os: ubuntu-20.04 + tools: + python: "3" + python: - version: "3.x" install: - requirements: docs/requirements.txt - requirements: requirements.txt From 62b8b20e5228a9cfe2c5cbbe9c1b50a8d2dfa9ae Mon Sep 17 00:00:00 2001 From: lady ada Date: Tue, 22 Mar 2022 17:59:44 -0400 Subject: [PATCH 079/153] the property did not work before. now it does what you expect - return true or false --- adafruit_io/adafruit_io.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 53efb66..624753f 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -22,6 +22,7 @@ import json import re +from adafruit_minimqtt.adafruit_minimqtt import MMQTTException from adafruit_io.adafruit_io_errors import ( AdafruitIO_RequestError, AdafruitIO_ThrottleError, @@ -117,7 +118,10 @@ def disconnect(self): @property def is_connected(self): """Returns if connected to Adafruit IO MQTT Broker.""" - return self._client.is_connected + try: + return self._client.is_connected() + except MMQTTException: + return False # pylint: disable=not-callable, unused-argument def _on_connect_mqtt(self, client, userdata, flags, return_code): From 2cee8b92a440cb7aacfbec54ec08e51cdfa6d1a3 Mon Sep 17 00:00:00 2001 From: lady ada Date: Tue, 22 Mar 2022 18:00:50 -0400 Subject: [PATCH 080/153] add requirement --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index f772f7b..ea5a0fd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ Adafruit-Blinka Adafruit_CircuitPython_ESP32SPI +Adafruit_CircuitPython_MiniMQTT From fac1039e9a5c05eb7a6caefd145abac5a05014fa Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Sun, 27 Mar 2022 13:44:53 -0400 Subject: [PATCH 081/153] Add adafruit_minimqtt as setup.py requirement --- setup.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 8120854..ba6d32c 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,11 @@ # Author details author="Adafruit Industries", author_email="circuitpython@adafruit.com", - install_requires=["Adafruit-Blinka", "Adafruit_CircuitPython_ESP32SPI"], + install_requires=[ + "Adafruit-Blinka", + "Adafruit_CircuitPython_ESP32SPI", + "Adafruit-CircuitPython-MiniMQTT", + ], # Choose your license license="MIT", # See https://pypi.python.org/pypi?%3Aaction=list_classifiers From a31b69947b438e48b07bab327d99cf4d960cf9aa Mon Sep 17 00:00:00 2001 From: Neradoc Date: Mon, 28 Mar 2022 14:53:51 +0200 Subject: [PATCH 082/153] Fix documentation of params and code blocks --- adafruit_io/adafruit_io.py | 71 ++++++++++++++++++++++++++++---------- docs/api.rst | 3 +- 2 files changed, 53 insertions(+), 21 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 624753f..ee50f25 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -146,6 +146,7 @@ def _on_disconnect_mqtt(self, client, userdata, return_code): def _on_message_mqtt(self, client, topic, payload): """Runs when the client calls on_message. Parses and returns incoming data from Adafruit IO feeds. + :param MQTT client: A MQTT Client Instance. :param str topic: MQTT topic response from Adafruit IO. :param str payload: MQTT payload data response from Adafruit IO. @@ -201,9 +202,9 @@ def add_feed_callback(self, feed_key, callback_method): NOTE: The callback_method registered to this method will only execute during loop(). + :param str feed_key: Adafruit IO feed key. :param str callback_method: Name of callback method. - """ validate_feed_key(feed_key) self._client.add_topic_callback( @@ -216,8 +217,8 @@ def remove_feed_callback(self, feed_key): After this method is called, incoming messages call the shared on_message. - :param str feed_key: Adafruit IO feed key. + :param str feed_key: Adafruit IO feed key. """ validate_feed_key(feed_key) self._client.remove_topic_callback("{0}/f/{1}".format(self._user, feed_key)) @@ -225,11 +226,12 @@ def remove_feed_callback(self, feed_key): def loop(self, timeout=1): """Manually process messages from Adafruit IO. Call this method to check incoming subscription messages. + :param int timeout: Socket timeout, in seconds. Example usage of polling the message queue using loop. - ..code-block:: python + .. code-block:: python while True: io.loop() @@ -240,6 +242,7 @@ def loop(self, timeout=1): def subscribe(self, feed_key=None, group_key=None, shared_user=None): """Subscribes to your Adafruit IO feed or group. Can also subscribe to someone else's feed. + :param str feed_key: Adafruit IO Feed key. :param str group_key: Adafruit IO Group key. :param str shared_user: Owner of the Adafruit IO feed, required for shared feeds. @@ -283,6 +286,7 @@ def subscribe_to_errors(self): def subscribe_to_randomizer(self, randomizer_id): """Subscribes to a random data stream created by the Adafruit IO Words service. + :param int randomizer_id: Random word record you want data for. """ self._client.subscribe( @@ -292,6 +296,7 @@ def subscribe_to_randomizer(self, randomizer_id): def subscribe_to_weather(self, weather_record, forecast): """Subscribes to a weather forecast using the Adafruit IO PLUS weather service. This feature is only avaliable to Adafruit IO PLUS subscribers. + :param int weather_record: Weather record you want data for. :param str forecast: Forecast data you'd like to recieve. """ @@ -303,7 +308,9 @@ def subscribe_to_weather(self, weather_record, forecast): def subscribe_to_time(self, time_type): """Adafruit IO provides some built-in MQTT topics for getting the current server time. + :param str time_type: Current Adafruit IO server time. Can be 'seconds', 'millis', or 'iso'. + Information about these topics can be found on the Adafruit IO MQTT API Docs.: https://io.adafruit.com/api/docs/mqtt.html#time-topics """ @@ -315,6 +322,7 @@ def subscribe_to_time(self, time_type): def unsubscribe(self, feed_key=None, group_key=None, shared_user=None): """Unsubscribes from an Adafruit IO feed or group. Can also subscribe to someone else's feed. + :param str feed_key: Adafruit IO Feed key. :param str group_key: Adafruit IO Group key. :param str shared_user: Owner of the Adafruit IO feed, required for shared feeds. @@ -337,7 +345,6 @@ def unsubscribe(self, feed_key=None, group_key=None, shared_user=None): .. code-block:: python client.unsubscribe('temperature', shared_user='adabot') - """ if shared_user is not None and feed_key is not None: validate_feed_key(feed_key) @@ -361,10 +368,10 @@ def publish_multiple(self, feeds_and_data, timeout=3, is_group=False): :param bool is_group: Set to True if you're publishing to a group. Example of publishing multiple data points on different feeds to Adafruit IO: - ..code-block:: python - client.publish_multiple([('humidity', 24.5), ('temperature', 54)]) + .. code-block:: python + client.publish_multiple([('humidity', 24.5), ('temperature', 54)]) """ if isinstance(feeds_and_data, list): feed_data = [] @@ -393,38 +400,43 @@ def publish(self, feed_key, data, metadata=None, shared_user=None, is_group=Fals :param bool is_group: Set True if publishing to an Adafruit IO Group. Example of publishing an integer to Adafruit IO on feed 'temperature'. - ..code-block:: python + + .. code-block:: python client.publish('temperature', 30) Example of publishing a floating point value to feed 'temperature'. - ..code-block:: python + + .. code-block:: python client.publish('temperature', 3.14) Example of publishing a string to feed 'temperature'. - ..code-block:: python + + .. code-block:: python client.publish('temperature, 'thirty degrees') Example of publishing an integer to group 'weatherstation'. - ..code-block:: python + + .. code-block:: python client.publish('weatherstation', 12, is_group=True) Example of publishing to a shared feed. - ..code-block:: python + + .. code-block:: python client.publish('temperature', shared_user='myfriend') Example of publishing a value along with locational metadata to a feed. - ..code-block:: python + + .. code-block:: python data = 42 # format: "lat, lon, ele" metadata = "40.726190, -74.005334, -6" io.publish("location-feed", data, metadata) - """ validate_feed_key(feed_key) if is_group: @@ -445,10 +457,12 @@ def get(self, feed_key): """Calling this method will make Adafruit IO publish the most recent value on feed_key. https://io.adafruit.com/api/docs/mqtt.html#retained-values + :param str feed_key: Adafruit IO Feed key. Example of obtaining a recently published value on a feed: - ..code-block:: python + + .. code-block:: python io.get('temperature') """ @@ -461,9 +475,9 @@ class IO_HTTP: Client for interacting with the Adafruit IO HTTP API. https://io.adafruit.com/api/docs/#adafruit-io-http-api - :param str adafruit_io_username: Adafruit IO Username - :param str adafruit_io_key: Adafruit IO Key - :param requests: A passed adafruit_requests module. + :param str adafruit_io_username: Adafruit IO Username + :param str adafruit_io_key: Adafruit IO Key + :param requests: A passed adafruit_requests module. """ def __init__(self, adafruit_io_username, adafruit_io_key, requests): @@ -486,9 +500,9 @@ def _create_headers(io_headers): @staticmethod def _create_data(data, metadata): """Returns a data payload as expected by the Adafruit IO HTTP API + :param data: Payload value. :param dict metadata: Payload metadata. - """ payload = {"value": data} if metadata: # metadata is expected as a dict, append key/vals @@ -510,6 +524,7 @@ def _handle_error(response): def _compose_path(self, path): """Composes a valid API request path. + :param str path: Adafruit IO API URL path. """ return "https://io.adafruit.com/api/v2/{0}/{1}".format(self.username, path) @@ -518,6 +533,7 @@ def _compose_path(self, path): def _post(self, path, payload): """ POST data to Adafruit IO + :param str path: Formatted Adafruit IO URL from _compose_path :param json payload: JSON data to send to Adafruit IO """ @@ -532,6 +548,7 @@ def _post(self, path, payload): def _get(self, path): """ GET data from Adafruit IO + :param str path: Formatted Adafruit IO URL from _compose_path """ response = self._http.get( @@ -545,6 +562,7 @@ def _get(self, path): def _delete(self, path): """ DELETE data from Adafruit IO. + :param str path: Formatted Adafruit IO URL from _compose_path """ response = self._http.delete( @@ -559,6 +577,7 @@ def _delete(self, path): def send_data(self, feed_key, data, metadata=None, precision=None): """ Sends value data to a specified Adafruit IO feed. + :param str feed_key: Adafruit IO feed key :param str data: Data to send to the Adafruit IO feed :param dict metadata: Optional metadata associated with the data @@ -579,6 +598,7 @@ def send_data(self, feed_key, data, metadata=None, precision=None): def send_batch_data(self, feed_key, data_list): """ Sends a batch array of data to a specified Adafruit IO feed + :param str feed_key: Adafruit IO feed key :param list Data: Data list to send """ @@ -591,6 +611,7 @@ def receive_all_data(self, feed_key): """ Get all data values from a specified Adafruit IO feed. Data is returned in reverse order. + :param str feed_key: Adafruit IO feed key """ validate_feed_key(feed_key) @@ -600,6 +621,7 @@ def receive_all_data(self, feed_key): def receive_data(self, feed_key): """ Return the most recent value for the specified feed. + :param string feed_key: Adafruit IO feed key """ validate_feed_key(feed_key) @@ -609,6 +631,7 @@ def receive_data(self, feed_key): def delete_data(self, feed_key, data_id): """ Deletes an existing Data point from a feed. + :param string feed: Adafruit IO feed key :param string data_id: Data point to delete from the feed """ @@ -620,6 +643,7 @@ def delete_data(self, feed_key, data_id): def create_new_group(self, group_key, group_description): """ Creates a new Adafruit IO Group. + :param str group_key: Adafruit IO Group Key :param str group_description: Brief summary about the group """ @@ -630,6 +654,7 @@ def create_new_group(self, group_key, group_description): def delete_group(self, group_key): """ Deletes an existing group. + :param str group_key: Adafruit IO Group Key """ path = self._compose_path("groups/{0}".format(group_key)) @@ -638,6 +663,7 @@ def delete_group(self, group_key): def get_group(self, group_key): """ Returns Group based on Group Key + :param str group_key: Adafruit IO Group Key """ path = self._compose_path("groups/{0}".format(group_key)) @@ -645,9 +671,9 @@ def get_group(self, group_key): def create_feed_in_group(self, group_key, feed_name): """Creates a new feed in an existing group. + :param str group_key: Group name. :param str feed_name: Name of new feed. - """ path = self._compose_path("groups/{0}/feeds".format(group_key)) payload = {"feed": {"name": feed_name}} @@ -656,6 +682,7 @@ def create_feed_in_group(self, group_key, feed_name): def add_feed_to_group(self, group_key, feed_key): """ Adds an existing feed to a group + :param str group_key: Group :param str feed_key: Feed to add to the group """ @@ -668,6 +695,7 @@ def add_feed_to_group(self, group_key, feed_key): def get_feed(self, feed_key, detailed=False): """ Returns an Adafruit IO feed based on the feed key + :param str feed_key: Adafruit IO Feed Key :param bool detailed: Returns a more verbose feed record """ @@ -681,6 +709,7 @@ def get_feed(self, feed_key, detailed=False): def create_new_feed(self, feed_key, feed_desc=None, feed_license=None): """ Creates a new Adafruit IO feed. + :param str feed_key: Adafruit IO Feed Key :param str feed_desc: Optional description of feed :param str feed_license: Optional feed license @@ -695,6 +724,7 @@ def create_and_get_feed( ): """ Attempts to return a feed; if the feed does not exist, it is created, and then returned. + :param str feed_key: Adafruit IO Feed Key :param bool detailed: Returns a more verbose existing feed record :param str feed_desc: Optional description of feed to be created @@ -711,6 +741,7 @@ def create_and_get_feed( def delete_feed(self, feed_key): """ Deletes an existing feed. + :param str feed_key: Valid feed key """ validate_feed_key(feed_key) @@ -722,6 +753,7 @@ def receive_weather(self, weather_id): """ Get data from the Adafruit IO Weather Forecast Service NOTE: This service is avaliable to Adafruit IO Plus subscribers only. + :param int weather_id: ID for retrieving a specified weather record. """ path = self._compose_path("integrations/weather/{0}".format(weather_id)) @@ -730,6 +762,7 @@ def receive_weather(self, weather_id): def receive_random_data(self, generator_id): """ Get data from the Adafruit IO Random Data Stream Service + :param int generator_id: Specified randomizer record """ path = self._compose_path("integrations/words/{0}".format(generator_id)) diff --git a/docs/api.rst b/docs/api.rst index f37bb28..2e26b2f 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,5 +1,4 @@ -API ------------- + .. If you created a package, create one automodule per module in the package. .. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py) From c411841bf14c419aa258879872c57527275b5810 Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Mon, 28 Mar 2022 15:52:04 -0400 Subject: [PATCH 083/153] Update Black to latest. Signed-off-by: Kattni Rembor --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1b9fadc..7467c1d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: - repo: https://github.com/python/black - rev: 20.8b1 + rev: 22.3.0 hooks: - id: black - repo: https://github.com/fsfe/reuse-tool From fe691a8250d4c3a6e2817e03ed5734c6943ded51 Mon Sep 17 00:00:00 2001 From: Alan Grover Date: Sun, 10 Apr 2022 11:51:34 -0400 Subject: [PATCH 084/153] adafruit_io#unsubscribe(group_key=xxx) should unsubscribe thegroup key provided --- adafruit_io/adafruit_io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index ee50f25..3298d1e 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -351,7 +351,7 @@ def unsubscribe(self, feed_key=None, group_key=None, shared_user=None): self._client.unsubscribe("{0}/f/{1}".format(shared_user, feed_key)) elif group_key is not None: validate_feed_key(group_key) - self._client.unsubscribe("{0}/g/{1}".format(self._user, feed_key)) + self._client.unsubscribe("{0}/g/{1}".format(self._user, group_key)) elif feed_key is not None: validate_feed_key(feed_key) self._client.unsubscribe("{0}/f/{1}".format(self._user, feed_key)) From 427b4bbfcf829a520687fb06121de154adb11df6 Mon Sep 17 00:00:00 2001 From: Vsaggiomo Date: Mon, 18 Apr 2022 17:48:42 +0200 Subject: [PATCH 085/153] added "port" to MQTT examples --- examples/adafruit_io_mqtt/adafruit_io_feed_callback.py | 1 + examples/adafruit_io_mqtt/adafruit_io_groups.py | 1 + examples/adafruit_io_mqtt/adafruit_io_location.py | 1 + examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py | 1 + examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py | 1 + examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py | 1 + examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py | 1 + examples/adafruit_io_mqtt/adafruit_io_time.py | 1 + examples/adafruit_io_simpletest.py | 1 + 9 files changed, 9 insertions(+) diff --git a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py index 8bc36a7..7da7950 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py +++ b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py @@ -99,6 +99,7 @@ def on_battery_msg(client, topic, message): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( broker="io.adafruit.com", + port=1883, username=secrets["aio_username"], password=secrets["aio_key"], ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_groups.py b/examples/adafruit_io_mqtt/adafruit_io_groups.py index 5ed80b7..753c263 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_groups.py +++ b/examples/adafruit_io_mqtt/adafruit_io_groups.py @@ -91,6 +91,7 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( broker="io.adafruit.com", + port=1883, username=secrets["aio_username"], password=secrets["aio_key"], ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_location.py b/examples/adafruit_io_mqtt/adafruit_io_location.py index 0890fe0..894c84b 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_location.py +++ b/examples/adafruit_io_mqtt/adafruit_io_location.py @@ -90,6 +90,7 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( broker="io.adafruit.com", + port=1883, username=secrets["aio_username"], password=secrets["aio_key"], ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py index fae9b0b..440aed3 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py +++ b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py @@ -75,6 +75,7 @@ def on_led_msg(client, topic, message): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( broker="io.adafruit.com", + port=1883, username=secrets["aio_username"], password=secrets["aio_key"], ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py index f54c842..242bfe0 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py @@ -87,6 +87,7 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( broker="io.adafruit.com", + port=1883, username=secrets["aio_username"], password=secrets["aio_key"], ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py index ef9e78d..8e9b1f0 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py @@ -73,6 +73,7 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( broker="io.adafruit.com", + port=1883, username=secrets["aio_username"], password=secrets["aio_key"], socket_pool=pool, diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index 653fa79..3b656fc 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -72,6 +72,7 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( broker="io.adafruit.com", + port=1883, username=secrets["aio_username"], password=secrets["aio_key"], ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_time.py b/examples/adafruit_io_mqtt/adafruit_io_time.py index bc5ad09..7f9cfb5 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_time.py +++ b/examples/adafruit_io_mqtt/adafruit_io_time.py @@ -104,6 +104,7 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( broker="io.adafruit.com", + port=1883, username=secrets["aio_username"], password=secrets["aio_key"], ) diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index d73fe34..8810f12 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -102,6 +102,7 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( broker="io.adafruit.com", + port=1883, username=secrets["aio_username"], password=secrets["aio_key"], ) From 82a00239715ee4ebe8ed689fa0de720f2a6858f6 Mon Sep 17 00:00:00 2001 From: evaherrada Date: Thu, 21 Apr 2022 15:00:27 -0400 Subject: [PATCH 086/153] Updated gitignore Signed-off-by: evaherrada --- .gitignore | 48 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 9647e71..544ec4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,47 @@ -# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-FileCopyrightText: 2022 Kattni Rembor, written for Adafruit Industries # -# SPDX-License-Identifier: Unlicense +# SPDX-License-Identifier: MIT +# Do not include files and directories created by your personal work environment, such as the IDE +# you use, except for those already listed here. Pull requests including changes to this file will +# not be accepted. + +# This .gitignore file contains rules for files generated by working with CircuitPython libraries, +# including building Sphinx, testing with pip, and creating a virual environment, as well as the +# MacOS and IDE-specific files generated by using MacOS in general, or the PyCharm or VSCode IDEs. + +# If you find that there are files being generated on your machine that should not be included in +# your git commit, you should create a .gitignore_global file on your computer to include the +# files created by your personal setup. To do so, follow the two steps below. + +# First, create a file called .gitignore_global somewhere convenient for you, and add rules for +# the files you want to exclude from git commits. + +# Second, configure Git to use the exclude file for all Git repositories by running the +# following via commandline, replacing "path/to/your/" with the actual path to your newly created +# .gitignore_global file: +# git config --global core.excludesfile path/to/your/.gitignore_global + +# CircuitPython-specific files *.mpy -.idea + +# Python-specific files __pycache__ -_build *.pyc + +# Sphinx build-specific files +_build + +# This file results from running `pip -e install .` in a local repository +*.egg-info + +# Virtual environment-specific files .env -bundles + +# MacOS-specific files *.DS_Store -.eggs -dist -**/*.egg-info + +# IDE-specific files +.idea +.vscode +*~ From 4bd3bbc6dedd5420cd805e649f50b407c453ba91 Mon Sep 17 00:00:00 2001 From: evaherrada Date: Fri, 22 Apr 2022 15:58:16 -0400 Subject: [PATCH 087/153] Patch: Replaced discord badge image --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 8abe6db..25491b5 100644 --- a/README.rst +++ b/README.rst @@ -5,7 +5,7 @@ Adafruit_CircuitPython_AdafruitIO :target: https://docs.circuitpython.org/projects/adafruitio/en/latest/ :alt: Documentation Status -.. image:: https://img.shields.io/discord/327254708534116352.svg +.. image:: https://github.com/adafruit/Adafruit_CircuitPython_Bundle/blob/main/badges/adafruit_discord.svg :target: https://adafru.it/discord :alt: Discord From 41151d6c9be8de0a3c56c1be327e36dc5a6c37a4 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Sun, 24 Apr 2022 14:01:06 -0500 Subject: [PATCH 088/153] change discord badge --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 25491b5..662d135 100644 --- a/README.rst +++ b/README.rst @@ -5,7 +5,7 @@ Adafruit_CircuitPython_AdafruitIO :target: https://docs.circuitpython.org/projects/adafruitio/en/latest/ :alt: Documentation Status -.. image:: https://github.com/adafruit/Adafruit_CircuitPython_Bundle/blob/main/badges/adafruit_discord.svg +.. image:: https://raw.githubusercontent.com/adafruit/Adafruit_CircuitPython_Bundle/main/badges/adafruit_discord.svg :target: https://adafru.it/discord :alt: Discord From 1986e2d3dcb4d32187c0eaf6c085fc15a9d26c28 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sun, 15 May 2022 12:49:16 -0400 Subject: [PATCH 089/153] Patch .pre-commit-config.yaml --- .pre-commit-config.yaml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7467c1d..3343606 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,40 +3,40 @@ # SPDX-License-Identifier: Unlicense repos: -- repo: https://github.com/python/black + - repo: https://github.com/python/black rev: 22.3.0 hooks: - - id: black -- repo: https://github.com/fsfe/reuse-tool - rev: v0.12.1 + - id: black + - repo: https://github.com/fsfe/reuse-tool + rev: v0.14.0 hooks: - - id: reuse -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.3.0 + - id: reuse + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.2.0 hooks: - - id: check-yaml - - id: end-of-file-fixer - - id: trailing-whitespace -- repo: https://github.com/pycqa/pylint + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + - repo: https://github.com/pycqa/pylint rev: v2.11.1 hooks: - - id: pylint + - id: pylint name: pylint (library code) types: [python] args: - --disable=consider-using-f-string exclude: "^(docs/|examples/|tests/|setup.py$)" - - id: pylint + - id: pylint name: pylint (example code) description: Run pylint rules on "examples/*.py" files types: [python] files: "^examples/" args: - - --disable=missing-docstring,invalid-name,consider-using-f-string,duplicate-code - - id: pylint + - --disable=missing-docstring,invalid-name,consider-using-f-string,duplicate-code + - id: pylint name: pylint (test code) description: Run pylint rules on "tests/*.py" files types: [python] files: "^tests/" args: - - --disable=missing-docstring,consider-using-f-string,duplicate-code + - --disable=missing-docstring,consider-using-f-string,duplicate-code From ebd2d8b8f583aa07517d3c09088ad832fd156f93 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sun, 22 May 2022 00:18:55 -0400 Subject: [PATCH 090/153] Increase min lines similarity Signed-off-by: Alec Delaney --- .pylintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pylintrc b/.pylintrc index cfd1c41..f006a4a 100644 --- a/.pylintrc +++ b/.pylintrc @@ -252,7 +252,7 @@ ignore-docstrings=yes ignore-imports=yes # Minimum lines number of a similarity. -min-similarity-lines=4 +min-similarity-lines=12 [BASIC] From 8dcdf7850579692c2a1b11da947917db6fba73e2 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sun, 22 May 2022 00:18:23 -0400 Subject: [PATCH 091/153] Switch to inclusive terminology Signed-off-by: Alec Delaney --- .pylintrc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pylintrc b/.pylintrc index f006a4a..f772971 100644 --- a/.pylintrc +++ b/.pylintrc @@ -9,11 +9,11 @@ # run arbitrary code extension-pkg-whitelist= -# Add files or directories to the blacklist. They should be base names, not +# Add files or directories to the ignore-list. They should be base names, not # paths. ignore=CVS -# Add files or directories matching the regex patterns to the blacklist. The +# Add files or directories matching the regex patterns to the ignore-list. The # regex matches against base names, not paths. ignore-patterns= From 3529082e5f32f6fb41b51962a51c3c0b11bb0f5a Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Mon, 30 May 2022 14:25:04 -0400 Subject: [PATCH 092/153] Set language to "en" for documentation Signed-off-by: Alec Delaney --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 181c912..2ade8f2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -53,7 +53,7 @@ # # 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 +language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. From 4903976256ecad760792d2ea1105649cbb7f0a56 Mon Sep 17 00:00:00 2001 From: evaherrada Date: Tue, 7 Jun 2022 15:33:58 -0400 Subject: [PATCH 093/153] Added cp.org link to index.rst --- docs/index.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 2096b02..8d0b9e9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -30,7 +30,8 @@ Table of Contents .. toctree:: :caption: Other Links - Download + Download from GitHub + Download Library Bundle CircuitPython Reference Documentation CircuitPython Support Forum Discord Chat From 0c3b81e95579cef409d50282e7254d2e1509db99 Mon Sep 17 00:00:00 2001 From: Neradoc Date: Wed, 13 Jul 2022 16:01:49 +0200 Subject: [PATCH 094/153] change requirements to pypi format, remove ESP32SPI requirement --- requirements.txt | 3 +-- setup.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index ea5a0fd..4ea69c9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,5 +3,4 @@ # SPDX-License-Identifier: Unlicense Adafruit-Blinka -Adafruit_CircuitPython_ESP32SPI -Adafruit_CircuitPython_MiniMQTT +adafruit-circuitpython-minimqtt diff --git a/setup.py b/setup.py index ba6d32c..faab02f 100644 --- a/setup.py +++ b/setup.py @@ -35,8 +35,7 @@ author_email="circuitpython@adafruit.com", install_requires=[ "Adafruit-Blinka", - "Adafruit_CircuitPython_ESP32SPI", - "Adafruit-CircuitPython-MiniMQTT", + "adafruit-circuitpython-minimqtt", ], # Choose your license license="MIT", From 1888b94d3ba34dfb1a32d896d483e0d2cd6ee4a1 Mon Sep 17 00:00:00 2001 From: Neradoc Date: Wed, 13 Jul 2022 18:43:47 +0200 Subject: [PATCH 095/153] add optional requirements --- optional_requirements.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 optional_requirements.txt diff --git a/optional_requirements.txt b/optional_requirements.txt new file mode 100644 index 0000000..49562ea --- /dev/null +++ b/optional_requirements.txt @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2022 Adafruit Industries +# +# SPDX-License-Identifier: Unlicense + +adafruit-circuitpython-esp32spi From c97962baedae9706b1a0ddf2761144d9aab958d0 Mon Sep 17 00:00:00 2001 From: evaherrada Date: Fri, 22 Jul 2022 13:58:25 -0400 Subject: [PATCH 096/153] Changed .env to .venv in README.rst --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 662d135..6633cc6 100644 --- a/README.rst +++ b/README.rst @@ -48,8 +48,8 @@ To install in a virtual environment in your current project: .. code-block:: shell mkdir project-name && cd project-name - python3 -m venv .env - source .env/bin/activate + python3 -m venv .venv + source .venv/bin/activate pip3 install adafruit-circuitpython-adafruitio Usage Example From 13440ca802133a25fb96aea1502b047f97f7ae9b Mon Sep 17 00:00:00 2001 From: evaherrada Date: Tue, 2 Aug 2022 17:00:18 -0400 Subject: [PATCH 097/153] Added Black formatting badge --- README.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.rst b/README.rst index 6633cc6..68f9ed1 100644 --- a/README.rst +++ b/README.rst @@ -13,6 +13,10 @@ Adafruit_CircuitPython_AdafruitIO :target: https://github.com/adafruit/Adafruit_CircuitPython_AdafruitIO/actions/ :alt: Build Status +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + :alt: Code Style: Black + CircuitPython wrapper library for communicating with `Adafruit IO `_. From 6826df53ff35bd93bfff30b8c46b79625c52e1c8 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Mon, 8 Aug 2022 22:05:54 -0400 Subject: [PATCH 098/153] Switched to pyproject.toml --- .github/workflows/build.yml | 23 ++++++-------- .github/workflows/release.yml | 17 ++++++----- optional_requirements.txt | 4 +-- pyproject.toml | 48 +++++++++++++++++++++++++++++ requirements.txt | 2 +- setup.py | 57 ----------------------------------- 6 files changed, 70 insertions(+), 81 deletions(-) create mode 100644 pyproject.toml delete mode 100644 setup.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 140d2d9..22f6582 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,6 +47,8 @@ jobs: pip install --force-reinstall Sphinx sphinx-rtd-theme pre-commit - name: Library version run: git describe --dirty --always --tags + - name: Setup problem matchers + uses: adafruit/circuitpython-action-library-ci-problem-matchers@v1 - name: Pre-commit hooks run: | pre-commit run --all-files @@ -57,24 +59,19 @@ jobs: with: name: bundles path: ${{ github.workspace }}/bundles/ - - name: Check For docs folder - id: need-docs - run: | - echo ::set-output name=docs::$( find . -wholename './docs' ) - name: Build docs - if: contains(steps.need-docs.outputs.docs, 'docs') working-directory: docs run: sphinx-build -E -W -b html . _build/html - - name: Check For setup.py + - name: Check For pyproject.toml id: need-pypi run: | - echo ::set-output name=setup-py::$( find . -wholename './setup.py' ) + echo ::set-output name=pyproject-toml::$( find . -wholename './pyproject.toml' ) - name: Build Python package - if: contains(steps.need-pypi.outputs.setup-py, 'setup.py') + if: contains(steps.need-pypi.outputs.pyproject-toml, 'pyproject.toml') run: | - pip install --upgrade setuptools wheel twine readme_renderer testresources - python setup.py sdist - python setup.py bdist_wheel --universal + pip install --upgrade build twine + for file in $(find -not -path "./.*" -not -path "./docs*" \( -name "*.py" -o -name "*.toml" \) ); do + sed -i -e "s/0.0.0-auto.0/1.2.3/" $file; + done; + python -m build twine check dist/* - - name: Setup problem matchers - uses: adafruit/circuitpython-action-library-ci-problem-matchers@v1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a65e5de..d1b4f8d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -61,25 +61,28 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - - name: Check For setup.py + - name: Check For pyproject.toml id: need-pypi run: | - echo ::set-output name=setup-py::$( find . -wholename './setup.py' ) + echo ::set-output name=pyproject-toml::$( find . -wholename './pyproject.toml' ) - name: Set up Python - if: contains(steps.need-pypi.outputs.setup-py, 'setup.py') + if: contains(steps.need-pypi.outputs.pyproject-toml, 'pyproject.toml') uses: actions/setup-python@v2 with: python-version: '3.x' - name: Install dependencies - if: contains(steps.need-pypi.outputs.setup-py, 'setup.py') + if: contains(steps.need-pypi.outputs.pyproject-toml, 'pyproject.toml') run: | python -m pip install --upgrade pip - pip install setuptools wheel twine + pip install --upgrade build twine - name: Build and publish - if: contains(steps.need-pypi.outputs.setup-py, 'setup.py') + if: contains(steps.need-pypi.outputs.pyproject-toml, 'pyproject.toml') env: TWINE_USERNAME: ${{ secrets.pypi_username }} TWINE_PASSWORD: ${{ secrets.pypi_password }} run: | - python setup.py sdist + for file in $(find -not -path "./.*" -not -path "./docs*" \( -name "*.py" -o -name "*.toml" \) ); do + sed -i -e "s/0.0.0-auto.0/${{github.event.release.tag_name}}/" $file; + done; + python -m build twine upload dist/* diff --git a/optional_requirements.txt b/optional_requirements.txt index 49562ea..d4e27c4 100644 --- a/optional_requirements.txt +++ b/optional_requirements.txt @@ -1,5 +1,3 @@ -# SPDX-FileCopyrightText: 2022 Adafruit Industries +# SPDX-FileCopyrightText: 2022 Alec Delaney, for Adafruit Industries # # SPDX-License-Identifier: Unlicense - -adafruit-circuitpython-esp32spi diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e15b3b5 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,48 @@ +# SPDX-FileCopyrightText: 2022 Alec Delaney for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +[build-system] +requires = [ + "setuptools", + "wheel", +] + +[project] +name = "adafruit-circuitpython-adafruitio" +description = "Adafruit IO for CircuitPython" +version = "0.0.0-auto.0" +readme = "README.rst" +authors = [ + {name = "Adafruit Industries", email = "circuitpython@adafruit.com"} +] +urls = {Homepage = "https://github.com/adafruit/Adafruit_CircuitPython_AdafruitIO"} +keywords = [ + "adafruit", + "blinka", + "circuitpython", + "micropython", + "adafruit_io", + "adafruit-io", + "rest", + "api", + "iot", + "wifi", +] +license = {text = "MIT"} +classifiers = [ + "Intended Audience :: Developers", + "Topic :: Software Development :: Libraries", + "Topic :: Software Development :: Embedded Systems", + "Topic :: System :: Hardware", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", +] +dynamic = ["dependencies", "optional-dependencies"] + +[tool.setuptools] +packages = ["adafruit_io"] + +[tool.setuptools.dynamic] +dependencies = {file = ["requirements.txt"]} +optional-dependencies = {optional = {file = ["optional_requirements.txt"]}} diff --git a/requirements.txt b/requirements.txt index 4ea69c9..e743893 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-FileCopyrightText: 2022 Alec Delaney, for Adafruit Industries # # SPDX-License-Identifier: Unlicense diff --git a/setup.py b/setup.py deleted file mode 100644 index faab02f..0000000 --- a/setup.py +++ /dev/null @@ -1,57 +0,0 @@ -# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries -# -# SPDX-License-Identifier: MIT - -"""A setuptools based setup module. - -See: -https://packaging.python.org/en/latest/distributing.html -https://github.com/pypa/sampleproject -""" - -from setuptools import setup, find_packages - -# To use a consistent encoding -from codecs import open -from os import path - -here = path.abspath(path.dirname(__file__)) - -# Get the long description from the README file -with open(path.join(here, "README.rst"), encoding="utf-8") as f: - long_description = f.read() - -setup( - name="adafruit-circuitpython-adafruitio", - use_scm_version=True, - setup_requires=["setuptools_scm"], - description="Adafruit IO for CircuitPython", - long_description=long_description, - long_description_content_type="text/x-rst", - # The project's main homepage. - url="https://github.com/adafruit/Adafruit_CircuitPython_AdafruitIO", - # Author details - author="Adafruit Industries", - author_email="circuitpython@adafruit.com", - install_requires=[ - "Adafruit-Blinka", - "adafruit-circuitpython-minimqtt", - ], - # Choose your license - license="MIT", - # See https://pypi.python.org/pypi?%3Aaction=list_classifiers - classifiers=[ - "Development Status :: 3 - Alpha", - "Intended Audience :: Developers", - "Topic :: Software Development :: Libraries", - "Topic :: System :: Hardware", - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3", - ], - # What does your project relate to? - keywords="adafruit blinka circuitpython micropython adafruit_io adafruit-io rest api iot " - "wifi", - # You can just specify the packages manually here if your project is - # simple. Or you can use find_packages(). - packages=["adafruit_io"], -) From fbb641eca7a2b055d0198ddbd32c55092b783492 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Tue, 9 Aug 2022 12:03:54 -0400 Subject: [PATCH 099/153] Add setuptools-scm to build system requirements Signed-off-by: Alec Delaney --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index e15b3b5..289be56 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,7 @@ requires = [ "setuptools", "wheel", + "setuptools-scm", ] [project] From aabde4ec07af0d18d1dda59723d63e0ac9f4f725 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Tue, 16 Aug 2022 18:09:15 -0400 Subject: [PATCH 100/153] Update version string --- adafruit_io/adafruit_io.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 3298d1e..03adf86 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -29,7 +29,7 @@ AdafruitIO_MQTTError, ) -__version__ = "0.0.0-auto.0" +__version__ = "0.0.0+auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_AdafruitIO.git" CLIENT_HEADERS = {"User-Agent": "AIO-CircuitPython/{0}".format(__version__)} diff --git a/pyproject.toml b/pyproject.toml index 289be56..6c2b9ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ requires = [ [project] name = "adafruit-circuitpython-adafruitio" description = "Adafruit IO for CircuitPython" -version = "0.0.0-auto.0" +version = "0.0.0+auto.0" readme = "README.rst" authors = [ {name = "Adafruit Industries", email = "circuitpython@adafruit.com"} From 42b0dd67c34ce95b1c7927d8a125ba3ab02e1788 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Tue, 16 Aug 2022 21:09:14 -0400 Subject: [PATCH 101/153] Fix version strings in workflow files --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 22f6582..cb2f60e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -71,7 +71,7 @@ jobs: run: | pip install --upgrade build twine for file in $(find -not -path "./.*" -not -path "./docs*" \( -name "*.py" -o -name "*.toml" \) ); do - sed -i -e "s/0.0.0-auto.0/1.2.3/" $file; + sed -i -e "s/0.0.0+auto.0/1.2.3/" $file; done; python -m build twine check dist/* diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d1b4f8d..f3a0325 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -82,7 +82,7 @@ jobs: TWINE_PASSWORD: ${{ secrets.pypi_password }} run: | for file in $(find -not -path "./.*" -not -path "./docs*" \( -name "*.py" -o -name "*.toml" \) ); do - sed -i -e "s/0.0.0-auto.0/${{github.event.release.tag_name}}/" $file; + sed -i -e "s/0.0.0+auto.0/${{github.event.release.tag_name}}/" $file; done; python -m build twine upload dist/* From 784a8a2af168062a7977c93f0d6133c2ec284afb Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Mon, 22 Aug 2022 21:36:32 -0400 Subject: [PATCH 102/153] Keep copyright up to date in documentation --- docs/conf.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 2ade8f2..78b6f0a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -6,6 +6,7 @@ import os import sys +import datetime sys.path.insert(0, os.path.abspath("..")) @@ -36,7 +37,8 @@ # General information about the project. project = "Adafruit Adafruit_IO Library" -copyright = "2019 Brent Rubell" +current_year = str(datetime.datetime.now().year) +copyright = current_year + " Brent Rubell" author = "Brent Rubell" # The version info for the project you're documenting, acts as replacement for From df54548a3799eed34880563e96307d6f934fd7f1 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Tue, 23 Aug 2022 17:26:22 -0400 Subject: [PATCH 103/153] Use year duration range for copyright attribution --- docs/conf.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 78b6f0a..91f0b1e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -37,8 +37,14 @@ # General information about the project. project = "Adafruit Adafruit_IO Library" +creation_year = "2019" current_year = str(datetime.datetime.now().year) -copyright = current_year + " Brent Rubell" +year_duration = ( + current_year + if current_year == creation_year + else creation_year + " - " + current_year +) +copyright = year_duration + " Brent Rubell" author = "Brent Rubell" # The version info for the project you're documenting, acts as replacement for From aaa95a04ef44ad9b2eb88b04b8f4ec3f5439f678 Mon Sep 17 00:00:00 2001 From: Alec Delaney <89490472+tekktrik@users.noreply.github.com> Date: Fri, 4 Nov 2022 00:02:50 -0400 Subject: [PATCH 104/153] Switching to composite actions --- .github/workflows/build.yml | 67 +---------------------- .github/workflows/release.yml | 88 ------------------------------ .github/workflows/release_gh.yml | 14 +++++ .github/workflows/release_pypi.yml | 14 +++++ 4 files changed, 30 insertions(+), 153 deletions(-) delete mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/release_gh.yml create mode 100644 .github/workflows/release_pypi.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cb2f60e..041a337 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,68 +10,5 @@ jobs: test: runs-on: ubuntu-latest steps: - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJson(github) }} - run: echo "$GITHUB_CONTEXT" - - name: Translate Repo Name For Build Tools filename_prefix - id: repo-name - run: | - echo ::set-output name=repo-name::$( - echo ${{ github.repository }} | - awk -F '\/' '{ print tolower($2) }' | - tr '_' '-' - ) - - name: Set up Python 3.x - uses: actions/setup-python@v2 - with: - python-version: "3.x" - - name: Versions - run: | - python3 --version - - name: Checkout Current Repo - uses: actions/checkout@v1 - with: - submodules: true - - name: Checkout tools repo - uses: actions/checkout@v2 - with: - repository: adafruit/actions-ci-circuitpython-libs - path: actions-ci - - name: Install dependencies - # (e.g. - apt-get: gettext, etc; pip: circuitpython-build-tools, requirements.txt; etc.) - run: | - source actions-ci/install.sh - - name: Pip install Sphinx, pre-commit - run: | - pip install --force-reinstall Sphinx sphinx-rtd-theme pre-commit - - name: Library version - run: git describe --dirty --always --tags - - name: Setup problem matchers - uses: adafruit/circuitpython-action-library-ci-problem-matchers@v1 - - name: Pre-commit hooks - run: | - pre-commit run --all-files - - name: Build assets - run: circuitpython-build-bundles --filename_prefix ${{ steps.repo-name.outputs.repo-name }} --library_location . - - name: Archive bundles - uses: actions/upload-artifact@v2 - with: - name: bundles - path: ${{ github.workspace }}/bundles/ - - name: Build docs - working-directory: docs - run: sphinx-build -E -W -b html . _build/html - - name: Check For pyproject.toml - id: need-pypi - run: | - echo ::set-output name=pyproject-toml::$( find . -wholename './pyproject.toml' ) - - name: Build Python package - if: contains(steps.need-pypi.outputs.pyproject-toml, 'pyproject.toml') - run: | - pip install --upgrade build twine - for file in $(find -not -path "./.*" -not -path "./docs*" \( -name "*.py" -o -name "*.toml" \) ); do - sed -i -e "s/0.0.0+auto.0/1.2.3/" $file; - done; - python -m build - twine check dist/* + - name: Run Build CI workflow + uses: adafruit/workflows-circuitpython-libs/build@main diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index f3a0325..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,88 +0,0 @@ -# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries -# -# SPDX-License-Identifier: MIT - -name: Release Actions - -on: - release: - types: [published] - -jobs: - upload-release-assets: - runs-on: ubuntu-latest - steps: - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJson(github) }} - run: echo "$GITHUB_CONTEXT" - - name: Translate Repo Name For Build Tools filename_prefix - id: repo-name - run: | - echo ::set-output name=repo-name::$( - echo ${{ github.repository }} | - awk -F '\/' '{ print tolower($2) }' | - tr '_' '-' - ) - - name: Set up Python 3.x - uses: actions/setup-python@v2 - with: - python-version: "3.x" - - name: Versions - run: | - python3 --version - - name: Checkout Current Repo - uses: actions/checkout@v1 - with: - submodules: true - - name: Checkout tools repo - uses: actions/checkout@v2 - with: - repository: adafruit/actions-ci-circuitpython-libs - path: actions-ci - - name: Install deps - run: | - source actions-ci/install.sh - - name: Build assets - run: circuitpython-build-bundles --filename_prefix ${{ steps.repo-name.outputs.repo-name }} --library_location . - - name: Upload Release Assets - # the 'official' actions version does not yet support dynamically - # supplying asset names to upload. @csexton's version chosen based on - # discussion in the issue below, as its the simplest to implement and - # allows for selecting files with a pattern. - # https://github.com/actions/upload-release-asset/issues/4 - #uses: actions/upload-release-asset@v1.0.1 - uses: csexton/release-asset-action@master - with: - pattern: "bundles/*" - github-token: ${{ secrets.GITHUB_TOKEN }} - - upload-pypi: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Check For pyproject.toml - id: need-pypi - run: | - echo ::set-output name=pyproject-toml::$( find . -wholename './pyproject.toml' ) - - name: Set up Python - if: contains(steps.need-pypi.outputs.pyproject-toml, 'pyproject.toml') - uses: actions/setup-python@v2 - with: - python-version: '3.x' - - name: Install dependencies - if: contains(steps.need-pypi.outputs.pyproject-toml, 'pyproject.toml') - run: | - python -m pip install --upgrade pip - pip install --upgrade build twine - - name: Build and publish - if: contains(steps.need-pypi.outputs.pyproject-toml, 'pyproject.toml') - env: - TWINE_USERNAME: ${{ secrets.pypi_username }} - TWINE_PASSWORD: ${{ secrets.pypi_password }} - run: | - for file in $(find -not -path "./.*" -not -path "./docs*" \( -name "*.py" -o -name "*.toml" \) ); do - sed -i -e "s/0.0.0+auto.0/${{github.event.release.tag_name}}/" $file; - done; - python -m build - twine upload dist/* diff --git a/.github/workflows/release_gh.yml b/.github/workflows/release_gh.yml new file mode 100644 index 0000000..041a337 --- /dev/null +++ b/.github/workflows/release_gh.yml @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +name: Build CI + +on: [pull_request, push] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Run Build CI workflow + uses: adafruit/workflows-circuitpython-libs/build@main diff --git a/.github/workflows/release_pypi.yml b/.github/workflows/release_pypi.yml new file mode 100644 index 0000000..041a337 --- /dev/null +++ b/.github/workflows/release_pypi.yml @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +name: Build CI + +on: [pull_request, push] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Run Build CI workflow + uses: adafruit/workflows-circuitpython-libs/build@main From f28d46fd8abe1444abdd557edae81ae23dd73b75 Mon Sep 17 00:00:00 2001 From: Alec Delaney <89490472+tekktrik@users.noreply.github.com> Date: Fri, 4 Nov 2022 00:47:00 -0400 Subject: [PATCH 105/153] Updated pylint version to 2.13.0 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3343606..4c43710 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/pycqa/pylint - rev: v2.11.1 + rev: v2.13.0 hooks: - id: pylint name: pylint (library code) From 202a77fa928cc004c042b3750064b305c0b4fadd Mon Sep 17 00:00:00 2001 From: Alec Delaney <89490472+tekktrik@users.noreply.github.com> Date: Fri, 4 Nov 2022 08:15:20 -0400 Subject: [PATCH 106/153] Update pylint to 2.15.5 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4c43710..0e5fccc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/pycqa/pylint - rev: v2.13.0 + rev: v2.15.5 hooks: - id: pylint name: pylint (library code) From 105b26dd7d08c7907ef2048ad2cf00b276b39a91 Mon Sep 17 00:00:00 2001 From: Alec Delaney <89490472+tekktrik@users.noreply.github.com> Date: Fri, 4 Nov 2022 09:12:45 -0400 Subject: [PATCH 107/153] Fix release CI files --- .github/workflows/release_gh.yml | 14 +++++++++----- .github/workflows/release_pypi.yml | 15 ++++++++++----- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release_gh.yml b/.github/workflows/release_gh.yml index 041a337..b8aa8d6 100644 --- a/.github/workflows/release_gh.yml +++ b/.github/workflows/release_gh.yml @@ -2,13 +2,17 @@ # # SPDX-License-Identifier: MIT -name: Build CI +name: GitHub Release Actions -on: [pull_request, push] +on: + release: + types: [published] jobs: - test: + upload-release-assets: runs-on: ubuntu-latest steps: - - name: Run Build CI workflow - uses: adafruit/workflows-circuitpython-libs/build@main + - name: Run GitHub Release CI workflow + uses: adafruit/workflows-circuitpython-libs/release-gh@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release_pypi.yml b/.github/workflows/release_pypi.yml index 041a337..65775b7 100644 --- a/.github/workflows/release_pypi.yml +++ b/.github/workflows/release_pypi.yml @@ -2,13 +2,18 @@ # # SPDX-License-Identifier: MIT -name: Build CI +name: PyPI Release Actions -on: [pull_request, push] +on: + release: + types: [published] jobs: - test: + upload-release-assets: runs-on: ubuntu-latest steps: - - name: Run Build CI workflow - uses: adafruit/workflows-circuitpython-libs/build@main + - name: Run PyPI Release CI workflow + uses: adafruit/workflows-circuitpython-libs/release-pypi@main + with: + pypi-username: ${{ secrets.pypi_username }} + pypi-password: ${{ secrets.pypi_password }} From 0e6a19d362bfcfe61216f8f61e42334457eb76b6 Mon Sep 17 00:00:00 2001 From: Alec Delaney <89490472+tekktrik@users.noreply.github.com> Date: Fri, 4 Nov 2022 18:34:33 -0400 Subject: [PATCH 108/153] Update .pylintrc for v2.15.5 --- .pylintrc | 45 ++++----------------------------------------- 1 file changed, 4 insertions(+), 41 deletions(-) diff --git a/.pylintrc b/.pylintrc index f772971..40208c3 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries +# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries # # SPDX-License-Identifier: Unlicense @@ -26,7 +26,7 @@ jobs=1 # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. -load-plugins= +load-plugins=pylint.extensions.no_self_use # Pickle collected data for later comparisons. persistent=yes @@ -54,8 +54,8 @@ confidence= # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" -# disable=import-error,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call -disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,bad-continuation,unspecified-encoding +# disable=import-error,raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,deprecated-str-translate-call +disable=raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,import-error,pointless-string-statement,unspecified-encoding # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option @@ -225,12 +225,6 @@ max-line-length=100 # Maximum number of lines in a module max-module-lines=1000 -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma,dict-separator - # Allow the body of a class to be on the same line as the declaration if body # contains single statement. single-line-class-stmt=no @@ -257,38 +251,22 @@ min-similarity-lines=12 [BASIC] -# Naming hint for argument names -argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - # Regular expression matching correct argument names argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ -# Naming hint for attribute names -attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - # Regular expression matching correct attribute names attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ # Bad variable names which should always be refused, separated by a comma bad-names=foo,bar,baz,toto,tutu,tata -# Naming hint for class attribute names -class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - # Regular expression matching correct class attribute names class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ -# Naming hint for class names -# class-name-hint=[A-Z_][a-zA-Z0-9]+$ -class-name-hint=[A-Z_][a-zA-Z0-9_]+$ - # Regular expression matching correct class names # class-rgx=[A-Z_][a-zA-Z0-9]+$ class-rgx=[A-Z_][a-zA-Z0-9_]+$ -# Naming hint for constant names -const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - # Regular expression matching correct constant names const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ @@ -296,9 +274,6 @@ const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ # ones are exempt. docstring-min-length=-1 -# Naming hint for function names -function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - # Regular expression matching correct function names function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ @@ -309,21 +284,12 @@ good-names=r,g,b,w,i,j,k,n,x,y,z,ex,ok,Run,_ # Include a hint for the correct naming format with invalid-name include-naming-hint=no -# Naming hint for inline iteration names -inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ - # Regular expression matching correct inline iteration names inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ -# Naming hint for method names -method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - # Regular expression matching correct method names method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ -# Naming hint for module names -module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - # Regular expression matching correct module names module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ @@ -339,9 +305,6 @@ no-docstring-rgx=^_ # to this list to register other decorators that produce valid properties. property-classes=abc.abstractproperty -# Naming hint for variable names -variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - # Regular expression matching correct variable names variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ From e501acc63ff796dbb2e38d8f1a73552575480c40 Mon Sep 17 00:00:00 2001 From: Alec Delaney <89490472+tekktrik@users.noreply.github.com> Date: Thu, 1 Sep 2022 20:16:31 -0400 Subject: [PATCH 109/153] Add .venv to .gitignore Signed-off-by: Alec Delaney <89490472+tekktrik@users.noreply.github.com> --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 544ec4a..db3d538 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ _build # Virtual environment-specific files .env +.venv # MacOS-specific files *.DS_Store From 52d17fd0068c1fdd1f0d54635a9d4e795c1af274 Mon Sep 17 00:00:00 2001 From: Alec Delaney <89490472+tekktrik@users.noreply.github.com> Date: Thu, 19 Jan 2023 23:39:55 -0500 Subject: [PATCH 110/153] Add upload url to release action Signed-off-by: Alec Delaney <89490472+tekktrik@users.noreply.github.com> --- .github/workflows/release_gh.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release_gh.yml b/.github/workflows/release_gh.yml index b8aa8d6..9acec60 100644 --- a/.github/workflows/release_gh.yml +++ b/.github/workflows/release_gh.yml @@ -16,3 +16,4 @@ jobs: uses: adafruit/workflows-circuitpython-libs/release-gh@main with: github-token: ${{ secrets.GITHUB_TOKEN }} + upload-url: ${{ github.event.release.upload_url }} From 04d1a68d27e6904337fa19559babfe0b79ca6374 Mon Sep 17 00:00:00 2001 From: Mahe Iram Khan Date: Mon, 24 Apr 2023 11:15:35 -0600 Subject: [PATCH 111/153] add type hints --- adafruit_io/adafruit_io.py | 61 +++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 03adf86..eb19a18 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -22,6 +22,11 @@ import json import re +try: + from typing import List, Tuple, Any +except ImportError: + pass + from adafruit_minimqtt.adafruit_minimqtt import MMQTTException from adafruit_io.adafruit_io_errors import ( AdafruitIO_RequestError, @@ -35,7 +40,7 @@ CLIENT_HEADERS = {"User-Agent": "AIO-CircuitPython/{0}".format(__version__)} -def validate_feed_key(feed_key): +def validate_feed_key(feed_key: str): """Validates a provided feed key against Adafruit IO's system rules. https://learn.adafruit.com/naming-things-in-adafruit-io/the-two-feed-identifiers """ @@ -143,7 +148,7 @@ def _on_disconnect_mqtt(self, client, userdata, return_code): self.on_disconnect(self) # pylint: disable=not-callable - def _on_message_mqtt(self, client, topic, payload): + def _on_message_mqtt(self, client, topic: str, payload: str): """Runs when the client calls on_message. Parses and returns incoming data from Adafruit IO feeds. @@ -195,7 +200,7 @@ def _on_unsubscribe_mqtt(self, client, user_data, topic, pid): if self.on_unsubscribe is not None: self.on_unsubscribe(self, user_data, topic, pid) - def add_feed_callback(self, feed_key, callback_method): + def add_feed_callback(self, feed_key: str, callback_method: str): """Attaches a callback_method to an Adafruit IO feed. The callback_method function is called when a new value is written to the feed. @@ -211,7 +216,7 @@ def add_feed_callback(self, feed_key, callback_method): "{0}/f/{1}".format(self._user, feed_key), callback_method ) - def remove_feed_callback(self, feed_key): + def remove_feed_callback(self, feed_key: str): """Removes a previously registered callback method from executing whenever feed_key receives new data. @@ -239,7 +244,7 @@ def loop(self, timeout=1): self._client.loop(timeout) # Subscriptions - def subscribe(self, feed_key=None, group_key=None, shared_user=None): + def subscribe(self, feed_key: str=None, group_key: str=None, shared_user: str=None): """Subscribes to your Adafruit IO feed or group. Can also subscribe to someone else's feed. @@ -387,7 +392,7 @@ def publish_multiple(self, feeds_and_data, timeout=3, is_group=False): time.sleep(timeout) # pylint: disable=too-many-arguments - def publish(self, feed_key, data, metadata=None, shared_user=None, is_group=False): + def publish(self, feed_key: str, data: Any, metadata: str=None, shared_use: str=None, is_group: bool=False): """Publishes to an An Adafruit IO Feed. :param str feed_key: Adafruit IO Feed key. @@ -453,7 +458,7 @@ def publish(self, feed_key, data, metadata=None, shared_user=None, is_group=Fals else: self._client.publish("{0}/f/{1}".format(self._user, feed_key), data) - def get(self, feed_key): + def get(self, feed_key: str): """Calling this method will make Adafruit IO publish the most recent value on feed_key. https://io.adafruit.com/api/docs/mqtt.html#retained-values @@ -498,7 +503,7 @@ def _create_headers(io_headers): return headers @staticmethod - def _create_data(data, metadata): + def _create_data(data, metadata: dict): """Returns a data payload as expected by the Adafruit IO HTTP API :param data: Payload value. @@ -522,7 +527,7 @@ def _handle_error(response): if response.status_code >= 400: raise AdafruitIO_RequestError(response) - def _compose_path(self, path): + def _compose_path(self, path: str): """Composes a valid API request path. :param str path: Adafruit IO API URL path. @@ -530,7 +535,7 @@ def _compose_path(self, path): return "https://io.adafruit.com/api/v2/{0}/{1}".format(self.username, path) # HTTP Requests - def _post(self, path, payload): + def _post(self, path: str, payload: json): """ POST data to Adafruit IO @@ -545,7 +550,7 @@ def _post(self, path, payload): response.close() return json_data - def _get(self, path): + def _get(self, path: str): """ GET data from Adafruit IO @@ -559,7 +564,7 @@ def _get(self, path): response.close() return json_data - def _delete(self, path): + def _delete(self, path: str): """ DELETE data from Adafruit IO. @@ -574,7 +579,7 @@ def _delete(self, path): return json_data # Data - def send_data(self, feed_key, data, metadata=None, precision=None): + def send_data(self, feed_key: str, data: str, metadata: dict=None, precision: int=None): """ Sends value data to a specified Adafruit IO feed. @@ -595,7 +600,7 @@ def send_data(self, feed_key, data, metadata=None, precision=None): payload = self._create_data(data, metadata) self._post(path, payload) - def send_batch_data(self, feed_key, data_list): + def send_batch_data(self, feed_key: str, data_list: list): """ Sends a batch array of data to a specified Adafruit IO feed @@ -607,7 +612,7 @@ def send_batch_data(self, feed_key, data_list): data_dict = type(data_list)((data._asdict() for data in data_list)) self._post(path, {"data": data_dict}) - def receive_all_data(self, feed_key): + def receive_all_data(self, feed_key: str): """ Get all data values from a specified Adafruit IO feed. Data is returned in reverse order. @@ -618,7 +623,7 @@ def receive_all_data(self, feed_key): path = self._compose_path("feeds/{0}/data".format(feed_key)) return self._get(path) - def receive_data(self, feed_key): + def receive_data(self, feed_key: str): """ Return the most recent value for the specified feed. @@ -628,7 +633,7 @@ def receive_data(self, feed_key): path = self._compose_path("feeds/{0}/data/last".format(feed_key)) return self._get(path) - def delete_data(self, feed_key, data_id): + def delete_data(self, feed_key: str, data_id: str): """ Deletes an existing Data point from a feed. @@ -640,7 +645,7 @@ def delete_data(self, feed_key, data_id): return self._delete(path) # Groups - def create_new_group(self, group_key, group_description): + def create_new_group(self, group_key:str , group_description: str): """ Creates a new Adafruit IO Group. @@ -651,7 +656,7 @@ def create_new_group(self, group_key, group_description): payload = {"name": group_key, "description": group_description} return self._post(path, payload) - def delete_group(self, group_key): + def delete_group(self, group_key: str): """ Deletes an existing group. @@ -660,7 +665,7 @@ def delete_group(self, group_key): path = self._compose_path("groups/{0}".format(group_key)) return self._delete(path) - def get_group(self, group_key): + def get_group(self, group_key: str): """ Returns Group based on Group Key @@ -669,7 +674,7 @@ def get_group(self, group_key): path = self._compose_path("groups/{0}".format(group_key)) return self._get(path) - def create_feed_in_group(self, group_key, feed_name): + def create_feed_in_group(self, group_key: str, feed_name: str): """Creates a new feed in an existing group. :param str group_key: Group name. @@ -679,7 +684,7 @@ def create_feed_in_group(self, group_key, feed_name): payload = {"feed": {"name": feed_name}} return self._post(path, payload) - def add_feed_to_group(self, group_key, feed_key): + def add_feed_to_group(self, group_key: str, feed_key: str): """ Adds an existing feed to a group @@ -692,7 +697,7 @@ def add_feed_to_group(self, group_key, feed_key): return self._post(path, payload) # Feeds - def get_feed(self, feed_key, detailed=False): + def get_feed(self, feed_key: str, detailed: bool=False): """ Returns an Adafruit IO feed based on the feed key @@ -706,7 +711,7 @@ def get_feed(self, feed_key, detailed=False): path = self._compose_path("feeds/{0}".format(feed_key)) return self._get(path) - def create_new_feed(self, feed_key, feed_desc=None, feed_license=None): + def create_new_feed(self, feed_key: str, feed_desc: str=None, feed_license: str=None): """ Creates a new Adafruit IO feed. @@ -720,7 +725,7 @@ def create_new_feed(self, feed_key, feed_desc=None, feed_license=None): return self._post(path, payload) def create_and_get_feed( - self, feed_key, detailed=False, feed_desc=None, feed_license=None + self, feed_key: str, detailed: bool=False, feed_desc: str=None, feed_license: str=None ): """ Attempts to return a feed; if the feed does not exist, it is created, and then returned. @@ -738,7 +743,7 @@ def create_and_get_feed( ) return self.get_feed(feed_key, detailed=detailed) - def delete_feed(self, feed_key): + def delete_feed(self, feed_key: str): """ Deletes an existing feed. @@ -749,7 +754,7 @@ def delete_feed(self, feed_key): return self._delete(path) # Adafruit IO Connected Services - def receive_weather(self, weather_id): + def receive_weather(self, weather_id: int): """ Get data from the Adafruit IO Weather Forecast Service NOTE: This service is avaliable to Adafruit IO Plus subscribers only. @@ -759,7 +764,7 @@ def receive_weather(self, weather_id): path = self._compose_path("integrations/weather/{0}".format(weather_id)) return self._get(path) - def receive_random_data(self, generator_id): + def receive_random_data(self, generator_id: int): """ Get data from the Adafruit IO Random Data Stream Service From a03f98f51f190ffb7147948003e0005b2fe842a4 Mon Sep 17 00:00:00 2001 From: Mahe Iram Khan Date: Mon, 24 Apr 2023 11:24:44 -0600 Subject: [PATCH 112/153] re-add tuple and add more typehints --- adafruit_io/adafruit_io.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index eb19a18..6bd3aa4 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -289,7 +289,7 @@ def subscribe_to_errors(self): """ self._client.subscribe("%s/errors" % self._user) - def subscribe_to_randomizer(self, randomizer_id): + def subscribe_to_randomizer(self, randomizer_id: int): """Subscribes to a random data stream created by the Adafruit IO Words service. :param int randomizer_id: Random word record you want data for. @@ -298,7 +298,7 @@ def subscribe_to_randomizer(self, randomizer_id): "{0}/integration/words/{1}".format(self._user, randomizer_id) ) - def subscribe_to_weather(self, weather_record, forecast): + def subscribe_to_weather(self, weather_record: int, forecast: str): """Subscribes to a weather forecast using the Adafruit IO PLUS weather service. This feature is only avaliable to Adafruit IO PLUS subscribers. @@ -324,7 +324,7 @@ def subscribe_to_time(self, time_type): else: self._client.subscribe("time/" + time_type) - def unsubscribe(self, feed_key=None, group_key=None, shared_user=None): + def unsubscribe(self, feed_key: str=None, group_key: str=None, shared_user: str=None): """Unsubscribes from an Adafruit IO feed or group. Can also subscribe to someone else's feed. @@ -364,11 +364,11 @@ def unsubscribe(self, feed_key=None, group_key=None, shared_user=None): raise AdafruitIO_MQTTError("Must provide a feed_key or group_key.") # Publishing - def publish_multiple(self, feeds_and_data, timeout=3, is_group=False): + def publish_multiple(self, feeds_and_data: List, timeout: int=3, is_group: bool=False): """Publishes multiple data points to multiple feeds or groups with a variable timeout. - :param str feeds_and_data: List of tuples containing topic strings and data values. + :param list feeds_and_data: List of tuples containing topic strings and data values. :param int timeout: Delay between publishing data points to Adafruit IO, in seconds. :param bool is_group: Set to True if you're publishing to a group. From 156147d522144ee41266b3388fae1f809bb9e86f Mon Sep 17 00:00:00 2001 From: Mudassir Chapra <37051110+muddi900@users.noreply.github.com> Date: Sun, 7 May 2023 04:10:21 +0000 Subject: [PATCH 113/153] Added with statement for requests[Issue #100] --- adafruit_io/adafruit_io.py | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 03adf86..c40b018 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -537,12 +537,12 @@ def _post(self, path, payload): :param str path: Formatted Adafruit IO URL from _compose_path :param json payload: JSON data to send to Adafruit IO """ - response = self._http.post( + with self._http.post( path, json=payload, headers=self._create_headers(self._aio_headers[0]) - ) - self._handle_error(response) - json_data = response.json() - response.close() + ) as response: + self._handle_error(response) + json_data = response.json() + return json_data def _get(self, path): @@ -551,12 +551,11 @@ def _get(self, path): :param str path: Formatted Adafruit IO URL from _compose_path """ - response = self._http.get( + with self._http.get( path, headers=self._create_headers(self._aio_headers[1]) - ) - self._handle_error(response) - json_data = response.json() - response.close() + ) as response: + self._handle_error(response) + json_data = response.json() return json_data def _delete(self, path): @@ -565,12 +564,12 @@ def _delete(self, path): :param str path: Formatted Adafruit IO URL from _compose_path """ - response = self._http.delete( + with self._http.delete( path, headers=self._create_headers(self._aio_headers[0]) - ) - self._handle_error(response) - json_data = response.json() - response.close() + ) as response: + self._handle_error(response) + json_data = response.json() + return json_data # Data From 5d56fb54c7972681f93085483b2dd126f90f1fdf Mon Sep 17 00:00:00 2001 From: Tekktrik Date: Tue, 9 May 2023 20:26:25 -0400 Subject: [PATCH 114/153] Update pre-commit hooks Signed-off-by: Tekktrik --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0e5fccc..70ade69 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,21 +4,21 @@ repos: - repo: https://github.com/python/black - rev: 22.3.0 + rev: 23.3.0 hooks: - id: black - repo: https://github.com/fsfe/reuse-tool - rev: v0.14.0 + rev: v1.1.2 hooks: - id: reuse - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 + rev: v4.4.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/pycqa/pylint - rev: v2.15.5 + rev: v2.17.4 hooks: - id: pylint name: pylint (library code) From cdaf615284120a605d23ae6c48b2dfb23266e4fc Mon Sep 17 00:00:00 2001 From: Tekktrik Date: Wed, 10 May 2023 22:22:43 -0400 Subject: [PATCH 115/153] Run pre-commit --- examples/adafruit_io_mqtt/adafruit_io_feed_callback.py | 1 + examples/adafruit_io_mqtt/adafruit_io_location.py | 1 + examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py | 1 + examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py | 1 + examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py | 1 + examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py | 1 + examples/adafruit_io_mqtt/adafruit_io_time.py | 1 + examples/adafruit_io_simpletest.py | 1 + 8 files changed, 8 insertions(+) diff --git a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py index 7da7950..2f083dc 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py +++ b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py @@ -49,6 +49,7 @@ # 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): diff --git a/examples/adafruit_io_mqtt/adafruit_io_location.py b/examples/adafruit_io_mqtt/adafruit_io_location.py index 894c84b..09c9291 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_location.py +++ b/examples/adafruit_io_mqtt/adafruit_io_location.py @@ -52,6 +52,7 @@ # 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): diff --git a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py index 440aed3..db15278 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py +++ b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py @@ -35,6 +35,7 @@ led_pin = DigitalInOut(board.LED) led_pin.switch_to_output() + # Define callback functions which will be called when certain events happen. # pylint: disable=unused-argument def connected(client): diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py index 242bfe0..1514e37 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py @@ -45,6 +45,7 @@ gsm.connect() time.sleep(5) + # Define callback functions which will be called when certain events happen. # pylint: disable=unused-argument def connected(client): diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py index 8e9b1f0..4171280 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py @@ -31,6 +31,7 @@ wifi.radio.connect(secrets["ssid"], secrets["password"]) print("Connected to %s!" % secrets["ssid"]) + # Define callback functions which will be called when certain events happen. # pylint: disable=unused-argument def connected(client): diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index 3b656fc..d0dee85 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -30,6 +30,7 @@ # Initialize ethernet interface with DHCP eth = WIZNET5K(spi_bus, cs) + # Define callback functions which will be called when certain events happen. # pylint: disable=unused-argument def connected(client): diff --git a/examples/adafruit_io_mqtt/adafruit_io_time.py b/examples/adafruit_io_mqtt/adafruit_io_time.py index 7f9cfb5..2fe544c 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_time.py +++ b/examples/adafruit_io_mqtt/adafruit_io_time.py @@ -52,6 +52,7 @@ # 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): diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index 8810f12..206cb0d 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -55,6 +55,7 @@ # 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): From ce0ff9191d2db91ef012407371b59042da341f33 Mon Sep 17 00:00:00 2001 From: Scott Povlot Date: Mon, 22 May 2023 09:28:03 -0400 Subject: [PATCH 116/153] Remove documentation for subscribing to multiple feeds The code does not provide for this. --- adafruit_io/adafruit_io.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index c40b018..c667a28 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -252,13 +252,6 @@ def subscribe(self, feed_key=None, group_key=None, shared_user=None): .. code-block:: python client.subscribe('temperature') - - Example of subscribing to two Adafruit IO feeds: 'temperature' - and 'humidity'. - - .. code-block:: python - - client.subscribe([('temperature'), ('humidity')]) """ if shared_user is not None and feed_key is not None: validate_feed_key(feed_key) @@ -333,13 +326,6 @@ def unsubscribe(self, feed_key=None, group_key=None, shared_user=None): client.unsubscribe('temperature') - Example of unsubscribing from two feeds: 'temperature' - and 'humidity' - - .. code-block:: python - - client.unsubscribe([('temperature'), ('humidity')]) - Example of unsubscribing from a shared feed. .. code-block:: python From a7e0bd95ae12bff1a7812908d7f18172fa3676d5 Mon Sep 17 00:00:00 2001 From: Alec Delaney <89490472+tekktrik@users.noreply.github.com> Date: Tue, 23 May 2023 23:54:38 -0400 Subject: [PATCH 117/153] Update .pylintrc, fix jQuery for docs --- .pylintrc | 2 +- docs/conf.py | 1 + docs/requirements.txt | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.pylintrc b/.pylintrc index 40208c3..f945e92 100644 --- a/.pylintrc +++ b/.pylintrc @@ -396,4 +396,4 @@ min-public-methods=1 # Exceptions that will emit a warning when being caught. Defaults to # "Exception" -overgeneral-exceptions=Exception +overgeneral-exceptions=builtins.Exception diff --git a/docs/conf.py b/docs/conf.py index 91f0b1e..0aecd04 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -17,6 +17,7 @@ # ones. extensions = [ "sphinx.ext.autodoc", + "sphinxcontrib.jquery", "sphinx.ext.intersphinx", "sphinx.ext.napoleon", "sphinx.ext.todo", diff --git a/docs/requirements.txt b/docs/requirements.txt index 88e6733..797aa04 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -3,3 +3,4 @@ # SPDX-License-Identifier: Unlicense sphinx>=4.0.0 +sphinxcontrib-jquery From c7aa8885408d4355b6203f2893a37a0aa7cf4efa Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 30 May 2023 08:38:46 -0500 Subject: [PATCH 118/153] code format, pylint fixes. --- adafruit_io/adafruit_io.py | 43 ++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 7e4c567..c81a4b0 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -23,7 +23,7 @@ import re try: - from typing import List, Tuple, Any + from typing import List, Any except ImportError: pass @@ -244,7 +244,9 @@ def loop(self, timeout=1): self._client.loop(timeout) # Subscriptions - def subscribe(self, feed_key: str=None, group_key: str=None, shared_user: str=None): + def subscribe( + self, feed_key: str = None, group_key: str = None, shared_user: str = None + ): """Subscribes to your Adafruit IO feed or group. Can also subscribe to someone else's feed. @@ -317,7 +319,9 @@ def subscribe_to_time(self, time_type): else: self._client.subscribe("time/" + time_type) - def unsubscribe(self, feed_key: str=None, group_key: str=None, shared_user: str=None): + def unsubscribe( + self, feed_key: str = None, group_key: str = None, shared_user: str = None + ): """Unsubscribes from an Adafruit IO feed or group. Can also subscribe to someone else's feed. @@ -350,7 +354,9 @@ def unsubscribe(self, feed_key: str=None, group_key: str=None, shared_user: str= raise AdafruitIO_MQTTError("Must provide a feed_key or group_key.") # Publishing - def publish_multiple(self, feeds_and_data: List, timeout: int=3, is_group: bool=False): + def publish_multiple( + self, feeds_and_data: List, timeout: int = 3, is_group: bool = False + ): """Publishes multiple data points to multiple feeds or groups with a variable timeout. @@ -378,8 +384,15 @@ def publish_multiple(self, feeds_and_data: List, timeout: int=3, is_group: bool= time.sleep(timeout) # pylint: disable=too-many-arguments - def publish(self, feed_key: str, data: Any, metadata: str=None, shared_use: str=None, is_group: bool=False): - """Publishes to an An Adafruit IO Feed. + def publish( + self, + feed_key: str, + data: Any, + metadata: str = None, + shared_user: str = None, + is_group: bool = False, + ): + """Publishes to an Adafruit IO Feed. :param str feed_key: Adafruit IO Feed key. :param str data: Data to publish to the feed or group. @@ -564,7 +577,9 @@ def _delete(self, path: str): return json_data # Data - def send_data(self, feed_key: str, data: str, metadata: dict=None, precision: int=None): + def send_data( + self, feed_key: str, data: str, metadata: dict = None, precision: int = None + ): """ Sends value data to a specified Adafruit IO feed. @@ -630,7 +645,7 @@ def delete_data(self, feed_key: str, data_id: str): return self._delete(path) # Groups - def create_new_group(self, group_key:str , group_description: str): + def create_new_group(self, group_key: str, group_description: str): """ Creates a new Adafruit IO Group. @@ -682,7 +697,7 @@ def add_feed_to_group(self, group_key: str, feed_key: str): return self._post(path, payload) # Feeds - def get_feed(self, feed_key: str, detailed: bool=False): + def get_feed(self, feed_key: str, detailed: bool = False): """ Returns an Adafruit IO feed based on the feed key @@ -696,7 +711,9 @@ def get_feed(self, feed_key: str, detailed: bool=False): path = self._compose_path("feeds/{0}".format(feed_key)) return self._get(path) - def create_new_feed(self, feed_key: str, feed_desc: str=None, feed_license: str=None): + def create_new_feed( + self, feed_key: str, feed_desc: str = None, feed_license: str = None + ): """ Creates a new Adafruit IO feed. @@ -710,7 +727,11 @@ def create_new_feed(self, feed_key: str, feed_desc: str=None, feed_license: str= return self._post(path, payload) def create_and_get_feed( - self, feed_key: str, detailed: bool=False, feed_desc: str=None, feed_license: str=None + self, + feed_key: str, + detailed: bool = False, + feed_desc: str = None, + feed_license: str = None, ): """ Attempts to return a feed; if the feed does not exist, it is created, and then returned. From d790205ba3fc90b88d33faf0f09f70563d0b6c9e Mon Sep 17 00:00:00 2001 From: foamyguy Date: Mon, 5 Jun 2023 14:46:40 -0500 Subject: [PATCH 119/153] typing tweaks --- adafruit_io/adafruit_io.py | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index c81a4b0..dfafc14 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -23,7 +23,7 @@ import re try: - from typing import List, Any + from typing import List, Any, Callable, Optional except ImportError: pass @@ -200,7 +200,7 @@ def _on_unsubscribe_mqtt(self, client, user_data, topic, pid): if self.on_unsubscribe is not None: self.on_unsubscribe(self, user_data, topic, pid) - def add_feed_callback(self, feed_key: str, callback_method: str): + def add_feed_callback(self, feed_key: str, callback_method: Callable): """Attaches a callback_method to an Adafruit IO feed. The callback_method function is called when a new value is written to the feed. @@ -245,7 +245,10 @@ def loop(self, timeout=1): # Subscriptions def subscribe( - self, feed_key: str = None, group_key: str = None, shared_user: str = None + self, + feed_key: str = None, + group_key: str = None, + shared_user: Optional[str] = None, ): """Subscribes to your Adafruit IO feed or group. Can also subscribe to someone else's feed. @@ -306,7 +309,7 @@ def subscribe_to_weather(self, weather_record: int, forecast: str): ) ) - def subscribe_to_time(self, time_type): + def subscribe_to_time(self, time_type: str): """Adafruit IO provides some built-in MQTT topics for getting the current server time. :param str time_type: Current Adafruit IO server time. Can be 'seconds', 'millis', or 'iso'. @@ -320,7 +323,10 @@ def subscribe_to_time(self, time_type): self._client.subscribe("time/" + time_type) def unsubscribe( - self, feed_key: str = None, group_key: str = None, shared_user: str = None + self, + feed_key: str = None, + group_key: str = None, + shared_user: Optional[str] = None, ): """Unsubscribes from an Adafruit IO feed or group. Can also subscribe to someone else's feed. @@ -387,7 +393,7 @@ def publish_multiple( def publish( self, feed_key: str, - data: Any, + data: str, metadata: str = None, shared_user: str = None, is_group: bool = False, @@ -534,7 +540,7 @@ def _compose_path(self, path: str): return "https://io.adafruit.com/api/v2/{0}/{1}".format(self.username, path) # HTTP Requests - def _post(self, path: str, payload: json): + def _post(self, path: str, payload: Any): """ POST data to Adafruit IO @@ -578,7 +584,11 @@ def _delete(self, path: str): # Data def send_data( - self, feed_key: str, data: str, metadata: dict = None, precision: int = None + self, + feed_key: str, + data: str, + metadata: Optional[dict] = None, + precision: Optional[int] = None, ): """ Sends value data to a specified Adafruit IO feed. @@ -712,7 +722,10 @@ def get_feed(self, feed_key: str, detailed: bool = False): return self._get(path) def create_new_feed( - self, feed_key: str, feed_desc: str = None, feed_license: str = None + self, + feed_key: str, + feed_desc: Optional[str] = None, + feed_license: Optional[str] = None, ): """ Creates a new Adafruit IO feed. @@ -730,8 +743,8 @@ def create_and_get_feed( self, feed_key: str, detailed: bool = False, - feed_desc: str = None, - feed_license: str = None, + feed_desc: Optional[str] = None, + feed_license: Optional[str] = None, ): """ Attempts to return a feed; if the feed does not exist, it is created, and then returned. From 46d93c2c991fef50aada36d1eea3b44fd53f8b9b Mon Sep 17 00:00:00 2001 From: tyeth Date: Sat, 2 Sep 2023 20:52:06 +0100 Subject: [PATCH 120/153] Update for settings.toml (CPY8) and SSL. Tested on Adafruit Feather ESP32-S2 Reverse TFT with CPY 8.2.4 --- .../adafruit_io_simpletest_esp32s2.py | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py index 4171280..1ecb026 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py @@ -3,6 +3,7 @@ import time from random import randint +import os import ssl import socketpool import wifi @@ -16,9 +17,19 @@ # source control. # pylint: disable=no-name-in-module,wrong-import-order try: - from secrets import secrets + if os.getenv("AIO_USERNAME") and os.getenv("AIO_KEY"): + secrets = { + "aio_username": os.getenv("AIO_USERNAME"), + "aio_key": os.getenv("AIO_KEY"), + "ssid": os.getenv("CIRCUITPY_WIFI_SSID"), + "password": os.getenv("CIRCUITPY_WIFI_PASSWORD"), + } + else: + from secrets import secrets except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") + print( + "WiFi + Adafruit IO secrets are kept in secrets.py or settings.toml, please add them there!" + ) raise # Set your Adafruit IO Username and Key in secrets.py @@ -27,9 +38,10 @@ aio_username = secrets["aio_username"] aio_key = secrets["aio_key"] -print("Connecting to %s" % secrets["ssid"]) -wifi.radio.connect(secrets["ssid"], secrets["password"]) -print("Connected to %s!" % secrets["ssid"]) +if not wifi.radio.connected: + print("Connecting to %s" % secrets["ssid"]) + wifi.radio.connect(secrets["ssid"], secrets["password"]) + print("Connected to %s!" % secrets["ssid"]) # Define callback functions which will be called when certain events happen. @@ -74,11 +86,12 @@ def message(client, feed_id, payload): # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( broker="io.adafruit.com", - port=1883, + port=8883, username=secrets["aio_username"], password=secrets["aio_key"], socket_pool=pool, ssl_context=ssl.create_default_context(), + is_ssl=True, ) # Initialize an Adafruit IO MQTT Client From ed8153fb88c92a34f057a827af49cfdd2f6aef7c Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 19 Sep 2023 18:48:40 -0500 Subject: [PATCH 121/153] fix rtd theme --- docs/conf.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 0aecd04..82edab7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -94,19 +94,10 @@ # 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 = ["."] +import sphinx_rtd_theme + +html_theme = "sphinx_rtd_theme" +html_theme_path = [sphinx_rtd_theme.get_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, From 30667b9b9865d14128f6f3b8202d53dfe1c49109 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Mon, 4 Dec 2023 11:53:06 -0600 Subject: [PATCH 122/153] unpin sphinx and add sphinx-rtd-theme to docs reqs --- docs/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 797aa04..979f568 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,5 +2,6 @@ # # SPDX-License-Identifier: Unlicense -sphinx>=4.0.0 +sphinx sphinxcontrib-jquery +sphinx-rtd-theme From 29815284e4cea37d800e4fb948b92502bf3f71fb Mon Sep 17 00:00:00 2001 From: kavinaidoo <83715825+kavinaidoo@users.noreply.github.com> Date: Thu, 7 Dec 2023 13:49:00 +0200 Subject: [PATCH 123/153] Added receive_n_data function Allows for an in-between step between receive_data (most recent value only) and receive_all_data (all data values) --- adafruit_io/adafruit_io.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index dfafc14..22d6dba 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -53,6 +53,16 @@ def validate_feed_key(feed_key: str): "Feed key must contain English letters, numbers, dash, and a period or a forward slash." ) +def validate_n_values(n_values: int): + """Validates a provided number of values to retrieve data from Adafruit IO. + + Although Adafruit IO will accept values < 1 and > 1000, this avoids two types of issues: + <1 - Coding errors + >1000 - Pagination-related expectation management + + """ + if n_values < 1 or n_values > 1000: # validate 0 < n_values <= 1000 + raise ValueError("Number of values must be greater than zero and less than or equal to 1000") class IO_MQTT: """ @@ -632,6 +642,18 @@ def receive_all_data(self, feed_key: str): validate_feed_key(feed_key) path = self._compose_path("feeds/{0}/data".format(feed_key)) return self._get(path) + + def receive_n_data(self, feed_key: str, n_values: int): + """ + Get n data values from a specified Adafruit IO feed. Data is + returned in reverse order. + + :param str feed_key: Adafruit IO feed key + """ + validate_n_values(n_values) + validate_feed_key(feed_key) + path = self._compose_path("feeds/{0}/data?limit={1}".format(feed_key,n_values)) + return self._get(path) def receive_data(self, feed_key: str): """ From af3c50ef96a4ce58a7bdf31d93762e24f57dd7b9 Mon Sep 17 00:00:00 2001 From: kavinaidoo <83715825+kavinaidoo@users.noreply.github.com> Date: Thu, 7 Dec 2023 15:22:35 +0200 Subject: [PATCH 124/153] formatting changes from black --- adafruit_io/adafruit_io.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 22d6dba..cdb6d56 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -53,6 +53,7 @@ def validate_feed_key(feed_key: str): "Feed key must contain English letters, numbers, dash, and a period or a forward slash." ) + def validate_n_values(n_values: int): """Validates a provided number of values to retrieve data from Adafruit IO. @@ -62,7 +63,10 @@ def validate_n_values(n_values: int): """ if n_values < 1 or n_values > 1000: # validate 0 < n_values <= 1000 - raise ValueError("Number of values must be greater than zero and less than or equal to 1000") + raise ValueError( + "Number of values must be greater than zero and less than or equal to 1000" + ) + class IO_MQTT: """ @@ -642,7 +646,7 @@ def receive_all_data(self, feed_key: str): validate_feed_key(feed_key) path = self._compose_path("feeds/{0}/data".format(feed_key)) return self._get(path) - + def receive_n_data(self, feed_key: str, n_values: int): """ Get n data values from a specified Adafruit IO feed. Data is @@ -652,7 +656,7 @@ def receive_n_data(self, feed_key: str, n_values: int): """ validate_n_values(n_values) validate_feed_key(feed_key) - path = self._compose_path("feeds/{0}/data?limit={1}".format(feed_key,n_values)) + path = self._compose_path("feeds/{0}/data?limit={1}".format(feed_key, n_values)) return self._get(path) def receive_data(self, feed_key: str): From 7facaf227dc690666242825556d857a6a51cbda9 Mon Sep 17 00:00:00 2001 From: kavinaidoo <83715825+kavinaidoo@users.noreply.github.com> Date: Wed, 20 Dec 2023 19:49:45 +0200 Subject: [PATCH 125/153] corrections to receive_n_data documentation receive_n_data - added missing n_values :param - changed description for more accurate wording validate_n_values - changed description for better formatting in docs --- adafruit_io/adafruit_io.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index cdb6d56..67b014c 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -58,8 +58,7 @@ def validate_n_values(n_values: int): """Validates a provided number of values to retrieve data from Adafruit IO. Although Adafruit IO will accept values < 1 and > 1000, this avoids two types of issues: - <1 - Coding errors - >1000 - Pagination-related expectation management + n_values < 1 (coding errors) and n_values > 1000 (pagination required for HTTP API) """ if n_values < 1 or n_values > 1000: # validate 0 < n_values <= 1000 @@ -649,10 +648,11 @@ def receive_all_data(self, feed_key: str): def receive_n_data(self, feed_key: str, n_values: int): """ - Get n data values from a specified Adafruit IO feed. Data is + Get most recent n data values from a specified feed. Data is returned in reverse order. :param str feed_key: Adafruit IO feed key + :param int n_values: Number of data values """ validate_n_values(n_values) validate_feed_key(feed_key) From 8a0556491921e220073afee6a8567c14eb40071b Mon Sep 17 00:00:00 2001 From: Justin Myers Date: Thu, 29 Feb 2024 11:41:52 -0800 Subject: [PATCH 126/153] Fix README requirements --- README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.rst b/README.rst index 68f9ed1..8ed057a 100644 --- a/README.rst +++ b/README.rst @@ -26,6 +26,8 @@ Dependencies This driver depends on: * `Adafruit CircuitPython `_ +* `Adafruit CircuitPython ConnectionManager `_ +* `Adafruit CircuitPython MiniMQTT `_ Please ensure that all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading From 637b274774d477591e411e7a60fecb303fb700c4 Mon Sep 17 00:00:00 2001 From: Justin Myers Date: Thu, 29 Feb 2024 21:16:25 -0800 Subject: [PATCH 127/153] Update legacy set_socket examples --- examples/adafruit_io_http/adafruit_io_analog_in.py | 10 ++++++---- examples/adafruit_io_http/adafruit_io_digital_out.py | 10 ++++++---- examples/adafruit_io_http/adafruit_io_feeds.py | 10 ++++++---- examples/adafruit_io_http/adafruit_io_groups.py | 10 ++++++---- examples/adafruit_io_http/adafruit_io_metadata.py | 10 ++++++---- examples/adafruit_io_http/adafruit_io_randomizer.py | 10 ++++++---- .../adafruit_io_simpletest_esp32spi.py | 10 ++++++---- examples/adafruit_io_http/adafruit_io_temperature.py | 10 ++++++---- examples/adafruit_io_http/adafruit_io_weather.py | 10 ++++++---- examples/adafruit_io_mqtt/adafruit_io_feed_callback.py | 8 +++++--- examples/adafruit_io_mqtt/adafruit_io_groups.py | 8 +++++--- examples/adafruit_io_mqtt/adafruit_io_location.py | 8 +++++--- examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py | 8 +++++--- .../adafruit_io_simpletest_cellular.py | 8 +++++--- .../adafruit_io_mqtt/adafruit_io_simpletest_eth.py | 8 +++++--- examples/adafruit_io_mqtt/adafruit_io_time.py | 8 +++++--- examples/adafruit_io_simpletest.py | 8 +++++--- 17 files changed, 94 insertions(+), 60 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_analog_in.py b/examples/adafruit_io_http/adafruit_io_analog_in.py index 7aafb8b..1ed52a3 100644 --- a/examples/adafruit_io_http/adafruit_io_analog_in.py +++ b/examples/adafruit_io_http/adafruit_io_analog_in.py @@ -8,9 +8,10 @@ import busio from analogio import AnalogIn from digitalio import DigitalInOut -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_connection_manager +import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests as requests +import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and @@ -45,8 +46,9 @@ continue print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) -socket.set_interface(esp) -requests.set_socket(socket, esp) +# Initialize a requests session +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, diff --git a/examples/adafruit_io_http/adafruit_io_digital_out.py b/examples/adafruit_io_http/adafruit_io_digital_out.py index c8b1d82..1453688 100644 --- a/examples/adafruit_io_http/adafruit_io_digital_out.py +++ b/examples/adafruit_io_http/adafruit_io_digital_out.py @@ -7,9 +7,10 @@ import board import busio from digitalio import DigitalInOut, Direction -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_connection_manager +import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests as requests +import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and @@ -44,8 +45,9 @@ continue print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) -socket.set_interface(esp) -requests.set_socket(socket, esp) +# Initialize a requests session +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, diff --git a/examples/adafruit_io_http/adafruit_io_feeds.py b/examples/adafruit_io_http/adafruit_io_feeds.py index 160a540..37bdcf9 100644 --- a/examples/adafruit_io_http/adafruit_io_feeds.py +++ b/examples/adafruit_io_http/adafruit_io_feeds.py @@ -7,9 +7,10 @@ import board import busio from digitalio import DigitalInOut -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_connection_manager +import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests as requests +import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and @@ -44,8 +45,9 @@ continue print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) -socket.set_interface(esp) -requests.set_socket(socket, esp) +# Initialize a requests session +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index daefd1e..6e31580 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -7,9 +7,10 @@ import board import busio from digitalio import DigitalInOut -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_connection_manager +import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests as requests +import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP @@ -45,8 +46,9 @@ continue print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) -socket.set_interface(esp) -requests.set_socket(socket, esp) +# Initialize a requests session +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, diff --git a/examples/adafruit_io_http/adafruit_io_metadata.py b/examples/adafruit_io_http/adafruit_io_metadata.py index 7bfb933..5d913b3 100644 --- a/examples/adafruit_io_http/adafruit_io_metadata.py +++ b/examples/adafruit_io_http/adafruit_io_metadata.py @@ -6,9 +6,10 @@ import board import busio from digitalio import DigitalInOut -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_connection_manager +import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests as requests +import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and @@ -43,8 +44,9 @@ continue print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) -socket.set_interface(esp) -requests.set_socket(socket, esp) +# Initialize a requests session +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, diff --git a/examples/adafruit_io_http/adafruit_io_randomizer.py b/examples/adafruit_io_http/adafruit_io_randomizer.py index d68f2e5..b838d20 100644 --- a/examples/adafruit_io_http/adafruit_io_randomizer.py +++ b/examples/adafruit_io_http/adafruit_io_randomizer.py @@ -7,9 +7,10 @@ import board import busio from digitalio import DigitalInOut -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_connection_manager +import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests as requests +import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and @@ -44,8 +45,9 @@ continue print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) -socket.set_interface(esp) -requests.set_socket(socket, esp) +# Initialize a requests session +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, diff --git a/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py b/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py index fb80f1a..656b67d 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py @@ -6,9 +6,10 @@ import board import busio from digitalio import DigitalInOut -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_connection_manager +import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests as requests +import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and @@ -43,8 +44,9 @@ continue print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) -socket.set_interface(esp) -requests.set_socket(socket, esp) +# Initialize a requests session +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, diff --git a/examples/adafruit_io_http/adafruit_io_temperature.py b/examples/adafruit_io_http/adafruit_io_temperature.py index b779a50..9ed8893 100644 --- a/examples/adafruit_io_http/adafruit_io_temperature.py +++ b/examples/adafruit_io_http/adafruit_io_temperature.py @@ -7,9 +7,10 @@ import board import busio from digitalio import DigitalInOut -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_connection_manager +import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests as requests +import adafruit_requests import adafruit_adt7410 from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError @@ -45,8 +46,9 @@ continue print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) -socket.set_interface(esp) -requests.set_socket(socket, esp) +# Initialize a requests session +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, diff --git a/examples/adafruit_io_http/adafruit_io_weather.py b/examples/adafruit_io_http/adafruit_io_weather.py index e65c654..aad86da 100644 --- a/examples/adafruit_io_http/adafruit_io_weather.py +++ b/examples/adafruit_io_http/adafruit_io_weather.py @@ -6,9 +6,10 @@ import board import busio from digitalio import DigitalInOut -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_connection_manager +import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests as requests +import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and @@ -43,8 +44,9 @@ continue print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) -socket.set_interface(esp) -requests.set_socket(socket, esp) +# Initialize a requests session +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, diff --git a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py index 2f083dc..aa9a1d2 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py +++ b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py @@ -6,9 +6,10 @@ import board import busio from digitalio import DigitalInOut +import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_esp32spi.adafruit_esp32spi_socket as pool import neopixel import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT @@ -94,8 +95,7 @@ def on_battery_msg(client, topic, message): wifi.connect() print("Connected!") -# Initialize MQTT interface with the esp interface -MQTT.set_socket(socket, esp) +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( @@ -103,6 +103,8 @@ def on_battery_msg(client, topic, message): port=1883, username=secrets["aio_username"], password=secrets["aio_key"], + socket_pool=pool, + ssl_context=ssl_context, ) # Initialize an Adafruit IO MQTT Client diff --git a/examples/adafruit_io_mqtt/adafruit_io_groups.py b/examples/adafruit_io_mqtt/adafruit_io_groups.py index 753c263..5b912c6 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_groups.py +++ b/examples/adafruit_io_mqtt/adafruit_io_groups.py @@ -9,9 +9,10 @@ import board import busio from digitalio import DigitalInOut +import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_esp32spi.adafruit_esp32spi_socket as pool import neopixel import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT @@ -85,8 +86,7 @@ def message(client, feed_id, payload): wifi.connect() print("Connected!") -# Initialize MQTT interface with the esp interface -MQTT.set_socket(socket, esp) +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( @@ -94,6 +94,8 @@ def message(client, feed_id, payload): port=1883, username=secrets["aio_username"], password=secrets["aio_key"], + socket_pool=pool, + ssl_context=ssl_context, ) # Initialize an Adafruit IO MQTT Client diff --git a/examples/adafruit_io_mqtt/adafruit_io_location.py b/examples/adafruit_io_mqtt/adafruit_io_location.py index 09c9291..20aef53 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_location.py +++ b/examples/adafruit_io_mqtt/adafruit_io_location.py @@ -7,9 +7,10 @@ import board import busio from digitalio import DigitalInOut +import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_esp32spi.adafruit_esp32spi_socket as pool import neopixel @@ -85,8 +86,7 @@ def message(client, feed_id, payload): wifi.connect() print("Connected!") -# Initialize MQTT interface with the esp interface -MQTT.set_socket(socket, esp) +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( @@ -94,6 +94,8 @@ def message(client, feed_id, payload): port=1883, username=secrets["aio_username"], password=secrets["aio_key"], + socket_pool=pool, + ssl_context=ssl_context, ) # Initialize an Adafruit IO MQTT Client diff --git a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py index db15278..7742c8f 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py +++ b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py @@ -6,9 +6,10 @@ import board import busio from digitalio import DigitalInOut +import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_esp32spi.adafruit_esp32spi_socket as pool import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT @@ -70,8 +71,7 @@ def on_led_msg(client, topic, message): wifi.connect() print("Connected!") -# Initialize MQTT interface with the esp interface -MQTT.set_socket(socket, esp) +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( @@ -79,6 +79,8 @@ def on_led_msg(client, topic, message): port=1883, username=secrets["aio_username"], password=secrets["aio_key"], + socket_pool=pool, + ssl_context=ssl_context, ) # Initialize an Adafruit IO MQTT Client diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py index 1514e37..bfe565b 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py @@ -12,9 +12,10 @@ import busio import digitalio +import adafruit_connection_manager from adafruit_fona.adafruit_fona import FONA from adafruit_fona.adafruit_fona_gsm import GSM -import adafruit_fona.adafruit_fona_socket as cellular_socket +import adafruit_fona.adafruit_fona_socket as pool import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT @@ -82,8 +83,7 @@ def message(client, feed_id, payload): print("Feed {0} received new value: {1}".format(feed_id, payload)) -# Initialize MQTT interface with the ethernet interface -MQTT.set_socket(cellular_socket, fona) +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, fona) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( @@ -91,6 +91,8 @@ def message(client, feed_id, payload): port=1883, username=secrets["aio_username"], password=secrets["aio_key"], + socket_pool=pool, + ssl_context=ssl_context, ) # Initialize an Adafruit IO MQTT Client diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index d0dee85..0d6a988 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -12,8 +12,9 @@ import busio from digitalio import DigitalInOut +import adafruit_connection_manager from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K -import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket +import adafruit_wiznet5k.adafruit_wiznet5k_socket as pool import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT @@ -67,8 +68,7 @@ def message(client, feed_id, payload): print("Feed {0} received new value: {1}".format(feed_id, payload)) -# Initialize MQTT interface with the ethernet interface -MQTT.set_socket(socket, eth) +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, eth) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( @@ -76,6 +76,8 @@ def message(client, feed_id, payload): port=1883, username=secrets["aio_username"], password=secrets["aio_key"], + socket_pool=pool, + ssl_context=ssl_context, ) # Initialize an Adafruit IO MQTT Client diff --git a/examples/adafruit_io_mqtt/adafruit_io_time.py b/examples/adafruit_io_mqtt/adafruit_io_time.py index 2fe544c..3babf9c 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_time.py +++ b/examples/adafruit_io_mqtt/adafruit_io_time.py @@ -8,9 +8,10 @@ import board import busio from digitalio import DigitalInOut +import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_esp32spi.adafruit_esp32spi_socket as pool import neopixel import adafruit_minimqtt.adafruit_minimqtt as MQTT @@ -99,8 +100,7 @@ def message(client, feed_id, payload): wifi.connect() print("Connected!") -# Initialize MQTT interface with the esp interface -MQTT.set_socket(socket, esp) +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( @@ -108,6 +108,8 @@ def message(client, feed_id, payload): port=1883, username=secrets["aio_username"], password=secrets["aio_key"], + socket_pool=pool, + ssl_context=ssl_context, ) # Initialize an Adafruit IO MQTT Client diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index 206cb0d..2733305 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -12,9 +12,10 @@ import board import busio from digitalio import DigitalInOut +import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_esp32spi.adafruit_esp32spi_socket as socket +import adafruit_esp32spi.adafruit_esp32spi_socket as pool import neopixel import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT @@ -97,8 +98,7 @@ def message(client, feed_id, payload): wifi.connect() print("Connected!") -# Initialize MQTT interface with the esp interface -MQTT.set_socket(socket, esp) +ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( @@ -106,6 +106,8 @@ def message(client, feed_id, payload): port=1883, username=secrets["aio_username"], password=secrets["aio_key"], + socket_pool=pool, + ssl_context=ssl_context, ) From d7bd8c31a41e5eb273c7fb90c2967e5e5a380a04 Mon Sep 17 00:00:00 2001 From: Justin Myers Date: Fri, 1 Mar 2024 08:25:25 -0800 Subject: [PATCH 128/153] Fix get_radio_ssl_context --- examples/adafruit_io_http/adafruit_io_analog_in.py | 4 ++-- examples/adafruit_io_http/adafruit_io_digital_out.py | 4 ++-- examples/adafruit_io_http/adafruit_io_feeds.py | 4 ++-- examples/adafruit_io_http/adafruit_io_groups.py | 4 ++-- examples/adafruit_io_http/adafruit_io_metadata.py | 4 ++-- examples/adafruit_io_http/adafruit_io_randomizer.py | 4 ++-- examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py | 4 ++-- examples/adafruit_io_http/adafruit_io_temperature.py | 4 ++-- examples/adafruit_io_http/adafruit_io_weather.py | 4 ++-- examples/adafruit_io_mqtt/adafruit_io_feed_callback.py | 4 ++-- examples/adafruit_io_mqtt/adafruit_io_groups.py | 4 ++-- examples/adafruit_io_mqtt/adafruit_io_location.py | 4 ++-- examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py | 4 ++-- examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py | 4 ++-- examples/adafruit_io_mqtt/adafruit_io_time.py | 4 ++-- examples/adafruit_io_simpletest.py | 4 ++-- 16 files changed, 32 insertions(+), 32 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_analog_in.py b/examples/adafruit_io_http/adafruit_io_analog_in.py index 1ed52a3..fe327e5 100644 --- a/examples/adafruit_io_http/adafruit_io_analog_in.py +++ b/examples/adafruit_io_http/adafruit_io_analog_in.py @@ -9,7 +9,6 @@ from analogio import AnalogIn from digitalio import DigitalInOut import adafruit_connection_manager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError @@ -47,7 +46,8 @@ print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) # Initialize a requests session -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py diff --git a/examples/adafruit_io_http/adafruit_io_digital_out.py b/examples/adafruit_io_http/adafruit_io_digital_out.py index 1453688..6a1ee04 100644 --- a/examples/adafruit_io_http/adafruit_io_digital_out.py +++ b/examples/adafruit_io_http/adafruit_io_digital_out.py @@ -8,7 +8,6 @@ import busio from digitalio import DigitalInOut, Direction import adafruit_connection_manager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError @@ -46,7 +45,8 @@ print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) # Initialize a requests session -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py diff --git a/examples/adafruit_io_http/adafruit_io_feeds.py b/examples/adafruit_io_http/adafruit_io_feeds.py index 37bdcf9..7637a06 100644 --- a/examples/adafruit_io_http/adafruit_io_feeds.py +++ b/examples/adafruit_io_http/adafruit_io_feeds.py @@ -8,7 +8,6 @@ import busio from digitalio import DigitalInOut import adafruit_connection_manager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP @@ -46,7 +45,8 @@ print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) # Initialize a requests session -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index 6e31580..4c36516 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -8,7 +8,6 @@ import busio from digitalio import DigitalInOut import adafruit_connection_manager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP @@ -47,7 +46,8 @@ print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) # Initialize a requests session -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py diff --git a/examples/adafruit_io_http/adafruit_io_metadata.py b/examples/adafruit_io_http/adafruit_io_metadata.py index 5d913b3..9bf27d5 100644 --- a/examples/adafruit_io_http/adafruit_io_metadata.py +++ b/examples/adafruit_io_http/adafruit_io_metadata.py @@ -7,7 +7,6 @@ import busio from digitalio import DigitalInOut import adafruit_connection_manager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError @@ -45,7 +44,8 @@ print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) # Initialize a requests session -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py diff --git a/examples/adafruit_io_http/adafruit_io_randomizer.py b/examples/adafruit_io_http/adafruit_io_randomizer.py index b838d20..920bf01 100644 --- a/examples/adafruit_io_http/adafruit_io_randomizer.py +++ b/examples/adafruit_io_http/adafruit_io_randomizer.py @@ -8,7 +8,6 @@ import busio from digitalio import DigitalInOut import adafruit_connection_manager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP @@ -46,7 +45,8 @@ print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) # Initialize a requests session -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py diff --git a/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py b/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py index 656b67d..0fe2df4 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py @@ -7,7 +7,6 @@ import busio from digitalio import DigitalInOut import adafruit_connection_manager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError @@ -45,7 +44,8 @@ print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) # Initialize a requests session -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py diff --git a/examples/adafruit_io_http/adafruit_io_temperature.py b/examples/adafruit_io_http/adafruit_io_temperature.py index 9ed8893..989260e 100644 --- a/examples/adafruit_io_http/adafruit_io_temperature.py +++ b/examples/adafruit_io_http/adafruit_io_temperature.py @@ -8,7 +8,6 @@ import busio from digitalio import DigitalInOut import adafruit_connection_manager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests import adafruit_adt7410 @@ -47,7 +46,8 @@ print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) # Initialize a requests session -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py diff --git a/examples/adafruit_io_http/adafruit_io_weather.py b/examples/adafruit_io_http/adafruit_io_weather.py index aad86da..376cf83 100644 --- a/examples/adafruit_io_http/adafruit_io_weather.py +++ b/examples/adafruit_io_http/adafruit_io_weather.py @@ -7,7 +7,6 @@ import busio from digitalio import DigitalInOut import adafruit_connection_manager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool from adafruit_esp32spi import adafruit_esp32spi import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP @@ -45,7 +44,8 @@ print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) # Initialize a requests session -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) # Set your Adafruit IO Username and Key in secrets.py diff --git a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py index aa9a1d2..a58f38c 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py +++ b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py @@ -9,7 +9,6 @@ import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool import neopixel import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT @@ -95,7 +94,8 @@ def on_battery_msg(client, topic, message): wifi.connect() print("Connected!") -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( diff --git a/examples/adafruit_io_mqtt/adafruit_io_groups.py b/examples/adafruit_io_mqtt/adafruit_io_groups.py index 5b912c6..15fd7d9 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_groups.py +++ b/examples/adafruit_io_mqtt/adafruit_io_groups.py @@ -12,7 +12,6 @@ import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool import neopixel import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT @@ -86,7 +85,8 @@ def message(client, feed_id, payload): wifi.connect() print("Connected!") -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( diff --git a/examples/adafruit_io_mqtt/adafruit_io_location.py b/examples/adafruit_io_mqtt/adafruit_io_location.py index 20aef53..f4e58f7 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_location.py +++ b/examples/adafruit_io_mqtt/adafruit_io_location.py @@ -10,7 +10,6 @@ import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool import neopixel @@ -86,7 +85,8 @@ def message(client, feed_id, payload): wifi.connect() print("Connected!") -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( diff --git a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py index 7742c8f..18cd1c1 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py +++ b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py @@ -9,7 +9,6 @@ import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT @@ -71,7 +70,8 @@ def on_led_msg(client, topic, message): wifi.connect() print("Connected!") -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index 0d6a988..ad9bcdc 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -14,7 +14,6 @@ import adafruit_connection_manager from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K -import adafruit_wiznet5k.adafruit_wiznet5k_socket as pool import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT @@ -68,7 +67,8 @@ def message(client, feed_id, payload): print("Feed {0} received new value: {1}".format(feed_id, payload)) -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, eth) +pool = adafruit_connection_manager.get_radio_socketpool(eth) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(eth) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( diff --git a/examples/adafruit_io_mqtt/adafruit_io_time.py b/examples/adafruit_io_mqtt/adafruit_io_time.py index 3babf9c..cd0ea42 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_time.py +++ b/examples/adafruit_io_mqtt/adafruit_io_time.py @@ -11,7 +11,6 @@ import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool import neopixel import adafruit_minimqtt.adafruit_minimqtt as MQTT @@ -100,7 +99,8 @@ def message(client, feed_id, payload): wifi.connect() print("Connected!") -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index 2733305..85382dd 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -15,7 +15,6 @@ import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_esp32spi.adafruit_esp32spi_socket as pool import neopixel import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT @@ -98,7 +97,8 @@ def message(client, feed_id, payload): wifi.connect() print("Connected!") -ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, esp) +pool = adafruit_connection_manager.get_radio_socketpool(esp) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( From a049b6fc8c4e516c02304b0716aadc2a87a9de51 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 25 Jun 2024 13:51:20 +0100 Subject: [PATCH 129/153] Highlight usage of different methods for group feeds + cleanup multigroup feeds User feedback was: "add_feed_to_group() is not working - used adafruit_io_groups.py example as a test case." Fixes #119 --- examples/adafruit_io_http/adafruit_io_groups.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index 4c36516..7398605 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -63,13 +63,24 @@ print("Creating a new Adafruit IO Group...") sensor_group = io.create_new_group("envsensors", "a group of environmental sensors") -# Add the 'temperature' feed to the group -print("Adding feed temperature to group...") -io.add_feed_to_group(sensor_group["key"], "temperature") +# Create the 'temperature' feed in the group +print("Creating feed temperature inside group...") +io.create_feed_in_group(sensor_group["key"], "temperature") + +# Create the 'humidity' feed then add to group (it will still be in Default group too) +print("Creating feed humidity then adding to group...") +humidity_feed = io.create_new_feed("humidity", "a feed for humidity data") +io.add_feed_to_group(sensor_group["key"], humidity_feed["key"]) # Get info from the group +print("Getting fresh group info...") +sensor_group = io.get_group("envsensors") # refresh data via HTTP API print(sensor_group) # Delete the group print("Deleting group...") io.delete_group("envsensors") + +# Delete the remaining humidity feed (it was in Two Groups so not deleted with our group) +print("Deleting feed humidity (still in default group)...") +io.delete_feed(humidity_feed["key"]) From 27a65d4ccb8f1d7c3693436af982eec9ed246c72 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Fri, 12 Jul 2024 19:08:50 +0100 Subject: [PATCH 130/153] Add missing "on_publish" event callback in IO_MQTT - Fixes #122 --- adafruit_io/adafruit_io.py | 8 ++++++++ .../adafruit_io_mqtt/adafruit_io_feed_callback.py | 10 ++++++++++ examples/adafruit_io_mqtt/adafruit_io_groups.py | 10 ++++++++++ examples/adafruit_io_mqtt/adafruit_io_location.py | 10 ++++++++++ .../adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py | 12 ++++++++++++ .../adafruit_io_simpletest_cellular.py | 12 ++++++++++++ .../adafruit_io_simpletest_esp32s2.py | 12 ++++++++++++ .../adafruit_io_mqtt/adafruit_io_simpletest_eth.py | 12 ++++++++++++ examples/adafruit_io_mqtt/adafruit_io_time.py | 10 ++++++++++ examples/adafruit_io_simpletest.py | 10 ++++++++++ 10 files changed, 106 insertions(+) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 67b014c..28822a4 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -98,12 +98,14 @@ def __init__(self, mqtt_client): self.on_message = None self.on_subscribe = None self.on_unsubscribe = None + self.on_publish = None # MQTT event callbacks self._client.on_connect = self._on_connect_mqtt self._client.on_disconnect = self._on_disconnect_mqtt self._client.on_message = self._on_message_mqtt self._client.on_subscribe = self._on_subscribe_mqtt self._client.on_unsubscribe = self._on_unsubscribe_mqtt + self._client.on_publish = self._on_publish_mqtt self._connected = False def __enter__(self): @@ -201,6 +203,12 @@ def _on_message_mqtt(self, client, topic: str, payload: str): ) self.on_message(self, topic_name, message) + # pylint: disable=not-callable, unused-argument + def _on_publish_mqtt(self, client, user_data, topic, pid): + """Runs when the client calls on_publish.""" + if self.on_publish is not None: + self.on_publish(self, user_data, topic, pid) + # pylint: disable=not-callable def _on_subscribe_mqtt(self, client, user_data, topic, qos): """Runs when the client calls on_subscribe.""" diff --git a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py index a58f38c..442ca91 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py +++ b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py @@ -76,6 +76,15 @@ def disconnected(client): print("Disconnected from Adafruit IO!") +# pylint: disable=unused-argument +def publish(client, userdata, topic, pid): + # This method is called when the client publishes data to a feed. + print("Published to {0} with PID {1}".format(topic, pid)) + if userdata is not None: + print("Published User data: ", end="") + print(userdata) + + # pylint: disable=unused-argument def on_message(client, feed_id, payload): # Message function will be called when a subscribed feed has a new value. @@ -116,6 +125,7 @@ def on_battery_msg(client, topic, message): io.on_subscribe = subscribe io.on_unsubscribe = unsubscribe io.on_message = on_message +io.on_publish = publish # Connect to Adafruit IO print("Connecting to Adafruit IO...") diff --git a/examples/adafruit_io_mqtt/adafruit_io_groups.py b/examples/adafruit_io_mqtt/adafruit_io_groups.py index 15fd7d9..0634ac1 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_groups.py +++ b/examples/adafruit_io_mqtt/adafruit_io_groups.py @@ -72,6 +72,15 @@ def disconnected(client): print("Disconnected from Adafruit IO!") +# pylint: disable=unused-argument +def publish(client, userdata, topic, pid): + # This method is called when the client publishes data to a feed. + print("Published to {0} with PID {1}".format(topic, pid)) + if userdata is not None: + print("Published User data: ", end="") + print(userdata) + + # pylint: disable=unused-argument def message(client, feed_id, payload): # Message function will be called when a subscribed feed has a new value. @@ -105,6 +114,7 @@ def message(client, feed_id, payload): io.on_connect = connected io.on_disconnect = disconnected io.on_message = message +io.on_publish = publish # Group name group_name = "weatherstation" diff --git a/examples/adafruit_io_mqtt/adafruit_io_location.py b/examples/adafruit_io_mqtt/adafruit_io_location.py index f4e58f7..4b78463 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_location.py +++ b/examples/adafruit_io_mqtt/adafruit_io_location.py @@ -72,6 +72,15 @@ def disconnected(client): print("Disconnected from Adafruit IO!") +# pylint: disable=unused-argument +def publish(client, userdata, topic, pid): + # This method is called when the client publishes data to a feed. + print("Published to {0} with PID {1}".format(topic, pid)) + if userdata is not None: + print("Published User data: ", end="") + print(userdata) + + # pylint: disable=unused-argument def message(client, feed_id, payload): # Message function will be called when a subscribed feed has a new value. @@ -105,6 +114,7 @@ def message(client, feed_id, payload): io.on_connect = connected io.on_disconnect = disconnected io.on_message = message +io.on_publish = publish # Connect to Adafruit IO io.connect() diff --git a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py index 18cd1c1..0fba44a 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py +++ b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py @@ -43,17 +43,28 @@ def connected(client): print("Connected to Adafruit IO! ") +# pylint: disable=unused-argument 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)) +# pylint: disable=unused-argument +def publish(client, userdata, topic, pid): + # This method is called when the client publishes data to a feed. + print("Published to {0} with PID {1}".format(topic, pid)) + if userdata is not None: + print("Published User data: ", end="") + print(userdata) + + # 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_led_msg(client, topic, message): # Method called whenever user/feeds/led has a new value print("New message on topic {0}: {1} ".format(topic, message)) @@ -90,6 +101,7 @@ def on_led_msg(client, topic, message): io.on_connect = connected io.on_disconnect = disconnected io.on_subscribe = subscribe +io.on_publish = publish # Set up a callback for the led feed io.add_feed_callback("led", on_led_msg) diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py index bfe565b..634de5b 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py @@ -59,11 +59,13 @@ def connected(client): client.subscribe("DemoFeed") +# pylint: disable=unused-argument 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)) +# pylint: disable=unused-argument 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)) @@ -75,6 +77,15 @@ def disconnected(client): print("Disconnected from Adafruit IO!") +# pylint: disable=unused-argument +def publish(client, userdata, topic, pid): + # This method is called when the client publishes data to a feed. + print("Published to {0} with PID {1}".format(topic, pid)) + if userdata is not None: + print("Published User data: ", end="") + print(userdata) + + # pylint: disable=unused-argument def message(client, feed_id, payload): # Message function will be called when a subscribed feed has a new value. @@ -104,6 +115,7 @@ def message(client, feed_id, payload): io.on_subscribe = subscribe io.on_unsubscribe = unsubscribe io.on_message = message +io.on_publish = publish # Connect to Adafruit IO print("Connecting to Adafruit IO...") diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py index 1ecb026..e032926 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py @@ -56,11 +56,13 @@ def connected(client): client.subscribe("DemoFeed") +# pylint: disable=unused-argument 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)) +# pylint: disable=unused-argument 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)) @@ -72,6 +74,15 @@ def disconnected(client): print("Disconnected from Adafruit IO!") +# pylint: disable=unused-argument +def publish(client, userdata, topic, pid): + # This method is called when the client publishes data to a feed. + print("Published to {0} with PID {1}".format(topic, pid)) + if userdata is not None: + print("Published User data: ", end="") + print(userdata) + + # pylint: disable=unused-argument def message(client, feed_id, payload): # Message function will be called when a subscribed feed has a new value. @@ -103,6 +114,7 @@ def message(client, feed_id, payload): io.on_subscribe = subscribe io.on_unsubscribe = unsubscribe io.on_message = message +io.on_publish = publish # Connect to Adafruit IO print("Connecting to Adafruit IO...") diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index ad9bcdc..07ff0f7 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -43,11 +43,13 @@ def connected(client): client.subscribe("DemoFeed") +# pylint: disable=unused-argument 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)) +# pylint: disable=unused-argument 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)) @@ -59,6 +61,15 @@ def disconnected(client): print("Disconnected from Adafruit IO!") +# pylint: disable=unused-argument +def publish(client, userdata, topic, pid): + # This method is called when the client publishes data to a feed. + print("Published to {0} with PID {1}".format(topic, pid)) + if userdata is not None: + print("Published User data: ", end="") + print(userdata) + + # pylint: disable=unused-argument def message(client, feed_id, payload): # Message function will be called when a subscribed feed has a new value. @@ -89,6 +100,7 @@ def message(client, feed_id, payload): io.on_subscribe = subscribe io.on_unsubscribe = unsubscribe io.on_message = message +io.on_publish = publish # Connect to Adafruit IO print("Connecting to Adafruit IO...") diff --git a/examples/adafruit_io_mqtt/adafruit_io_time.py b/examples/adafruit_io_mqtt/adafruit_io_time.py index cd0ea42..d457865 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_time.py +++ b/examples/adafruit_io_mqtt/adafruit_io_time.py @@ -86,6 +86,15 @@ def disconnected(client): print("Disconnected from Adafruit IO!") +# pylint: disable=unused-argument +def publish(client, userdata, topic, pid): + # This method is called when the client publishes data to a feed. + print("Published to {0} with PID {1}".format(topic, pid)) + if userdata is not None: + print("Published User data: ", end="") + print(userdata) + + # pylint: disable=unused-argument def message(client, feed_id, payload): # Message function will be called when a subscribed feed has a new value. @@ -119,6 +128,7 @@ def message(client, feed_id, payload): io.on_connect = connected io.on_disconnect = disconnected io.on_message = message +io.on_publish = publish # Connect to Adafruit IO io.connect() diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index 85382dd..2dc56b3 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -84,6 +84,15 @@ def disconnected(client): print("Disconnected from Adafruit IO!") +# pylint: disable=unused-argument +def publish(client, userdata, topic, pid): + """This method is called when the client publishes data to a feed.""" + print(f"Published to {topic} with PID {pid}") + if userdata is not None: + print("Published User data: ", end="") + print(userdata) + + # pylint: disable=unused-argument def message(client, feed_id, payload): # Message function will be called when a subscribed feed has a new value. @@ -120,6 +129,7 @@ def message(client, feed_id, payload): io.on_subscribe = subscribe io.on_unsubscribe = unsubscribe io.on_message = message +io.on_publish = publish # Connect to Adafruit IO print("Connecting to Adafruit IO...") From 1498e285e6da21d78f07f2c529fd3c391c846979 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 16 Jul 2024 14:53:17 +0100 Subject: [PATCH 131/153] IO_HTTP: Support creating group data with `send_group_data` Fixes #97 --- adafruit_io/adafruit_io.py | 21 ++++++++++++- .../adafruit_io_http/adafruit_io_groups.py | 31 ++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 67b014c..176255c 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -631,10 +631,29 @@ def send_batch_data(self, feed_key: str, data_list: list): :param list Data: Data list to send """ validate_feed_key(feed_key) - path = "feeds/{0}/data/batch".format(feed_key) + path = self._compose_path("feeds/{0}/data/batch".format(feed_key)) data_dict = type(data_list)((data._asdict() for data in data_list)) self._post(path, {"data": data_dict}) + def send_group_data( + self, group_key: str, feeds_and_data: list, metadata: Optional[dict] = None + ): + """ + Sends data to specified Adafruit IO feeds in a group + + :param str group_key: Adafruit IO feed key + :param list feeds_and_data: A list of dicts, with feed "key" and "value" entries + :param dict metadata: Optional metadata associated with the data e.g. created_at, lat, lon, ele + """ + validate_feed_key(group_key) + path = self._compose_path("groups/{0}/data".format(group_key)) + if not isinstance(feeds_and_data, list): + raise ValueError("This method accepts a list of dicts with \"key\" and \"value\".") + if metadata is not None: + self._post(path, {**metadata, "feeds": feeds_and_data}) + else: + self._post(path, {"feeds": feeds_and_data}) + def receive_all_data(self, feed_key: str): """ Get all data values from a specified Adafruit IO feed. Data is diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index 7398605..06ac1f7 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -4,6 +4,7 @@ # Adafruit IO HTTP API - Group Interactions # Documentation: https://io.adafruit.com/api/docs/#groups # adafruit_circuitpython_adafruitio with an esp32spi_socket +import datetime import board import busio from digitalio import DigitalInOut @@ -50,6 +51,13 @@ ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) +# If you are testing on python with blinka, use real requests below and comment out above: +# import os, datetime, requests as real_requests +# from adafruit_io.adafruit_io import IO_HTTP +# secrets = {"aio_username": os.getenv("AIO_USERNAME"), "aio_key": os.getenv("AIO_KEY")} +# requests = real_requests.Session() + + # Set your Adafruit IO Username and Key in secrets.py # (visit io.adafruit.com if you need to create an account, # or if you need your Adafruit IO key.) @@ -72,8 +80,29 @@ humidity_feed = io.create_new_feed("humidity", "a feed for humidity data") io.add_feed_to_group(sensor_group["key"], humidity_feed["key"]) +# show humidity feed is in two groups +print("Getting fresh humidity feed info... (notice groups)") +print(io.get_feed(humidity_feed["key"])) + +# Publish data for multiple feeds to a group, use different timestamps for no reason +print("Publishing batch data to group feeds with created_at set 99minutes ago...") +thetime = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(minutes=99) +io.send_group_data( + group_key=sensor_group["key"], + feeds_and_data=[ + {"key": "temperature", "value": 20.0}, + {"key": "humidity", "value": 40.0}, + ], + metadata={ + "lat": 50.1858942, + "lon": -4.9677478, + "ele": 4, + "created_at": thetime.isoformat(), + }, +) + # Get info from the group -print("Getting fresh group info...") +print("Getting fresh group info... (notice created_at vs updated_at)") sensor_group = io.get_group("envsensors") # refresh data via HTTP API print(sensor_group) From 7191b1bd3196b7d6fb376f21647b3b1903e4b757 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 16 Jul 2024 14:57:44 +0100 Subject: [PATCH 132/153] formatting --- adafruit_io/adafruit_io.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 176255c..00745e2 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -648,7 +648,9 @@ def send_group_data( validate_feed_key(group_key) path = self._compose_path("groups/{0}/data".format(group_key)) if not isinstance(feeds_and_data, list): - raise ValueError("This method accepts a list of dicts with \"key\" and \"value\".") + raise ValueError( + 'This method accepts a list of dicts with "key" and "value".' + ) if metadata is not None: self._post(path, {**metadata, "feeds": feeds_and_data}) else: From 3af0502096b49004ac4c4c9def4cc33db088c00a Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 16 Jul 2024 14:59:21 +0100 Subject: [PATCH 133/153] adjust docstring --- adafruit_io/adafruit_io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 00745e2..e59b4c7 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -643,7 +643,7 @@ def send_group_data( :param str group_key: Adafruit IO feed key :param list feeds_and_data: A list of dicts, with feed "key" and "value" entries - :param dict metadata: Optional metadata associated with the data e.g. created_at, lat, lon, ele + :param dict metadata: Optional metadata for the data e.g. created_at, lat, lon, ele """ validate_feed_key(group_key) path = self._compose_path("groups/{0}/data".format(group_key)) From ac84b37052461f1c29d1aeed841b3d5688cc5714 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 16 Jul 2024 16:01:10 +0100 Subject: [PATCH 134/153] fix metadata logic + saftey check --- adafruit_io/adafruit_io.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index e59b4c7..085273c 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -652,7 +652,10 @@ def send_group_data( 'This method accepts a list of dicts with "key" and "value".' ) if metadata is not None: - self._post(path, {**metadata, "feeds": feeds_and_data}) + if not isinstance(metadata, dict): + raise ValueError("Metadata must be a dictionary.") + metadata.update({"feeds": feeds_and_data}) + self._post(path, metadata) else: self._post(path, {"feeds": feeds_and_data}) From 6e630a8f8c412a46dfa2c3b935777561fab908fd Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 16 Jul 2024 18:50:38 +0100 Subject: [PATCH 135/153] Update groups http example --- .../adafruit_io_http/adafruit_io_groups.py | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index 06ac1f7..16cedd6 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -4,7 +4,7 @@ # Adafruit IO HTTP API - Group Interactions # Documentation: https://io.adafruit.com/api/docs/#groups # adafruit_circuitpython_adafruitio with an esp32spi_socket -import datetime +import adafruit_datetime as datetime import board import busio from digitalio import DigitalInOut @@ -15,14 +15,25 @@ # Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. +# "password" keys with your WiFi credentials, along with "aio_username" and "aio_key" for +# your Adafruit IO user/key. DO NOT share that file or commit it into Git or other source control. # pylint: disable=no-name-in-module,wrong-import-order try: from secrets import secrets except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise + import os + if os.getenv("ADAFRUIT_AIO_USERNAME") and os.getenv("ADAFRUIT_AIO_KEY"): + secrets = { + "aio_username": os.getenv("ADAFRUIT_AIO_USERNAME", "Your_Username_Here"), + "aio_key": os.getenv("ADAFRUIT_AIO_KEY", "Your_Adafruit_IO_Key_Here"), + "ssid": os.getenv("CIRCUITPY_WIFI_SSID", ""), + "password": os.getenv("CIRCUITPY_WIFI_PASSWORD", ""), + } + else: + print( + "WiFi + Adafruit IO 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) @@ -46,6 +57,11 @@ continue print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) +# If you are using a wifi based mcu use this instead of esp code above, remove the from +# adafruit_esp32spi import line, optionally esp.connect(secrets["ssid"], secrets["password"]) +# import wifi +# esp = wifi.radio + # Initialize a requests session pool = adafruit_connection_manager.get_radio_socketpool(esp) ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) @@ -84,9 +100,17 @@ print("Getting fresh humidity feed info... (notice groups)") print(io.get_feed(humidity_feed["key"])) +# fetch current time +print("Fetching current time from IO... ", end="") +year, month, day, hour, minute, second, *_ = io.receive_time() +old_time = datetime.datetime(year, month, day, hour, minute, second) +print(old_time.isoformat()) + # Publish data for multiple feeds to a group, use different timestamps for no reason print("Publishing batch data to group feeds with created_at set 99minutes ago...") -thetime = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(minutes=99) +thetime = old_time - datetime.timedelta(minutes=99) +print(thetime) + io.send_group_data( group_key=sensor_group["key"], feeds_and_data=[ From 55e0adb4b7c8782d095a9e6a3f41102c4c3ff5f0 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 16 Jul 2024 18:55:07 +0100 Subject: [PATCH 136/153] formatting --- examples/adafruit_io_http/adafruit_io_groups.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index 16cedd6..5c4326f 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -22,6 +22,7 @@ from secrets import secrets except ImportError: import os + if os.getenv("ADAFRUIT_AIO_USERNAME") and os.getenv("ADAFRUIT_AIO_KEY"): secrets = { "aio_username": os.getenv("ADAFRUIT_AIO_USERNAME", "Your_Username_Here"), From 3e231a1b2fde125af309ef1a7ba6a88454862f47 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 16 Jul 2024 19:02:17 +0100 Subject: [PATCH 137/153] Correct secrets key to ADAFRUIT_AIO_USERNAME --- examples/adafruit_io_http/adafruit_io_groups.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index 5c4326f..a7f0809 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -71,7 +71,10 @@ # If you are testing on python with blinka, use real requests below and comment out above: # import os, datetime, requests as real_requests # from adafruit_io.adafruit_io import IO_HTTP -# secrets = {"aio_username": os.getenv("AIO_USERNAME"), "aio_key": os.getenv("AIO_KEY")} +# secrets = { +# "aio_username": os.getenv("ADAFRUIT_AIO_USERNAME"), +# "aio_key": os.getenv("ADAFRUIT_AIO_KEY"), +# } # requests = real_requests.Session() From 435dab5e8d245196be82af2d465cc23f765dae13 Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 16 Jul 2024 19:17:06 +0100 Subject: [PATCH 138/153] Add tz arg (TimeZone) to receive_time --- adafruit_io/adafruit_io.py | 6 +++++- examples/adafruit_io_http/adafruit_io_groups.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 085273c..ed1fc92 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -842,12 +842,16 @@ def receive_random_data(self, generator_id: int): path = self._compose_path("integrations/words/{0}".format(generator_id)) return self._get(path) - def receive_time(self): + def receive_time(self, tz: str = None): """ Returns a struct_time from the Adafruit IO Server based on the device's IP address. https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/__init__.html#time.struct_time + + :param str tz: Timezone to return the time in, see https://io.adafruit.com/services/time """ path = self._compose_path("integrations/time/struct.json") + if tz is not None: + path += "?tz={0}".format(tz) time_struct = self._get(path) return time.struct_time( ( diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index a7f0809..12ab0d6 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -106,7 +106,7 @@ # fetch current time print("Fetching current time from IO... ", end="") -year, month, day, hour, minute, second, *_ = io.receive_time() +year, month, day, hour, minute, second, *_ = io.receive_time(tz="UTC") old_time = datetime.datetime(year, month, day, hour, minute, second) print(old_time.isoformat()) From 2ebf075406735c2bf0324013980e0e5604852541 Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 16 Jul 2024 19:22:27 +0100 Subject: [PATCH 139/153] improve docstring and link tz list --- adafruit_io/adafruit_io.py | 1 + 1 file changed, 1 insertion(+) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index ed1fc92..b185465 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -848,6 +848,7 @@ def receive_time(self, tz: str = None): https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/__init__.html#time.struct_time :param str tz: Timezone to return the time in, see https://io.adafruit.com/services/time + default is based on the device's IP address being geolocated, falling back to UTC. """ path = self._compose_path("integrations/time/struct.json") if tz is not None: From 479afd4e3ac9bd52a78617d4204f2381e7a116f2 Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 16 Jul 2024 19:24:53 +0100 Subject: [PATCH 140/153] Update argument name from tz to timezone --- adafruit_io/adafruit_io.py | 8 ++++---- examples/adafruit_io_http/adafruit_io_groups.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index b185465..5bf34dc 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -842,17 +842,17 @@ def receive_random_data(self, generator_id: int): path = self._compose_path("integrations/words/{0}".format(generator_id)) return self._get(path) - def receive_time(self, tz: str = None): + def receive_time(self, timezone: str = None): """ Returns a struct_time from the Adafruit IO Server based on the device's IP address. https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/__init__.html#time.struct_time - :param str tz: Timezone to return the time in, see https://io.adafruit.com/services/time + :param str timezone: Timezone to return the time in, see https://io.adafruit.com/services/time default is based on the device's IP address being geolocated, falling back to UTC. """ path = self._compose_path("integrations/time/struct.json") - if tz is not None: - path += "?tz={0}".format(tz) + if timezone is not None: + path += "?tz={0}".format(timezone) time_struct = self._get(path) return time.struct_time( ( diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index 12ab0d6..2e1754b 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -106,7 +106,7 @@ # fetch current time print("Fetching current time from IO... ", end="") -year, month, day, hour, minute, second, *_ = io.receive_time(tz="UTC") +year, month, day, hour, minute, second, *_ = io.receive_time(timezone="UTC") old_time = datetime.datetime(year, month, day, hour, minute, second) print(old_time.isoformat()) From 89765af9ca4e99cf65526611d58c30707e5b3520 Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 16 Jul 2024 19:28:38 +0100 Subject: [PATCH 141/153] satisfy pylint --- adafruit_io/adafruit_io.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 5bf34dc..308f5e9 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -847,7 +847,7 @@ def receive_time(self, timezone: str = None): Returns a struct_time from the Adafruit IO Server based on the device's IP address. https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/__init__.html#time.struct_time - :param str timezone: Timezone to return the time in, see https://io.adafruit.com/services/time + :param str timezone: Timezone to return time in, see https://io.adafruit.com/services/time default is based on the device's IP address being geolocated, falling back to UTC. """ path = self._compose_path("integrations/time/struct.json") @@ -855,6 +855,7 @@ def receive_time(self, timezone: str = None): path += "?tz={0}".format(timezone) time_struct = self._get(path) return time.struct_time( + # pylint: disable=line-too-long ( time_struct["year"], time_struct["mon"], From 7d7485032f1f81d70dfebdd79d7144ec4de6941c Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 16 Jul 2024 19:34:38 +0100 Subject: [PATCH 142/153] Cleanup timezone doctstring for pylint --- adafruit_io/adafruit_io.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 308f5e9..d780c6f 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -846,9 +846,10 @@ def receive_time(self, timezone: str = None): """ Returns a struct_time from the Adafruit IO Server based on the device's IP address. https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/__init__.html#time.struct_time + The default time returned is based on the device's IP address being geolocated, + falling back to UTC if unable to be geolocated. The timezone can be manually set. :param str timezone: Timezone to return time in, see https://io.adafruit.com/services/time - default is based on the device's IP address being geolocated, falling back to UTC. """ path = self._compose_path("integrations/time/struct.json") if timezone is not None: From e0998f0ffd31d11b79ce724a21db4a25d51a8800 Mon Sep 17 00:00:00 2001 From: tyeth Date: Tue, 16 Jul 2024 21:09:32 +0100 Subject: [PATCH 143/153] Add list of dicts support to send_batch_data --- adafruit_io/adafruit_io.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index ea38556..3f385ff 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -636,12 +636,17 @@ def send_batch_data(self, feed_key: str, data_list: list): Sends a batch array of data to a specified Adafruit IO feed :param str feed_key: Adafruit IO feed key - :param list Data: Data list to send + :param list Data: Data list to send (namedtuples or dicts with 'value' key) """ validate_feed_key(feed_key) + if not isinstance(data_list, list) or data_list == []: + raise ValueError("Data must be a list of dicts or namedtuples") + if not isinstance(data_list[0], dict): # assume namedtuple + data_list = type(data_list)((data._asdict() for data in data_list)) + if not all("value" in data for data in data_list): + raise ValueError("Data list items must at least contain a 'value' key") path = self._compose_path("feeds/{0}/data/batch".format(feed_key)) - data_dict = type(data_list)((data._asdict() for data in data_list)) - self._post(path, {"data": data_dict}) + self._post(path, {"data": data_list}) def send_group_data( self, group_key: str, feeds_and_data: list, metadata: Optional[dict] = None From 26c459fee107ef3ccc738eac3d311ab961244785 Mon Sep 17 00:00:00 2001 From: Tyeth Gundry Date: Tue, 16 Jul 2024 21:13:24 +0100 Subject: [PATCH 144/153] format whitespace --- adafruit_io/adafruit_io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 3f385ff..8325b01 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -641,7 +641,7 @@ def send_batch_data(self, feed_key: str, data_list: list): validate_feed_key(feed_key) if not isinstance(data_list, list) or data_list == []: raise ValueError("Data must be a list of dicts or namedtuples") - if not isinstance(data_list[0], dict): # assume namedtuple + if not isinstance(data_list[0], dict): # assume namedtuple data_list = type(data_list)((data._asdict() for data in data_list)) if not all("value" in data for data in data_list): raise ValueError("Data list items must at least contain a 'value' key") From 41e858b2e6e8df604c317e1371e958073cd4e996 Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 18 Jul 2024 12:27:19 +0100 Subject: [PATCH 145/153] Add batch example --- .../adafruit_io_batch_cpython.py | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 examples/adafruit_io_http/adafruit_io_batch_cpython.py diff --git a/examples/adafruit_io_http/adafruit_io_batch_cpython.py b/examples/adafruit_io_http/adafruit_io_batch_cpython.py new file mode 100644 index 0000000..6249f26 --- /dev/null +++ b/examples/adafruit_io_http/adafruit_io_batch_cpython.py @@ -0,0 +1,82 @@ +# SPDX-FileCopyrightText: 2024 Tyeth Gundry for Adafruit Industries +# SPDX-License-Identifier: MIT + +# adafruit_circuitpython_adafruitio usage for batch data with a CPython socket. +import datetime +import socket +import ssl +from random import randint +import adafruit_requests +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError + +# Add a secrets.py to your filesystem that has a dictionary called secrets with "aio_username" +# and "aio_key" entries with your IO credentials, or set environment variables/defaults below. +# *** DO NOT share that file or commit it into Git or other source control. *** +# pylint: disable=no-name-in-module,wrong-import-order +try: + from secrets import secrets +except ImportError: + import os + + secrets = { + "aio_username": os.getenv("ADAFRUIT_AIO_USERNAME", "Your_Username_Here"), + "aio_key": os.getenv("ADAFRUIT_AIO_KEY", "Your_Adafruit_IO_Key_Here"), + } + if ( + secrets["aio_key"] == "Your_Adafruit_IO_Key_Here" + or secrets["aio_username"] == "Your_Username_Here" + ): + print("Adafruit IO secrets are kept in secrets.py, please add them there!") + raise + +# Set your Adafruit IO Username and Key in secrets.py +# (visit io.adafruit.com if you need to create an account, +# or if you need your Adafruit IO key.) +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + + +requests = adafruit_requests.Session(socket, ssl.create_default_context()) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) + +try: + # Get the 'temperature' feed from Adafruit IO + temperature_feed = io.get_feed("batch-temperature") +except AdafruitIO_RequestError: + # If no 'temperature' feed exists, create one + temperature_feed = io.create_new_feed("batch-temperature") + +# Get current time from Adafruit IO time service (in UTC) +years, months, days, hours, minutes, seconds, *_ = io.receive_time("UTC") +current_time = datetime.datetime(years, months, days, hours, minutes, seconds) +print("Current time from Adafruit IO: ", current_time) + +# Create random values at different timestamps to send to the feed +data = [] +for i in range(5): + random_value = randint(0, 50) + time_offset = i - 5 + created_at = current_time + datetime.timedelta(seconds=time_offset) + print( + "Adding datapoint {0} (at T:{1}) to collection for batch-temperature feed...".format( + random_value, time_offset + ) + ) + data.append({"value": random_value, "created_at": created_at.isoformat()}) + +# Send the data to the feed as a single batch +io.send_batch_data(temperature_feed["key"], data) +print("Data sent!") +print() +print( + "View your feed graph at: https://io.adafruit.com/{0}/feeds/{1}".format( + aio_username, temperature_feed["key"] + ) +) +print() + +# Retrieve data value from the feed +print("Retrieving data from batch-temperature feed...") +received_data = io.receive_data(temperature_feed["key"]) +print("Data from temperature feed: ", received_data["value"]) From b85b8e261c67fc022ed9582b6a520ba6a33a087e Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 18 Jul 2024 12:32:23 +0100 Subject: [PATCH 146/153] Adjust line endings for batch example --- .../adafruit_io_batch_cpython.py | 164 +++++++++--------- 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_batch_cpython.py b/examples/adafruit_io_http/adafruit_io_batch_cpython.py index 6249f26..8c994c4 100644 --- a/examples/adafruit_io_http/adafruit_io_batch_cpython.py +++ b/examples/adafruit_io_http/adafruit_io_batch_cpython.py @@ -1,82 +1,82 @@ -# SPDX-FileCopyrightText: 2024 Tyeth Gundry for Adafruit Industries -# SPDX-License-Identifier: MIT - -# adafruit_circuitpython_adafruitio usage for batch data with a CPython socket. -import datetime -import socket -import ssl -from random import randint -import adafruit_requests -from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError - -# Add a secrets.py to your filesystem that has a dictionary called secrets with "aio_username" -# and "aio_key" entries with your IO credentials, or set environment variables/defaults below. -# *** DO NOT share that file or commit it into Git or other source control. *** -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - import os - - secrets = { - "aio_username": os.getenv("ADAFRUIT_AIO_USERNAME", "Your_Username_Here"), - "aio_key": os.getenv("ADAFRUIT_AIO_KEY", "Your_Adafruit_IO_Key_Here"), - } - if ( - secrets["aio_key"] == "Your_Adafruit_IO_Key_Here" - or secrets["aio_username"] == "Your_Username_Here" - ): - print("Adafruit IO secrets are kept in secrets.py, please add them there!") - raise - -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - - -requests = adafruit_requests.Session(socket, ssl.create_default_context()) -# Initialize an Adafruit IO HTTP API object -io = IO_HTTP(aio_username, aio_key, requests) - -try: - # Get the 'temperature' feed from Adafruit IO - temperature_feed = io.get_feed("batch-temperature") -except AdafruitIO_RequestError: - # If no 'temperature' feed exists, create one - temperature_feed = io.create_new_feed("batch-temperature") - -# Get current time from Adafruit IO time service (in UTC) -years, months, days, hours, minutes, seconds, *_ = io.receive_time("UTC") -current_time = datetime.datetime(years, months, days, hours, minutes, seconds) -print("Current time from Adafruit IO: ", current_time) - -# Create random values at different timestamps to send to the feed -data = [] -for i in range(5): - random_value = randint(0, 50) - time_offset = i - 5 - created_at = current_time + datetime.timedelta(seconds=time_offset) - print( - "Adding datapoint {0} (at T:{1}) to collection for batch-temperature feed...".format( - random_value, time_offset - ) - ) - data.append({"value": random_value, "created_at": created_at.isoformat()}) - -# Send the data to the feed as a single batch -io.send_batch_data(temperature_feed["key"], data) -print("Data sent!") -print() -print( - "View your feed graph at: https://io.adafruit.com/{0}/feeds/{1}".format( - aio_username, temperature_feed["key"] - ) -) -print() - -# Retrieve data value from the feed -print("Retrieving data from batch-temperature feed...") -received_data = io.receive_data(temperature_feed["key"]) -print("Data from temperature feed: ", received_data["value"]) +# SPDX-FileCopyrightText: 2024 Tyeth Gundry for Adafruit Industries +# SPDX-License-Identifier: MIT + +# adafruit_circuitpython_adafruitio usage for batch data with a CPython socket. +import datetime +import socket +import ssl +from random import randint +import adafruit_requests +from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError + +# Add a secrets.py to your filesystem that has a dictionary called secrets with "aio_username" +# and "aio_key" entries with your IO credentials, or set environment variables/defaults below. +# *** DO NOT share that file or commit it into Git or other source control. *** +# pylint: disable=no-name-in-module,wrong-import-order +try: + from secrets import secrets +except ImportError: + import os + + secrets = { + "aio_username": os.getenv("ADAFRUIT_AIO_USERNAME", "Your_Username_Here"), + "aio_key": os.getenv("ADAFRUIT_AIO_KEY", "Your_Adafruit_IO_Key_Here"), + } + if ( + secrets["aio_key"] == "Your_Adafruit_IO_Key_Here" + or secrets["aio_username"] == "Your_Username_Here" + ): + print("Adafruit IO secrets are kept in secrets.py, please add them there!") + raise + +# Set your Adafruit IO Username and Key in secrets.py +# (visit io.adafruit.com if you need to create an account, +# or if you need your Adafruit IO key.) +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + + +requests = adafruit_requests.Session(socket, ssl.create_default_context()) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) + +try: + # Get the 'temperature' feed from Adafruit IO + temperature_feed = io.get_feed("batch-temperature") +except AdafruitIO_RequestError: + # If no 'temperature' feed exists, create one + temperature_feed = io.create_new_feed("batch-temperature") + +# Get current time from Adafruit IO time service (in UTC) +years, months, days, hours, minutes, seconds, *_ = io.receive_time("UTC") +current_time = datetime.datetime(years, months, days, hours, minutes, seconds) +print("Current time from Adafruit IO: ", current_time) + +# Create random values at different timestamps to send to the feed +data = [] +for i in range(5): + random_value = randint(0, 50) + time_offset = i - 5 + created_at = current_time + datetime.timedelta(seconds=time_offset) + print( + "Adding datapoint {0} (at T:{1}) to collection for batch-temperature feed...".format( + random_value, time_offset + ) + ) + data.append({"value": random_value, "created_at": created_at.isoformat()}) + +# Send the data to the feed as a single batch +io.send_batch_data(temperature_feed["key"], data) +print("Data sent!") +print() +print( + "View your feed graph at: https://io.adafruit.com/{0}/feeds/{1}".format( + aio_username, temperature_feed["key"] + ) +) +print() + +# Retrieve data value from the feed +print("Retrieving data from batch-temperature feed...") +received_data = io.receive_data(temperature_feed["key"]) +print("Data from temperature feed: ", received_data["value"]) From a83c183f965b593bc3046840474a594df570ba76 Mon Sep 17 00:00:00 2001 From: tyeth Date: Thu, 18 Jul 2024 12:47:56 +0100 Subject: [PATCH 147/153] explain optional metadata arguments --- examples/adafruit_io_http/adafruit_io_batch_cpython.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/adafruit_io_http/adafruit_io_batch_cpython.py b/examples/adafruit_io_http/adafruit_io_batch_cpython.py index 8c994c4..16835a9 100644 --- a/examples/adafruit_io_http/adafruit_io_batch_cpython.py +++ b/examples/adafruit_io_http/adafruit_io_batch_cpython.py @@ -63,7 +63,12 @@ random_value, time_offset ) ) - data.append({"value": random_value, "created_at": created_at.isoformat()}) + data.append( + { + "value": random_value, + "created_at": created_at.isoformat(), # optional metadata like lat, lon, ele, etc + } + ) # Send the data to the feed as a single batch io.send_batch_data(temperature_feed["key"], data) From 6d7abbc2269679f223171c002cf7a03ee501f74d Mon Sep 17 00:00:00 2001 From: tyeth Date: Mon, 5 Aug 2024 15:44:22 +0100 Subject: [PATCH 148/153] Add Current User info methods + convenience methods for get_throttle_limit and get_remaining_throttle_limit Return User Usage Limits / Current Usage towards Throttle Limits with `get_user_rate_info` Return full account info with `get_user_info` Fixes #126 --- .pylintrc | 2 +- adafruit_io/adafruit_io.py | 71 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/.pylintrc b/.pylintrc index f945e92..ddbd91f 100644 --- a/.pylintrc +++ b/.pylintrc @@ -55,7 +55,7 @@ confidence= # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" # disable=import-error,raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,deprecated-str-translate-call -disable=raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,import-error,pointless-string-statement,unspecified-encoding +disable=raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,import-error,pointless-string-statement,unspecified-encoding,too-many-public-methods # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 8325b01..3099d27 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -855,6 +855,77 @@ def receive_random_data(self, generator_id: int): path = self._compose_path("integrations/words/{0}".format(generator_id)) return self._get(path) + def get_user_info(self): + """ + Get detailed account information for the current user. + + See https://io.adafruit.com/api/docs/#get-user-info + """ + return self._get("https://io.adafruit.com/api/v2/user") + + def get_user_rate_info(self): + """ + Get rate limit and usage information for the current user. + + See https://io.adafruit.com/api/docs/#get-detailed-user-info + + Example output: + ``` + { + "data_rate_limit": 30, + "active_data_rate": 0, + "authentication_rate": 0, + "subscribe_authorization_rate": 0, + "publish_authorization_rate": 0, + "hourly_ban_rate": 0, + "mqtt_ban_error_message": null, + "active_sms_rate": 0 + } + ``` + """ + path = self._compose_path("throttle") + return self._get(path) + + def get_remaining_throttle_limit(self): + """ + Get the remaining data points allowed before hitting the throttle limit. + This retrieves the user rate limit and deducts usage for the current user. + + See https://io.adafruit.com/api/docs/#get-detailed-user-info + """ + user_rates = self.get_user_rate_info() + if user_rates is None: + raise ValueError( + "Could not get user info, get_user_rate_info returned None." + ) + return user_rates["data_rate_limit"] - user_rates["active_data_rate"] + + def get_throttle_limit(self): + """ + Get user throttle limit a.k.a "data_rate_limit" for the current user. + + See https://io.adafruit.com/api/docs/#get-detailed-user-info + """ + user_rates = self.get_user_rate_info() + if user_rates is None: + raise ValueError( + "Could not get user info, get_user_rate_info returned None." + ) + return user_rates["data_rate_limit"] + + def get_current_usage(self): + """ + Get current rate usage a.k.a "active_data_rate" for the current user. + + See https://io.adafruit.com/api/docs/#get-detailed-user-info + """ + user_rates = self.get_user_rate_info() + if user_rates is None: + raise ValueError( + "Could not get user info, get_user_rate_info returned None." + ) + return user_rates["active_data_rate"] + def receive_time(self, timezone: str = None): """ Returns a struct_time from the Adafruit IO Server based on the device's IP address. From 69b05015660adbe9321a91b2ff0620f645a8f284 Mon Sep 17 00:00:00 2001 From: tyeth Date: Fri, 4 Oct 2024 16:31:03 +0100 Subject: [PATCH 149/153] Add example for get_user_rate_info --- .../adafruit_io_http/adafruit_io_user_info.py | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 examples/adafruit_io_http/adafruit_io_user_info.py diff --git a/examples/adafruit_io_http/adafruit_io_user_info.py b/examples/adafruit_io_http/adafruit_io_user_info.py new file mode 100644 index 0000000..3351311 --- /dev/null +++ b/examples/adafruit_io_http/adafruit_io_user_info.py @@ -0,0 +1,62 @@ +# SPDX-FileCopyrightText: 2024 Tyeth Gundry for Adafruit Industries +# SPDX-License-Identifier: MIT + +# retrieve user rate info via adafruit_circuitpython_adafruitio with native wifi networking +import ssl +import time # pylint: disable=unused-import +import adafruit_requests +import socketpool +import wifi +from adafruit_io.adafruit_io import IO_HTTP + +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. + +# pylint: disable=no-name-in-module,wrong-import-order +try: + from secrets import secrets +except ImportError: + print("WiFi secrets are kept in secrets.py, please add them there!") + raise + +# Set your Adafruit IO Username and Key in secrets.py +# (visit io.adafruit.com if you need to create an account, +# or if you need your Adafruit IO key.) +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + +print("Connecting to %s" % secrets["ssid"]) +wifi.radio.connect(secrets["ssid"], secrets["password"]) +print("Connected to %s!" % secrets["ssid"]) + + +pool = socketpool.SocketPool(wifi.radio) +requests = adafruit_requests.Session(pool, ssl.create_default_context()) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) + +print("===============\nUser Rate info:\n===============") +print("\n".join([f"{k:<30}\t=\t{v}" for (k, v) in io.get_user_rate_info().items()])) + +print(f"Throttle limit: {io.get_throttle_limit()}") +print(f"Remaining throttle limit: {io.get_remaining_throttle_limit()}") + + +# # Uncomment these lines to retrieve all user info as one big json object: +# print("Waiting 5seconds before fetching full user info (a lot of JSON output)") +# time.sleep(5) +# try: +# print("\n\nFull User info:") +# print(io.get_user_info()) +# except MemoryError as me: +# print( +# "Board ran out of memory when processing all that user info json." +# + "This is expected on most boards (ESP32-S3 should work)" +# ) +# raise me +# except Exception as e: +# print("Unexpected error!") +# raise e + +print("\n\nDone!") From ece3e396ccb5504558f6b11423a96d06a6dfb5c9 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Mon, 7 Oct 2024 09:24:05 -0500 Subject: [PATCH 150/153] remove deprecated get_html_theme_path() call Signed-off-by: foamyguy --- docs/conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 82edab7..089b753 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -97,7 +97,6 @@ import sphinx_rtd_theme html_theme = "sphinx_rtd_theme" -html_theme_path = [sphinx_rtd_theme.get_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, From 48fb3ae95b99814f6e6829c19084cd9257303112 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 14 Jan 2025 11:32:34 -0600 Subject: [PATCH 151/153] add sphinx configuration to rtd.yaml Signed-off-by: foamyguy --- .readthedocs.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 33c2a61..88bca9f 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -8,6 +8,9 @@ # Required version: 2 +sphinx: + configuration: docs/conf.py + build: os: ubuntu-20.04 tools: From ea7c397d640edd6960acaa01909cb9a7b3172f43 Mon Sep 17 00:00:00 2001 From: Justin Myers Date: Sun, 23 Feb 2025 08:25:35 -0800 Subject: [PATCH 152/153] Remove secrets usage --- .../adafruit_io_http/adafruit_io_analog_in.py | 24 +++----- .../adafruit_io_batch_cpython.py | 33 +++-------- .../adafruit_io_create_and_get_feed.py | 37 +++++-------- .../adafruit_io_digital_out.py | 24 +++----- .../adafruit_io_http/adafruit_io_feeds.py | 24 +++----- .../adafruit_io_http/adafruit_io_groups.py | 44 +++------------ .../adafruit_io_http/adafruit_io_metadata.py | 24 +++----- .../adafruit_io_randomizer.py | 24 +++----- .../adafruit_io_simpletest.py | 37 +++++-------- .../adafruit_io_simpletest_cpython.py | 23 +++----- .../adafruit_io_simpletest_esp32spi.py | 24 +++----- .../adafruit_io_temperature.py | 24 +++----- .../adafruit_io_http/adafruit_io_user_info.py | 38 +++++-------- .../adafruit_io_http/adafruit_io_weather.py | 24 +++----- .../adafruit_io_feed_callback.py | 30 +++++----- .../adafruit_io_mqtt/adafruit_io_groups.py | 29 +++++----- .../adafruit_io_mqtt/adafruit_io_location.py | 31 ++++++----- .../adafruit_io_pubsub_rp2040.py | 21 +++---- .../adafruit_io_simpletest_cellular.py | 20 ++++--- .../adafruit_io_simpletest_esp32s2.py | 55 ++++++------------- .../adafruit_io_simpletest_eth.py | 17 +++--- examples/adafruit_io_mqtt/adafruit_io_time.py | 30 +++++----- examples/adafruit_io_simpletest.py | 31 ++++++----- 23 files changed, 258 insertions(+), 410 deletions(-) diff --git a/examples/adafruit_io_http/adafruit_io_analog_in.py b/examples/adafruit_io_http/adafruit_io_analog_in.py index fe327e5..bbbda7d 100644 --- a/examples/adafruit_io_http/adafruit_io_analog_in.py +++ b/examples/adafruit_io_http/adafruit_io_analog_in.py @@ -3,6 +3,7 @@ # Example of publishing the value of an ADC to Adafruit IO # adafruit_circuitpython_adafruitio with an esp32spi_socket +from os import getenv import time import board import busio @@ -13,15 +14,12 @@ import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -39,7 +37,7 @@ print("Connecting to AP...") while not esp.is_connected: try: - esp.connect_AP(secrets["ssid"], secrets["password"]) + esp.connect_AP(ssid, password) except RuntimeError as e: print("could not connect to AP, retrying: ", e) continue @@ -50,12 +48,6 @@ ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) diff --git a/examples/adafruit_io_http/adafruit_io_batch_cpython.py b/examples/adafruit_io_http/adafruit_io_batch_cpython.py index 16835a9..4423fad 100644 --- a/examples/adafruit_io_http/adafruit_io_batch_cpython.py +++ b/examples/adafruit_io_http/adafruit_io_batch_cpython.py @@ -3,38 +3,19 @@ # adafruit_circuitpython_adafruitio usage for batch data with a CPython socket. import datetime +from os import getenv import socket import ssl from random import randint import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# Add a secrets.py to your filesystem that has a dictionary called secrets with "aio_username" -# and "aio_key" entries with your IO credentials, or set environment variables/defaults below. -# *** DO NOT share that file or commit it into Git or other source control. *** -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - import os - - secrets = { - "aio_username": os.getenv("ADAFRUIT_AIO_USERNAME", "Your_Username_Here"), - "aio_key": os.getenv("ADAFRUIT_AIO_KEY", "Your_Adafruit_IO_Key_Here"), - } - if ( - secrets["aio_key"] == "Your_Adafruit_IO_Key_Here" - or secrets["aio_username"] == "Your_Username_Here" - ): - print("Adafruit IO secrets are kept in secrets.py, please add them there!") - raise - -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") requests = adafruit_requests.Session(socket, ssl.create_default_context()) # Initialize an Adafruit IO HTTP API object diff --git a/examples/adafruit_io_http/adafruit_io_create_and_get_feed.py b/examples/adafruit_io_http/adafruit_io_create_and_get_feed.py index 7b687f6..0eac01b 100644 --- a/examples/adafruit_io_http/adafruit_io_create_and_get_feed.py +++ b/examples/adafruit_io_http/adafruit_io_create_and_get_feed.py @@ -4,37 +4,28 @@ Example using create_and_get_feed. Creates a new feed if it does not exist and sends to it, or sends to an existing feed once it has been created. """ -import ssl +from os import getenv import adafruit_requests -import socketpool import wifi import microcontroller +import adafruit_connection_manager from adafruit_io.adafruit_io import IO_HTTP -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials, and "aio_username" and "aio_key" keys with your -# Adafruit IO credentials, DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print( - "WiFi and Adafruit IO credentials are kept in secrets.py, please add them there!" - ) - raise +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") -# Connect to Wi-Fi using credentials from secrets.py -wifi.radio.connect(secrets["ssid"], secrets["password"]) -print("Connected to {}!".format(secrets["ssid"])) +# Connect to Wi-Fi using credentials from settings.toml +wifi.radio.connect(ssid, password) +print("Connected to {}!".format(ssid)) print("IP:", wifi.radio.ipv4_address) -pool = socketpool.SocketPool(wifi.radio) -requests = adafruit_requests.Session(pool, ssl.create_default_context()) - -# Obtain Adafruit IO credentials from secrets.py -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] +pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio) +requests = adafruit_requests.Session(pool, ssl_context) # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) diff --git a/examples/adafruit_io_http/adafruit_io_digital_out.py b/examples/adafruit_io_http/adafruit_io_digital_out.py index 6a1ee04..5385b39 100644 --- a/examples/adafruit_io_http/adafruit_io_digital_out.py +++ b/examples/adafruit_io_http/adafruit_io_digital_out.py @@ -4,6 +4,7 @@ # Turn on and off a LED from your Adafruit IO Dashboard. # adafruit_circuitpython_adafruitio with an esp32spi_socket import time +from os import getenv import board import busio from digitalio import DigitalInOut, Direction @@ -12,15 +13,12 @@ import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -38,7 +36,7 @@ print("Connecting to AP...") while not esp.is_connected: try: - esp.connect_AP(secrets["ssid"], secrets["password"]) + esp.connect_AP(ssid, password) except RuntimeError as e: print("could not connect to AP, retrying: ", e) continue @@ -49,12 +47,6 @@ ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) diff --git a/examples/adafruit_io_http/adafruit_io_feeds.py b/examples/adafruit_io_http/adafruit_io_feeds.py index 7637a06..ea4874c 100644 --- a/examples/adafruit_io_http/adafruit_io_feeds.py +++ b/examples/adafruit_io_http/adafruit_io_feeds.py @@ -4,6 +4,7 @@ # Adafruit IO HTTP API - Feed Interactions # Documentation: https://io.adafruit.com/api/docs/#feeds # adafruit_circuitpython_adafruitio with an esp32spi_socket +from os import getenv import board import busio from digitalio import DigitalInOut @@ -12,15 +13,12 @@ import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -38,7 +36,7 @@ print("Connecting to AP...") while not esp.is_connected: try: - esp.connect_AP(secrets["ssid"], secrets["password"]) + esp.connect_AP(ssid, password) except RuntimeError as e: print("could not connect to AP, retrying: ", e) continue @@ -49,12 +47,6 @@ ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index 2e1754b..5911f33 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -4,6 +4,7 @@ # Adafruit IO HTTP API - Group Interactions # Documentation: https://io.adafruit.com/api/docs/#groups # adafruit_circuitpython_adafruitio with an esp32spi_socket +from os import getenv import adafruit_datetime as datetime import board import busio @@ -13,28 +14,12 @@ import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP - -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials, along with "aio_username" and "aio_key" for -# your Adafruit IO user/key. DO NOT share that file or commit it into Git or other source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - import os - - if os.getenv("ADAFRUIT_AIO_USERNAME") and os.getenv("ADAFRUIT_AIO_KEY"): - secrets = { - "aio_username": os.getenv("ADAFRUIT_AIO_USERNAME", "Your_Username_Here"), - "aio_key": os.getenv("ADAFRUIT_AIO_KEY", "Your_Adafruit_IO_Key_Here"), - "ssid": os.getenv("CIRCUITPY_WIFI_SSID", ""), - "password": os.getenv("CIRCUITPY_WIFI_PASSWORD", ""), - } - else: - print( - "WiFi + Adafruit IO secrets are kept in secrets.py, please add them there!" - ) - raise +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -52,14 +37,14 @@ print("Connecting to AP...") while not esp.is_connected: try: - esp.connect_AP(secrets["ssid"], secrets["password"]) + esp.connect_AP(ssid, password) except RuntimeError as e: print("could not connect to AP, retrying: ", e) continue print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) # If you are using a wifi based mcu use this instead of esp code above, remove the from -# adafruit_esp32spi import line, optionally esp.connect(secrets["ssid"], secrets["password"]) +# adafruit_esp32spi import line, optionally esp.connect(ssid, password) # import wifi # esp = wifi.radio @@ -71,19 +56,8 @@ # If you are testing on python with blinka, use real requests below and comment out above: # import os, datetime, requests as real_requests # from adafruit_io.adafruit_io import IO_HTTP -# secrets = { -# "aio_username": os.getenv("ADAFRUIT_AIO_USERNAME"), -# "aio_key": os.getenv("ADAFRUIT_AIO_KEY"), -# } # requests = real_requests.Session() - -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) diff --git a/examples/adafruit_io_http/adafruit_io_metadata.py b/examples/adafruit_io_http/adafruit_io_metadata.py index 9bf27d5..de6c339 100644 --- a/examples/adafruit_io_http/adafruit_io_metadata.py +++ b/examples/adafruit_io_http/adafruit_io_metadata.py @@ -3,6 +3,7 @@ # Adafruit IO HTTP API - Sending values with optional metadata # adafruit_circuitpython_adafruitio with an esp32spi_socket +from os import getenv import board import busio from digitalio import DigitalInOut @@ -11,15 +12,12 @@ import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -37,7 +35,7 @@ print("Connecting to AP...") while not esp.is_connected: try: - esp.connect_AP(secrets["ssid"], secrets["password"]) + esp.connect_AP(ssid, password) except RuntimeError as e: print("could not connect to AP, retrying: ", e) continue @@ -48,12 +46,6 @@ ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) diff --git a/examples/adafruit_io_http/adafruit_io_randomizer.py b/examples/adafruit_io_http/adafruit_io_randomizer.py index 920bf01..a7b46db 100644 --- a/examples/adafruit_io_http/adafruit_io_randomizer.py +++ b/examples/adafruit_io_http/adafruit_io_randomizer.py @@ -4,6 +4,7 @@ # Example for using Adafruit IO's random data (randomizer) service # adafruit_circuitpython_adafruitio with an esp32spi_socket import time +from os import getenv import board import busio from digitalio import DigitalInOut @@ -12,15 +13,12 @@ import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -38,7 +36,7 @@ print("Connecting to AP...") while not esp.is_connected: try: - esp.connect_AP(secrets["ssid"], secrets["password"]) + esp.connect_AP(ssid, password) except RuntimeError as e: print("could not connect to AP, retrying: ", e) continue @@ -49,12 +47,6 @@ ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) diff --git a/examples/adafruit_io_http/adafruit_io_simpletest.py b/examples/adafruit_io_http/adafruit_io_simpletest.py index 836e0be..1d0b8a1 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest.py @@ -2,36 +2,27 @@ # SPDX-License-Identifier: MIT # adafruit_circuitpython_adafruitio usage with native wifi networking -import ssl +from os import getenv from random import randint import adafruit_requests -import socketpool import wifi +import adafruit_connection_manager from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise - -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - -print("Connecting to %s" % secrets["ssid"]) -wifi.radio.connect(secrets["ssid"], secrets["password"]) -print("Connected to %s!" % secrets["ssid"]) +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") +print("Connecting to %s" % ssid) +wifi.radio.connect(ssid, password) +print("Connected to %s!" % ssid) -pool = socketpool.SocketPool(wifi.radio) -requests = adafruit_requests.Session(pool, ssl.create_default_context()) +pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio) +requests = adafruit_requests.Session(pool, ssl_context) # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) diff --git a/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py b/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py index 52f5031..dd5ac50 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py @@ -2,28 +2,19 @@ # SPDX-License-Identifier: MIT # adafruit_circuitpython_adafruitio usage with a CPython socket +from os import getenv import socket import ssl from random import randint import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise - -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") requests = adafruit_requests.Session(socket, ssl.create_default_context()) # Initialize an Adafruit IO HTTP API object diff --git a/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py b/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py index 0fe2df4..a7e0ac0 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: MIT # adafruit_circuitpython_adafruitio usage with an esp32spi_socket +from os import getenv from random import randint import board import busio @@ -11,15 +12,12 @@ import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -37,7 +35,7 @@ print("Connecting to AP...") while not esp.is_connected: try: - esp.connect_AP(secrets["ssid"], secrets["password"]) + esp.connect_AP(ssid, password) except RuntimeError as e: print("could not connect to AP, retrying: ", e) continue @@ -48,12 +46,6 @@ ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) diff --git a/examples/adafruit_io_http/adafruit_io_temperature.py b/examples/adafruit_io_http/adafruit_io_temperature.py index 989260e..969ad90 100644 --- a/examples/adafruit_io_http/adafruit_io_temperature.py +++ b/examples/adafruit_io_http/adafruit_io_temperature.py @@ -4,6 +4,7 @@ # Example of sending ADT7410 sensor temperature values to IO # adafruit_circuitpython_adafruitio with an esp32spi_socket import time +from os import getenv import board import busio from digitalio import DigitalInOut @@ -13,15 +14,12 @@ import adafruit_adt7410 from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -39,7 +37,7 @@ print("Connecting to AP...") while not esp.is_connected: try: - esp.connect_AP(secrets["ssid"], secrets["password"]) + esp.connect_AP(ssid, password) except RuntimeError as e: print("could not connect to AP, retrying: ", e) continue @@ -50,12 +48,6 @@ ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) diff --git a/examples/adafruit_io_http/adafruit_io_user_info.py b/examples/adafruit_io_http/adafruit_io_user_info.py index 3351311..fe9a0f6 100644 --- a/examples/adafruit_io_http/adafruit_io_user_info.py +++ b/examples/adafruit_io_http/adafruit_io_user_info.py @@ -2,37 +2,27 @@ # SPDX-License-Identifier: MIT # retrieve user rate info via adafruit_circuitpython_adafruitio with native wifi networking -import ssl +from os import getenv import time # pylint: disable=unused-import import adafruit_requests -import socketpool import wifi +import adafruit_connection_manager from adafruit_io.adafruit_io import IO_HTTP -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise +print("Connecting to %s" % ssid) +wifi.radio.connect(ssid, password) +print("Connected to %s!" % ssid) -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - -print("Connecting to %s" % secrets["ssid"]) -wifi.radio.connect(secrets["ssid"], secrets["password"]) -print("Connected to %s!" % secrets["ssid"]) - - -pool = socketpool.SocketPool(wifi.radio) -requests = adafruit_requests.Session(pool, ssl.create_default_context()) +pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio) +requests = adafruit_requests.Session(pool, ssl_context) # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) diff --git a/examples/adafruit_io_http/adafruit_io_weather.py b/examples/adafruit_io_http/adafruit_io_weather.py index 376cf83..5731858 100644 --- a/examples/adafruit_io_http/adafruit_io_weather.py +++ b/examples/adafruit_io_http/adafruit_io_weather.py @@ -3,6 +3,7 @@ # Example of using the Adafruit IO+ Weather Service # adafruit_circuitpython_adafruitio with an esp32spi_socket +from os import getenv import board import busio from digitalio import DigitalInOut @@ -11,15 +12,12 @@ import adafruit_requests from adafruit_io.adafruit_io import IO_HTTP -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - from secrets import secrets -except ImportError: - print("WiFi secrets are kept in secrets.py, please add them there!") - raise +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -37,7 +35,7 @@ print("Connecting to AP...") while not esp.is_connected: try: - esp.connect_AP(secrets["ssid"], secrets["password"]) + esp.connect_AP(ssid, password) except RuntimeError as e: print("could not connect to AP, retrying: ", e) continue @@ -48,12 +46,6 @@ ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] - # Initialize an Adafruit IO HTTP API object io = IO_HTTP(aio_username, aio_key, requests) diff --git a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py index 442ca91..594fe71 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py +++ b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT import time - +from os import getenv import board import busio from digitalio import DigitalInOut @@ -13,14 +13,14 @@ import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT -### WiFi ### +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") -# 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 +### WiFi ### # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -35,19 +35,21 @@ 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( +status_pixel = 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) +# status_pixel = 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) +# status_pixel = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) +wifi = adafruit_esp32spi_wifimanager.WiFiManager( + esp, ssid, password, status_pixel=status_pixel +) # Define callback functions which will be called when certain events happen. @@ -110,8 +112,8 @@ def on_battery_msg(client, topic, message): mqtt_client = MQTT.MQTT( broker="io.adafruit.com", port=1883, - username=secrets["aio_username"], - password=secrets["aio_key"], + username=aio_username, + password=aio_key, socket_pool=pool, ssl_context=ssl_context, ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_groups.py b/examples/adafruit_io_mqtt/adafruit_io_groups.py index 0634ac1..7294fd7 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_groups.py +++ b/examples/adafruit_io_mqtt/adafruit_io_groups.py @@ -4,6 +4,7 @@ # Subscribing to an Adafruit IO Group # and Publishing to the feeds in the group import time +from os import getenv from random import randint import board @@ -16,14 +17,14 @@ import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT -### WiFi ### +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") -# 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 +### WiFi ### # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -38,19 +39,21 @@ 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( +status_pixel = 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) +# status_pixel = 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) +# status_pixel = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) +wifi = adafruit_esp32spi_wifimanager.WiFiManager( + esp, ssid, password, status_pixel=status_pixel +) # Define callback functions which will be called when certain events happen. @@ -101,8 +104,8 @@ def message(client, feed_id, payload): mqtt_client = MQTT.MQTT( broker="io.adafruit.com", port=1883, - username=secrets["aio_username"], - password=secrets["aio_key"], + username=aio_username, + password=aio_key, socket_pool=pool, ssl_context=ssl_context, ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_location.py b/examples/adafruit_io_mqtt/adafruit_io_location.py index 4b78463..b2a1d8c 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_location.py +++ b/examples/adafruit_io_mqtt/adafruit_io_location.py @@ -4,6 +4,7 @@ # Example of tagging data with location values # and sending it to an Adafruit IO feed. import time +from os import getenv import board import busio from digitalio import DigitalInOut @@ -11,19 +12,17 @@ from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager import neopixel - - import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT -### WiFi ### +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") -# 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 +### WiFi ### # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -38,19 +37,21 @@ 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( +status_pixel = 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) +# status_pixel = 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) +# status_pixel = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) +wifi = adafruit_esp32spi_wifimanager.WiFiManager( + esp, ssid, password, status_pixel=status_pixel +) # Define callback functions which will be called when certain events happen. @@ -101,8 +102,8 @@ def message(client, feed_id, payload): mqtt_client = MQTT.MQTT( broker="io.adafruit.com", port=1883, - username=secrets["aio_username"], - password=secrets["aio_key"], + username=aio_username, + password=aio_key, socket_pool=pool, ssl_context=ssl_context, ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py index 0fba44a..d4c1258 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py +++ b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: MIT import time +from os import getenv from microcontroller import cpu import board import busio @@ -12,14 +13,14 @@ import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT -### WiFi ### +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") -# 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 +### WiFi ### # Raspberry Pi RP2040 esp32_cs = DigitalInOut(board.GP13) @@ -29,7 +30,7 @@ spi = busio.SPI(board.GP10, board.GP11, board.GP12) esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) -wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets) +wifi = adafruit_esp32spi_wifimanager.WiFiManager(esp, ssid, password) # Configure the RP2040 Pico LED Pin as an output led_pin = DigitalInOut(board.LED) @@ -88,8 +89,8 @@ def on_led_msg(client, topic, message): mqtt_client = MQTT.MQTT( broker="io.adafruit.com", port=1883, - username=secrets["aio_username"], - password=secrets["aio_key"], + username=aio_username, + password=aio_key, socket_pool=pool, ssl_context=ssl_context, ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py index 634de5b..3c0b314 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py @@ -6,6 +6,7 @@ # to subscribe to an Adafruit IO feed and publish random data # to be received by the feed. import time +from os import getenv from random import randint import board @@ -20,12 +21,13 @@ import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT -# Get MQTT details and more from a secrets.py file -try: - from secrets import secrets -except ImportError: - print("MQTT secrets are kept in secrets.py, please add them there!") - raise +# Get Fona details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +apn = getenv("apn") +apn_username = getenv("apn_username") +apn_password = getenv("apn_password") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") # Create a serial connection for the FONA connection uart = busio.UART(board.TX, board.RX) @@ -35,7 +37,7 @@ fona = FONA(uart, rst) # initialize gsm -gsm = GSM(fona, (secrets["apn"], secrets["apn_username"], secrets["apn_password"])) +gsm = GSM(fona, (apn, apn_username, apn_password)) while not gsm.is_attached: print("Attaching to network...") @@ -100,8 +102,8 @@ def message(client, feed_id, payload): mqtt_client = MQTT.MQTT( broker="io.adafruit.com", port=1883, - username=secrets["aio_username"], - password=secrets["aio_key"], + username=aio_username, + password=aio_key, socket_pool=pool, ssl_context=ssl_context, ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py index e032926..e308c27 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py @@ -1,47 +1,27 @@ # SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT import time +from os import getenv from random import randint -import os -import ssl -import socketpool import wifi +import adafruit_connection_manager import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT -### WiFi ### +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") -# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and -# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other -# source control. -# pylint: disable=no-name-in-module,wrong-import-order -try: - if os.getenv("AIO_USERNAME") and os.getenv("AIO_KEY"): - secrets = { - "aio_username": os.getenv("AIO_USERNAME"), - "aio_key": os.getenv("AIO_KEY"), - "ssid": os.getenv("CIRCUITPY_WIFI_SSID"), - "password": os.getenv("CIRCUITPY_WIFI_PASSWORD"), - } - else: - from secrets import secrets -except ImportError: - print( - "WiFi + Adafruit IO secrets are kept in secrets.py or settings.toml, please add them there!" - ) - raise - -# Set your Adafruit IO Username and Key in secrets.py -# (visit io.adafruit.com if you need to create an account, -# or if you need your Adafruit IO key.) -aio_username = secrets["aio_username"] -aio_key = secrets["aio_key"] +### WiFi ### if not wifi.radio.connected: - print("Connecting to %s" % secrets["ssid"]) - wifi.radio.connect(secrets["ssid"], secrets["password"]) - print("Connected to %s!" % secrets["ssid"]) + print("Connecting to %s" % ssid) + wifi.radio.connect(ssid, password) + print("Connected to %s!" % ssid) # Define callback functions which will be called when certain events happen. @@ -91,17 +71,18 @@ def message(client, feed_id, payload): print("Feed {0} received new value: {1}".format(feed_id, payload)) -# Create a socket pool -pool = socketpool.SocketPool(wifi.radio) +# Create a socket pool and ssl_context +pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio) +ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio) # Initialize a new MQTT Client object mqtt_client = MQTT.MQTT( broker="io.adafruit.com", port=8883, - username=secrets["aio_username"], - password=secrets["aio_key"], + username=aio_username, + password=aio_key, socket_pool=pool, - ssl_context=ssl.create_default_context(), + ssl_context=ssl_context, is_ssl=True, ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index 07ff0f7..b502983 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -6,6 +6,7 @@ # to subscribe to an Adafruit IO feed and publish random data # to be received by the feed. import time +from os import getenv from random import randint import board @@ -17,12 +18,12 @@ import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT -# Get MQTT details and more from a secrets.py file -try: - from secrets import secrets -except ImportError: - print("MQTT secrets are kept in secrets.py, please add them there!") - raise +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") cs = DigitalInOut(board.D10) spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) @@ -85,8 +86,8 @@ def message(client, feed_id, payload): mqtt_client = MQTT.MQTT( broker="io.adafruit.com", port=1883, - username=secrets["aio_username"], - password=secrets["aio_key"], + username=aio_username, + password=aio_key, socket_pool=pool, ssl_context=ssl_context, ) diff --git a/examples/adafruit_io_mqtt/adafruit_io_time.py b/examples/adafruit_io_mqtt/adafruit_io_time.py index d457865..e2b69a6 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_time.py +++ b/examples/adafruit_io_mqtt/adafruit_io_time.py @@ -5,6 +5,7 @@ # for obtaining the current server time, if you don't have # access to a RTC module. import time +from os import getenv import board import busio from digitalio import DigitalInOut @@ -12,18 +13,17 @@ from adafruit_esp32spi import adafruit_esp32spi from adafruit_esp32spi import adafruit_esp32spi_wifimanager import neopixel - import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT -### WiFi ### +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") -# 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 +### WiFi ### # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -38,19 +38,21 @@ 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( +status_pixel = 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) +# status_pixel = 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) +# status_pixel = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) +wifi = adafruit_esp32spi_wifimanager.WiFiManager( + esp, ssid, password, status_pixel=status_pixel +) # Define callback functions which will be called when certain events happen. @@ -115,8 +117,8 @@ def message(client, feed_id, payload): mqtt_client = MQTT.MQTT( broker="io.adafruit.com", port=1883, - username=secrets["aio_username"], - password=secrets["aio_key"], + username=aio_username, + password=aio_key, socket_pool=pool, ssl_context=ssl_context, ) diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index 2dc56b3..702f3ca 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -6,9 +6,8 @@ # to subscribe to an Adafruit IO feed and publish random data # to be received by the feed. import time +from os import getenv from random import randint - - import board import busio from digitalio import DigitalInOut @@ -19,14 +18,14 @@ import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT -### WiFi ### +# Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml +# (visit io.adafruit.com if you need to create an account, or if you need your Adafruit IO key.) +ssid = getenv("CIRCUITPY_WIFI_SSID") +password = getenv("CIRCUITPY_WIFI_PASSWORD") +aio_username = getenv("ADAFRUIT_AIO_USERNAME") +aio_key = getenv("ADAFRUIT_AIO_KEY") -# 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 +### WiFi ### # If you are using a board with pre-defined ESP32 Pins: esp32_cs = DigitalInOut(board.ESP_CS) @@ -41,19 +40,21 @@ 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( +status_pixel = 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) +# status_pixel = 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) +# status_pixel = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) +wifi = adafruit_esp32spi_wifimanager.WiFiManager( + esp, ssid, password, status_pixel=status_pixel +) # Define callback functions which will be called when certain events happen. @@ -113,8 +114,8 @@ def message(client, feed_id, payload): mqtt_client = MQTT.MQTT( broker="io.adafruit.com", port=1883, - username=secrets["aio_username"], - password=secrets["aio_key"], + username=aio_username, + password=aio_key, socket_pool=pool, ssl_context=ssl_context, ) From 9c3630cbb59dd52d54ee7c6811e86c402dff34d2 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Thu, 15 May 2025 19:49:37 +0000 Subject: [PATCH 153/153] change to ruff --- .gitattributes | 11 + .pre-commit-config.yaml | 43 +- .pylintrc | 399 ------------------ README.rst | 6 +- adafruit_io/adafruit_io.py | 141 +++---- adafruit_io/adafruit_io_errors.py | 6 +- docs/api.rst | 3 + docs/conf.py | 8 +- .../adafruit_io_http/adafruit_io_analog_in.py | 10 +- .../adafruit_io_batch_cpython.py | 8 +- .../adafruit_io_create_and_get_feed.py | 11 +- .../adafruit_io_digital_out.py | 8 +- .../adafruit_io_http/adafruit_io_feeds.py | 8 +- .../adafruit_io_http/adafruit_io_groups.py | 8 +- .../adafruit_io_http/adafruit_io_metadata.py | 8 +- .../adafruit_io_randomizer.py | 8 +- .../adafruit_io_simpletest.py | 6 +- .../adafruit_io_simpletest_cpython.py | 6 +- .../adafruit_io_simpletest_esp32spi.py | 10 +- .../adafruit_io_temperature.py | 12 +- .../adafruit_io_http/adafruit_io_user_info.py | 6 +- .../adafruit_io_http/adafruit_io_weather.py | 14 +- .../adafruit_io_feed_callback.py | 33 +- .../adafruit_io_mqtt/adafruit_io_groups.py | 30 +- .../adafruit_io_mqtt/adafruit_io_location.py | 27 +- .../adafruit_io_pubsub_rp2040.py | 22 +- .../adafruit_io_simpletest_cellular.py | 23 +- .../adafruit_io_simpletest_esp32s2.py | 19 +- .../adafruit_io_simpletest_eth.py | 22 +- examples/adafruit_io_mqtt/adafruit_io_time.py | 27 +- examples/adafruit_io_simpletest.py | 31 +- ruff.toml | 107 +++++ 32 files changed, 351 insertions(+), 730 deletions(-) create mode 100644 .gitattributes delete mode 100644 .pylintrc create mode 100644 ruff.toml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..21c125c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2024 Justin Myers for Adafruit Industries +# +# SPDX-License-Identifier: Unlicense + +.py text eol=lf +.rst text eol=lf +.txt text eol=lf +.yaml text eol=lf +.toml text eol=lf +.license text eol=lf +.md text eol=lf diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 70ade69..ff19dde 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,42 +1,21 @@ -# SPDX-FileCopyrightText: 2020 Diego Elio Pettenò +# SPDX-FileCopyrightText: 2024 Justin Myers for Adafruit Industries # # SPDX-License-Identifier: Unlicense repos: - - repo: https://github.com/python/black - rev: 23.3.0 - hooks: - - id: black - - repo: https://github.com/fsfe/reuse-tool - rev: v1.1.2 - hooks: - - id: reuse - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - - repo: https://github.com/pycqa/pylint - rev: v2.17.4 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.3.4 hooks: - - id: pylint - name: pylint (library code) - types: [python] - args: - - --disable=consider-using-f-string - exclude: "^(docs/|examples/|tests/|setup.py$)" - - id: pylint - name: pylint (example code) - description: Run pylint rules on "examples/*.py" files - types: [python] - files: "^examples/" - args: - - --disable=missing-docstring,invalid-name,consider-using-f-string,duplicate-code - - id: pylint - name: pylint (test code) - description: Run pylint rules on "tests/*.py" files - types: [python] - files: "^tests/" - args: - - --disable=missing-docstring,consider-using-f-string,duplicate-code + - id: ruff-format + - id: ruff + args: ["--fix"] + - repo: https://github.com/fsfe/reuse-tool + rev: v3.0.1 + hooks: + - id: reuse diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index ddbd91f..0000000 --- a/.pylintrc +++ /dev/null @@ -1,399 +0,0 @@ -# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries -# -# SPDX-License-Identifier: Unlicense - -[MASTER] - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code -extension-pkg-whitelist= - -# Add files or directories to the ignore-list. They should be base names, not -# paths. -ignore=CVS - -# Add files or directories matching the regex patterns to the ignore-list. The -# regex matches against base names, not paths. -ignore-patterns= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Use multiple processes to speed up Pylint. -jobs=1 - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins=pylint.extensions.no_self_use - -# Pickle collected data for later comparisons. -persistent=yes - -# Specify a configuration file. -#rcfile= - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once).You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use"--disable=all --enable=classes -# --disable=W" -# disable=import-error,raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,deprecated-str-translate-call -disable=raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,import-error,pointless-string-statement,unspecified-encoding,too-many-public-methods - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable= - - -[REPORTS] - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details -#msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio).You can also give a reporter class, eg -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Tells whether to display a full report or only the messages -reports=no - -# Activate the evaluation score. -score=yes - - -[REFACTORING] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - - -[LOGGING] - -# Logging modules to check that the string format arguments are in logging -# function parameter format -logging-modules=logging - - -[SPELLING] - -# Spelling dictionary name. Available dictionaries: none. To make it working -# install python-enchant package. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to indicated private dictionary in -# --spelling-private-dict-file option instead of raising a message. -spelling-store-unknown-words=no - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -# notes=FIXME,XXX,TODO -notes=FIXME,XXX - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis. It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules=board - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - - -[VARIABLES] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_,_cb - -# A regular expression matching the name of dummy variables (i.e. expectedly -# not used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.*|^ignored_|^unused_ - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,future.builtins - - -[FORMAT] - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -# expected-line-ending-format= -expected-line-ending-format=LF - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Maximum number of characters on a single line. -max-line-length=100 - -# Maximum number of lines in a module -max-module-lines=1000 - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -single-line-class-stmt=no - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - - -[SIMILARITIES] - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=yes - -# Minimum lines number of a similarity. -min-similarity-lines=12 - - -[BASIC] - -# Regular expression matching correct argument names -argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Regular expression matching correct attribute names -attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata - -# Regular expression matching correct class attribute names -class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Regular expression matching correct class names -# class-rgx=[A-Z_][a-zA-Z0-9]+$ -class-rgx=[A-Z_][a-zA-Z0-9_]+$ - -# Regular expression matching correct constant names -const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - -# Regular expression matching correct function names -function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Good variable names which should always be accepted, separated by a comma -# good-names=i,j,k,ex,Run,_ -good-names=r,g,b,w,i,j,k,n,x,y,z,ex,ok,Run,_ - -# Include a hint for the correct naming format with invalid-name -include-naming-hint=no - -# Regular expression matching correct inline iteration names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Regular expression matching correct method names -method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Regular expression matching correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -property-classes=abc.abstractproperty - -# Regular expression matching correct variable names -variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - - -[IMPORTS] - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=no - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=optparse,tkinter.tix - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict,_fields,_replace,_source,_make - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs - - -[DESIGN] - -# Maximum number of arguments for function / method -max-args=5 - -# Maximum number of attributes for a class (see R0902). -# max-attributes=7 -max-attributes=11 - -# Maximum number of boolean expressions in a if statement -max-bool-expr=5 - -# Maximum number of branch for function / method body -max-branches=12 - -# Maximum number of locals for function / method body -max-locals=15 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of statements in function / method body -max-statements=50 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=1 - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=builtins.Exception diff --git a/README.rst b/README.rst index 8ed057a..e6bb3cb 100644 --- a/README.rst +++ b/README.rst @@ -13,9 +13,9 @@ Adafruit_CircuitPython_AdafruitIO :target: https://github.com/adafruit/Adafruit_CircuitPython_AdafruitIO/actions/ :alt: Build Status -.. image:: https://img.shields.io/badge/code%20style-black-000000.svg - :target: https://github.com/psf/black - :alt: Code Style: Black +.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json + :target: https://github.com/astral-sh/ruff + :alt: Code Style: Ruff CircuitPython wrapper library for communicating with `Adafruit IO `_. diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 3099d27..0117adf 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -18,26 +18,28 @@ * Adafruit CircuitPython firmware for the supported boards: https://github.com/adafruit/circuitpython/releases """ -import time + import json import re +import time try: - from typing import List, Any, Callable, Optional + from typing import Any, Callable, List, Optional except ImportError: pass from adafruit_minimqtt.adafruit_minimqtt import MMQTTException + from adafruit_io.adafruit_io_errors import ( + AdafruitIO_MQTTError, AdafruitIO_RequestError, AdafruitIO_ThrottleError, - AdafruitIO_MQTTError, ) __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_AdafruitIO.git" -CLIENT_HEADERS = {"User-Agent": "AIO-CircuitPython/{0}".format(__version__)} +CLIENT_HEADERS = {"User-Agent": f"AIO-CircuitPython/{__version__}"} def validate_feed_key(feed_key: str): @@ -75,23 +77,18 @@ class IO_MQTT: :param MiniMQTT mqtt_client: MiniMQTT Client object. """ - # pylint: disable=protected-access def __init__(self, mqtt_client): # Check for MiniMQTT client mqtt_client_type = str(type(mqtt_client)) if "MQTT" in mqtt_client_type: self._client = mqtt_client else: - raise TypeError( - "This class requires a MiniMQTT client object, please create one." - ) + raise TypeError("This class requires a MiniMQTT client object, please create one.") # Adafruit IO MQTT API MUST require a username try: self._user = self._client._username except Exception as err: - raise TypeError( - "Adafruit IO requires a username, please set one in MiniMQTT" - ) from err + raise TypeError("Adafruit IO requires a username, please set one in MiniMQTT") from err # User-defined MQTT callback methods must be init'd to None self.on_connect = None self.on_disconnect = None @@ -143,7 +140,6 @@ def is_connected(self): except MMQTTException: return False - # pylint: disable=not-callable, unused-argument def _on_connect_mqtt(self, client, userdata, flags, return_code): """Runs when the client calls on_connect.""" if return_code == 0: @@ -154,7 +150,6 @@ def _on_connect_mqtt(self, client, userdata, flags, return_code): if self.on_connect is not None: self.on_connect(self) - # pylint: disable=not-callable, unused-argument def _on_disconnect_mqtt(self, client, userdata, return_code): """Runs when the client calls on_disconnect.""" self._connected = False @@ -162,7 +157,6 @@ def _on_disconnect_mqtt(self, client, userdata, return_code): if self.on_disconnect is not None: self.on_disconnect(self) - # pylint: disable=not-callable def _on_message_mqtt(self, client, topic: str, payload: str): """Runs when the client calls on_message. Parses and returns incoming data from Adafruit IO feeds. @@ -198,24 +192,19 @@ def _on_message_mqtt(self, client, topic: str, payload: str): topic_name = topic_name[2] message = payload else: - raise ValueError( - "You must define an on_message method before calling this callback." - ) + raise ValueError("You must define an on_message method before calling this callback.") self.on_message(self, topic_name, message) - # pylint: disable=not-callable, unused-argument def _on_publish_mqtt(self, client, user_data, topic, pid): """Runs when the client calls on_publish.""" if self.on_publish is not None: self.on_publish(self, user_data, topic, pid) - # pylint: disable=not-callable def _on_subscribe_mqtt(self, client, user_data, topic, qos): """Runs when the client calls 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.""" if self.on_unsubscribe is not None: @@ -233,9 +222,7 @@ def add_feed_callback(self, feed_key: str, callback_method: Callable): :param str callback_method: Name of callback method. """ validate_feed_key(feed_key) - self._client.add_topic_callback( - "{0}/f/{1}".format(self._user, feed_key), callback_method - ) + self._client.add_topic_callback(f"{self._user}/f/{feed_key}", callback_method) def remove_feed_callback(self, feed_key: str): """Removes a previously registered callback method @@ -247,7 +234,7 @@ def remove_feed_callback(self, feed_key: str): :param str feed_key: Adafruit IO feed key. """ validate_feed_key(feed_key) - self._client.remove_topic_callback("{0}/f/{1}".format(self._user, feed_key)) + self._client.remove_topic_callback(f"{self._user}/f/{feed_key}") def loop(self, timeout=1): """Manually process messages from Adafruit IO. @@ -286,13 +273,13 @@ def subscribe( """ if shared_user is not None and feed_key is not None: validate_feed_key(feed_key) - self._client.subscribe("{0}/f/{1}".format(shared_user, feed_key)) + self._client.subscribe(f"{shared_user}/f/{feed_key}") elif group_key is not None: validate_feed_key(group_key) - self._client.subscribe("{0}/g/{1}".format(self._user, group_key)) + self._client.subscribe(f"{self._user}/g/{group_key}") elif feed_key is not None: validate_feed_key(feed_key) - self._client.subscribe("{0}/f/{1}".format(self._user, feed_key)) + self._client.subscribe(f"{self._user}/f/{feed_key}") else: raise AdafruitIO_MQTTError("Must provide a feed_key or group_key.") @@ -313,9 +300,7 @@ def subscribe_to_randomizer(self, randomizer_id: int): :param int randomizer_id: Random word record you want data for. """ - self._client.subscribe( - "{0}/integration/words/{1}".format(self._user, randomizer_id) - ) + self._client.subscribe(f"{self._user}/integration/words/{randomizer_id}") def subscribe_to_weather(self, weather_record: int, forecast: str): """Subscribes to a weather forecast using the Adafruit IO PLUS weather @@ -324,11 +309,7 @@ def subscribe_to_weather(self, weather_record: int, forecast: str): :param int weather_record: Weather record you want data for. :param str forecast: Forecast data you'd like to recieve. """ - self._client.subscribe( - "{0}/integration/weather/{1}/{2}".format( - self._user, weather_record, forecast - ) - ) + self._client.subscribe(f"{self._user}/integration/weather/{weather_record}/{forecast}") def subscribe_to_time(self, time_type: str): """Adafruit IO provides some built-in MQTT topics for getting the current server time. @@ -370,20 +351,18 @@ def unsubscribe( """ if shared_user is not None and feed_key is not None: validate_feed_key(feed_key) - self._client.unsubscribe("{0}/f/{1}".format(shared_user, feed_key)) + self._client.unsubscribe(f"{shared_user}/f/{feed_key}") elif group_key is not None: validate_feed_key(group_key) - self._client.unsubscribe("{0}/g/{1}".format(self._user, group_key)) + self._client.unsubscribe(f"{self._user}/g/{group_key}") elif feed_key is not None: validate_feed_key(feed_key) - self._client.unsubscribe("{0}/f/{1}".format(self._user, feed_key)) + self._client.unsubscribe(f"{self._user}/f/{feed_key}") else: raise AdafruitIO_MQTTError("Must provide a feed_key or group_key.") # Publishing - def publish_multiple( - self, feeds_and_data: List, timeout: int = 3, is_group: bool = False - ): + def publish_multiple(self, feeds_and_data: List, timeout: int = 3, is_group: bool = False): """Publishes multiple data points to multiple feeds or groups with a variable timeout. @@ -410,7 +389,6 @@ def publish_multiple( self.publish(topic, data) time.sleep(timeout) - # pylint: disable=too-many-arguments def publish( self, feed_key: str, @@ -471,18 +449,16 @@ def publish( """ validate_feed_key(feed_key) if is_group: - self._client.publish("{0}/g/{1}".format(self._user, feed_key), data) + self._client.publish(f"{self._user}/g/{feed_key}", data) if shared_user is not None: - self._client.publish("{0}/f/{1}".format(shared_user, feed_key), data) + self._client.publish(f"{shared_user}/f/{feed_key}", data) if metadata is not None: if isinstance(data, int or float): data = str(data) csv_string = data + "," + metadata - self._client.publish( - "{0}/f/{1}/csv".format(self._user, feed_key), csv_string - ) + self._client.publish(f"{self._user}/f/{feed_key}/csv", csv_string) else: - self._client.publish("{0}/f/{1}".format(self._user, feed_key), data) + self._client.publish(f"{self._user}/f/{feed_key}", data) def get(self, feed_key: str): """Calling this method will make Adafruit IO publish the most recent @@ -498,7 +474,7 @@ def get(self, feed_key: str): io.get('temperature') """ validate_feed_key(feed_key) - self._client.publish("{0}/f/{1}/get".format(self._user, feed_key), "\0") + self._client.publish(f"{self._user}/f/{feed_key}/get", "\0") class IO_HTTP: @@ -558,7 +534,7 @@ def _compose_path(self, path: str): :param str path: Adafruit IO API URL path. """ - return "https://io.adafruit.com/api/v2/{0}/{1}".format(self.username, path) + return f"https://io.adafruit.com/api/v2/{self.username}/{path}" # HTTP Requests def _post(self, path: str, payload: Any): @@ -582,9 +558,7 @@ def _get(self, path: str): :param str path: Formatted Adafruit IO URL from _compose_path """ - with self._http.get( - path, headers=self._create_headers(self._aio_headers[1]) - ) as response: + with self._http.get(path, headers=self._create_headers(self._aio_headers[1])) as response: self._handle_error(response) json_data = response.json() return json_data @@ -620,14 +594,12 @@ def send_data( :param int precision: Optional amount of precision points to send with floating point data """ validate_feed_key(feed_key) - path = self._compose_path("feeds/{0}/data".format(feed_key)) + path = self._compose_path(f"feeds/{feed_key}/data") if precision: try: data = round(data, precision) except NotImplementedError as err: # received a non-float value - raise NotImplementedError( - "Precision requires a floating point value" - ) from err + raise NotImplementedError("Precision requires a floating point value") from err payload = self._create_data(data, metadata) self._post(path, payload) @@ -642,10 +614,10 @@ def send_batch_data(self, feed_key: str, data_list: list): if not isinstance(data_list, list) or data_list == []: raise ValueError("Data must be a list of dicts or namedtuples") if not isinstance(data_list[0], dict): # assume namedtuple - data_list = type(data_list)((data._asdict() for data in data_list)) + data_list = type(data_list)(data._asdict() for data in data_list) if not all("value" in data for data in data_list): raise ValueError("Data list items must at least contain a 'value' key") - path = self._compose_path("feeds/{0}/data/batch".format(feed_key)) + path = self._compose_path(f"feeds/{feed_key}/data/batch") self._post(path, {"data": data_list}) def send_group_data( @@ -659,11 +631,9 @@ def send_group_data( :param dict metadata: Optional metadata for the data e.g. created_at, lat, lon, ele """ validate_feed_key(group_key) - path = self._compose_path("groups/{0}/data".format(group_key)) + path = self._compose_path(f"groups/{group_key}/data") if not isinstance(feeds_and_data, list): - raise ValueError( - 'This method accepts a list of dicts with "key" and "value".' - ) + raise ValueError('This method accepts a list of dicts with "key" and "value".') if metadata is not None: if not isinstance(metadata, dict): raise ValueError("Metadata must be a dictionary.") @@ -680,7 +650,7 @@ def receive_all_data(self, feed_key: str): :param str feed_key: Adafruit IO feed key """ validate_feed_key(feed_key) - path = self._compose_path("feeds/{0}/data".format(feed_key)) + path = self._compose_path(f"feeds/{feed_key}/data") return self._get(path) def receive_n_data(self, feed_key: str, n_values: int): @@ -693,7 +663,7 @@ def receive_n_data(self, feed_key: str, n_values: int): """ validate_n_values(n_values) validate_feed_key(feed_key) - path = self._compose_path("feeds/{0}/data?limit={1}".format(feed_key, n_values)) + path = self._compose_path(f"feeds/{feed_key}/data?limit={n_values}") return self._get(path) def receive_data(self, feed_key: str): @@ -703,7 +673,7 @@ def receive_data(self, feed_key: str): :param string feed_key: Adafruit IO feed key """ validate_feed_key(feed_key) - path = self._compose_path("feeds/{0}/data/last".format(feed_key)) + path = self._compose_path(f"feeds/{feed_key}/data/last") return self._get(path) def delete_data(self, feed_key: str, data_id: str): @@ -714,7 +684,7 @@ def delete_data(self, feed_key: str, data_id: str): :param string data_id: Data point to delete from the feed """ validate_feed_key(feed_key) - path = self._compose_path("feeds/{0}/data/{1}".format(feed_key, data_id)) + path = self._compose_path(f"feeds/{feed_key}/data/{data_id}") return self._delete(path) # Groups @@ -735,7 +705,7 @@ def delete_group(self, group_key: str): :param str group_key: Adafruit IO Group Key """ - path = self._compose_path("groups/{0}".format(group_key)) + path = self._compose_path(f"groups/{group_key}") return self._delete(path) def get_group(self, group_key: str): @@ -744,7 +714,7 @@ def get_group(self, group_key: str): :param str group_key: Adafruit IO Group Key """ - path = self._compose_path("groups/{0}".format(group_key)) + path = self._compose_path(f"groups/{group_key}") return self._get(path) def create_feed_in_group(self, group_key: str, feed_name: str): @@ -753,7 +723,7 @@ def create_feed_in_group(self, group_key: str, feed_name: str): :param str group_key: Group name. :param str feed_name: Name of new feed. """ - path = self._compose_path("groups/{0}/feeds".format(group_key)) + path = self._compose_path(f"groups/{group_key}/feeds") payload = {"feed": {"name": feed_name}} return self._post(path, payload) @@ -765,7 +735,7 @@ def add_feed_to_group(self, group_key: str, feed_key: str): :param str feed_key: Feed to add to the group """ validate_feed_key(feed_key) - path = self._compose_path("groups/{0}/add".format(group_key)) + path = self._compose_path(f"groups/{group_key}/add") payload = {"feed_key": feed_key} return self._post(path, payload) @@ -779,9 +749,9 @@ def get_feed(self, feed_key: str, detailed: bool = False): """ validate_feed_key(feed_key) if detailed: - path = self._compose_path("feeds/{0}/details".format(feed_key)) + path = self._compose_path(f"feeds/{feed_key}/details") else: - path = self._compose_path("feeds/{0}".format(feed_key)) + path = self._compose_path(f"feeds/{feed_key}") return self._get(path) def create_new_feed( @@ -820,9 +790,7 @@ def create_and_get_feed( try: return self.get_feed(feed_key, detailed=detailed) except AdafruitIO_RequestError: - self.create_new_feed( - feed_key, feed_desc=feed_desc, feed_license=feed_license - ) + self.create_new_feed(feed_key, feed_desc=feed_desc, feed_license=feed_license) return self.get_feed(feed_key, detailed=detailed) def delete_feed(self, feed_key: str): @@ -832,7 +800,7 @@ def delete_feed(self, feed_key: str): :param str feed_key: Valid feed key """ validate_feed_key(feed_key) - path = self._compose_path("feeds/{0}".format(feed_key)) + path = self._compose_path(f"feeds/{feed_key}") return self._delete(path) # Adafruit IO Connected Services @@ -843,7 +811,7 @@ def receive_weather(self, weather_id: int): :param int weather_id: ID for retrieving a specified weather record. """ - path = self._compose_path("integrations/weather/{0}".format(weather_id)) + path = self._compose_path(f"integrations/weather/{weather_id}") return self._get(path) def receive_random_data(self, generator_id: int): @@ -852,7 +820,7 @@ def receive_random_data(self, generator_id: int): :param int generator_id: Specified randomizer record """ - path = self._compose_path("integrations/words/{0}".format(generator_id)) + path = self._compose_path(f"integrations/words/{generator_id}") return self._get(path) def get_user_info(self): @@ -895,9 +863,7 @@ def get_remaining_throttle_limit(self): """ user_rates = self.get_user_rate_info() if user_rates is None: - raise ValueError( - "Could not get user info, get_user_rate_info returned None." - ) + raise ValueError("Could not get user info, get_user_rate_info returned None.") return user_rates["data_rate_limit"] - user_rates["active_data_rate"] def get_throttle_limit(self): @@ -908,9 +874,7 @@ def get_throttle_limit(self): """ user_rates = self.get_user_rate_info() if user_rates is None: - raise ValueError( - "Could not get user info, get_user_rate_info returned None." - ) + raise ValueError("Could not get user info, get_user_rate_info returned None.") return user_rates["data_rate_limit"] def get_current_usage(self): @@ -921,9 +885,7 @@ def get_current_usage(self): """ user_rates = self.get_user_rate_info() if user_rates is None: - raise ValueError( - "Could not get user info, get_user_rate_info returned None." - ) + raise ValueError("Could not get user info, get_user_rate_info returned None.") return user_rates["active_data_rate"] def receive_time(self, timezone: str = None): @@ -937,10 +899,9 @@ def receive_time(self, timezone: str = None): """ path = self._compose_path("integrations/time/struct.json") if timezone is not None: - path += "?tz={0}".format(timezone) + path += f"?tz={timezone}" time_struct = self._get(path) return time.struct_time( - # pylint: disable=line-too-long ( time_struct["year"], time_struct["mon"], diff --git a/adafruit_io/adafruit_io_errors.py b/adafruit_io/adafruit_io_errors.py index c35c836..f3b256a 100755 --- a/adafruit_io/adafruit_io_errors.py +++ b/adafruit_io/adafruit_io_errors.py @@ -20,13 +20,11 @@ class AdafruitIO_RequestError(Exception): def __init__(self, response): response_content = response.json() error = response_content["error"] - super().__init__( - "Adafruit IO Error {0}: {1}".format(response.status_code, error) - ) + super().__init__(f"Adafruit IO Error {response.status_code}: {error}") class AdafruitIO_MQTTError(Exception): """Adafruit IO MQTT error class""" def __init__(self, response): - super().__init__("MQTT Error: {0}".format(response)) + super().__init__(f"MQTT Error: {response}") diff --git a/docs/api.rst b/docs/api.rst index 2e26b2f..c50c72c 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -4,5 +4,8 @@ .. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py) .. use this format as the module name: "adafruit_foo.foo" +API Reference +############# + .. automodule:: adafruit_io.adafruit_io :members: diff --git a/docs/conf.py b/docs/conf.py index 089b753..d211602 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,12 +1,10 @@ -# -*- coding: utf-8 -*- - # SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # # SPDX-License-Identifier: MIT +import datetime import os import sys -import datetime sys.path.insert(0, os.path.abspath("..")) @@ -41,9 +39,7 @@ creation_year = "2019" current_year = str(datetime.datetime.now().year) year_duration = ( - current_year - if current_year == creation_year - else creation_year + " - " + current_year + current_year if current_year == creation_year else creation_year + " - " + current_year ) copyright = year_duration + " Brent Rubell" author = "Brent Rubell" diff --git a/examples/adafruit_io_http/adafruit_io_analog_in.py b/examples/adafruit_io_http/adafruit_io_analog_in.py index bbbda7d..f6888b7 100644 --- a/examples/adafruit_io_http/adafruit_io_analog_in.py +++ b/examples/adafruit_io_http/adafruit_io_analog_in.py @@ -3,15 +3,17 @@ # Example of publishing the value of an ADC to Adafruit IO # adafruit_circuitpython_adafruitio with an esp32spi_socket -from os import getenv import time +from os import getenv + +import adafruit_connection_manager +import adafruit_requests import board import busio +from adafruit_esp32spi import adafruit_esp32spi from analogio import AnalogIn from digitalio import DigitalInOut -import adafruit_connection_manager -from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests + from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml diff --git a/examples/adafruit_io_http/adafruit_io_batch_cpython.py b/examples/adafruit_io_http/adafruit_io_batch_cpython.py index 4423fad..af45d8d 100644 --- a/examples/adafruit_io_http/adafruit_io_batch_cpython.py +++ b/examples/adafruit_io_http/adafruit_io_batch_cpython.py @@ -3,11 +3,13 @@ # adafruit_circuitpython_adafruitio usage for batch data with a CPython socket. import datetime -from os import getenv import socket import ssl +from os import getenv from random import randint + import adafruit_requests + from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -40,9 +42,7 @@ time_offset = i - 5 created_at = current_time + datetime.timedelta(seconds=time_offset) print( - "Adding datapoint {0} (at T:{1}) to collection for batch-temperature feed...".format( - random_value, time_offset - ) + f"Adding datapoint {random_value} (at T:{time_offset}) to collection for batch-temperature feed..." # noqa: E501 ) data.append( { diff --git a/examples/adafruit_io_http/adafruit_io_create_and_get_feed.py b/examples/adafruit_io_http/adafruit_io_create_and_get_feed.py index 0eac01b..640b838 100644 --- a/examples/adafruit_io_http/adafruit_io_create_and_get_feed.py +++ b/examples/adafruit_io_http/adafruit_io_create_and_get_feed.py @@ -4,11 +4,14 @@ Example using create_and_get_feed. Creates a new feed if it does not exist and sends to it, or sends to an existing feed once it has been created. """ + from os import getenv + +import adafruit_connection_manager import adafruit_requests -import wifi import microcontroller -import adafruit_connection_manager +import wifi + from adafruit_io.adafruit_io import IO_HTTP # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -20,7 +23,7 @@ # Connect to Wi-Fi using credentials from settings.toml wifi.radio.connect(ssid, password) -print("Connected to {}!".format(ssid)) +print(f"Connected to {ssid}!") print("IP:", wifi.radio.ipv4_address) pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio) @@ -32,7 +35,7 @@ # Create temperature variable using the CPU temperature and print the current value. temperature = microcontroller.cpu.temperature -print("Current CPU temperature: {0} C".format(temperature)) +print(f"Current CPU temperature: {temperature} C") # Create and get feed. io.send_data(io.create_and_get_feed("cpu-temperature-feed")["key"], temperature) diff --git a/examples/adafruit_io_http/adafruit_io_digital_out.py b/examples/adafruit_io_http/adafruit_io_digital_out.py index 5385b39..f51c276 100644 --- a/examples/adafruit_io_http/adafruit_io_digital_out.py +++ b/examples/adafruit_io_http/adafruit_io_digital_out.py @@ -5,12 +5,14 @@ # adafruit_circuitpython_adafruitio with an esp32spi_socket import time from os import getenv + +import adafruit_connection_manager +import adafruit_requests import board import busio -from digitalio import DigitalInOut, Direction -import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests +from digitalio import DigitalInOut, Direction + from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml diff --git a/examples/adafruit_io_http/adafruit_io_feeds.py b/examples/adafruit_io_http/adafruit_io_feeds.py index ea4874c..2225436 100644 --- a/examples/adafruit_io_http/adafruit_io_feeds.py +++ b/examples/adafruit_io_http/adafruit_io_feeds.py @@ -5,12 +5,14 @@ # Documentation: https://io.adafruit.com/api/docs/#feeds # adafruit_circuitpython_adafruitio with an esp32spi_socket from os import getenv + +import adafruit_connection_manager +import adafruit_requests import board import busio -from digitalio import DigitalInOut -import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests +from digitalio import DigitalInOut + from adafruit_io.adafruit_io import IO_HTTP # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml diff --git a/examples/adafruit_io_http/adafruit_io_groups.py b/examples/adafruit_io_http/adafruit_io_groups.py index 5911f33..f0203a9 100644 --- a/examples/adafruit_io_http/adafruit_io_groups.py +++ b/examples/adafruit_io_http/adafruit_io_groups.py @@ -5,13 +5,15 @@ # Documentation: https://io.adafruit.com/api/docs/#groups # adafruit_circuitpython_adafruitio with an esp32spi_socket from os import getenv + +import adafruit_connection_manager import adafruit_datetime as datetime +import adafruit_requests import board import busio -from digitalio import DigitalInOut -import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests +from digitalio import DigitalInOut + from adafruit_io.adafruit_io import IO_HTTP # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml diff --git a/examples/adafruit_io_http/adafruit_io_metadata.py b/examples/adafruit_io_http/adafruit_io_metadata.py index de6c339..b7e7aa4 100644 --- a/examples/adafruit_io_http/adafruit_io_metadata.py +++ b/examples/adafruit_io_http/adafruit_io_metadata.py @@ -4,12 +4,14 @@ # Adafruit IO HTTP API - Sending values with optional metadata # adafruit_circuitpython_adafruitio with an esp32spi_socket from os import getenv + +import adafruit_connection_manager +import adafruit_requests import board import busio -from digitalio import DigitalInOut -import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests +from digitalio import DigitalInOut + from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml diff --git a/examples/adafruit_io_http/adafruit_io_randomizer.py b/examples/adafruit_io_http/adafruit_io_randomizer.py index a7b46db..c3aa1fe 100644 --- a/examples/adafruit_io_http/adafruit_io_randomizer.py +++ b/examples/adafruit_io_http/adafruit_io_randomizer.py @@ -5,12 +5,14 @@ # adafruit_circuitpython_adafruitio with an esp32spi_socket import time from os import getenv + +import adafruit_connection_manager +import adafruit_requests import board import busio -from digitalio import DigitalInOut -import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests +from digitalio import DigitalInOut + from adafruit_io.adafruit_io import IO_HTTP # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml diff --git a/examples/adafruit_io_http/adafruit_io_simpletest.py b/examples/adafruit_io_http/adafruit_io_simpletest.py index 1d0b8a1..9f93625 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest.py @@ -4,9 +4,11 @@ # adafruit_circuitpython_adafruitio usage with native wifi networking from os import getenv from random import randint + +import adafruit_connection_manager import adafruit_requests import wifi -import adafruit_connection_manager + from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -35,7 +37,7 @@ # Send random integer values to the feed random_value = randint(0, 50) -print("Sending {0} to temperature feed...".format(random_value)) +print(f"Sending {random_value} to temperature feed...") io.send_data(temperature_feed["key"], random_value) print("Data sent!") diff --git a/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py b/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py index dd5ac50..d0ee4ce 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest_cpython.py @@ -2,11 +2,13 @@ # SPDX-License-Identifier: MIT # adafruit_circuitpython_adafruitio usage with a CPython socket -from os import getenv import socket import ssl +from os import getenv from random import randint + import adafruit_requests + from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -29,7 +31,7 @@ # Send random integer values to the feed random_value = randint(0, 50) -print("Sending {0} to temperature feed...".format(random_value)) +print(f"Sending {random_value} to temperature feed...") io.send_data(temperature_feed["key"], random_value) print("Data sent!") diff --git a/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py b/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py index a7e0ac0..62f23c9 100644 --- a/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py +++ b/examples/adafruit_io_http/adafruit_io_simpletest_esp32spi.py @@ -4,12 +4,14 @@ # adafruit_circuitpython_adafruitio usage with an esp32spi_socket from os import getenv from random import randint + +import adafruit_connection_manager +import adafruit_requests import board import busio -from digitalio import DigitalInOut -import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests +from digitalio import DigitalInOut + from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -58,7 +60,7 @@ # Send random integer values to the feed random_value = randint(0, 50) -print("Sending {0} to temperature feed...".format(random_value)) +print(f"Sending {random_value} to temperature feed...") io.send_data(temperature_feed["key"], random_value) print("Data sent!") diff --git a/examples/adafruit_io_http/adafruit_io_temperature.py b/examples/adafruit_io_http/adafruit_io_temperature.py index 969ad90..6a39a6b 100644 --- a/examples/adafruit_io_http/adafruit_io_temperature.py +++ b/examples/adafruit_io_http/adafruit_io_temperature.py @@ -5,13 +5,15 @@ # adafruit_circuitpython_adafruitio with an esp32spi_socket import time from os import getenv + +import adafruit_adt7410 +import adafruit_connection_manager +import adafruit_requests import board import busio -from digitalio import DigitalInOut -import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests -import adafruit_adt7410 +from digitalio import DigitalInOut + from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -68,7 +70,7 @@ # set temperature value to two precision points temperature = "%0.2f" % (temperature) - print("Current Temperature: {0}*C".format(temperature)) + print(f"Current Temperature: {temperature}*C") print("Sending to Adafruit IO...") io.send_data(temperature_feed["key"], temperature) print("Data sent!") diff --git a/examples/adafruit_io_http/adafruit_io_user_info.py b/examples/adafruit_io_http/adafruit_io_user_info.py index fe9a0f6..096f809 100644 --- a/examples/adafruit_io_http/adafruit_io_user_info.py +++ b/examples/adafruit_io_http/adafruit_io_user_info.py @@ -2,11 +2,13 @@ # SPDX-License-Identifier: MIT # retrieve user rate info via adafruit_circuitpython_adafruitio with native wifi networking +import time from os import getenv -import time # pylint: disable=unused-import + +import adafruit_connection_manager import adafruit_requests import wifi -import adafruit_connection_manager + from adafruit_io.adafruit_io import IO_HTTP # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml diff --git a/examples/adafruit_io_http/adafruit_io_weather.py b/examples/adafruit_io_http/adafruit_io_weather.py index 5731858..580ad65 100644 --- a/examples/adafruit_io_http/adafruit_io_weather.py +++ b/examples/adafruit_io_http/adafruit_io_weather.py @@ -4,12 +4,14 @@ # Example of using the Adafruit IO+ Weather Service # adafruit_circuitpython_adafruitio with an esp32spi_socket from os import getenv + +import adafruit_connection_manager +import adafruit_requests import board import busio -from digitalio import DigitalInOut -import adafruit_connection_manager from adafruit_esp32spi import adafruit_esp32spi -import adafruit_requests +from digitalio import DigitalInOut + from adafruit_io.adafruit_io import IO_HTTP # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -62,11 +64,7 @@ # Get today's forecast current_forecast = forecast["current"] -print( - "It is {0} and {1}*F.".format( - current_forecast["summary"], current_forecast["temperature"] - ) -) +print("It is {0} and {1}*F.".format(current_forecast["summary"], current_forecast["temperature"])) print("with a humidity of {0}%".format(current_forecast["humidity"] * 100)) # Get tomorrow's forecast diff --git a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py index 594fe71..b1e286c 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py +++ b/examples/adafruit_io_mqtt/adafruit_io_feed_callback.py @@ -3,14 +3,15 @@ import time from os import getenv + +import adafruit_connection_manager +import adafruit_minimqtt.adafruit_minimqtt as MQTT import board import busio -from digitalio import DigitalInOut -import adafruit_connection_manager -from adafruit_esp32spi import adafruit_esp32spi -from adafruit_esp32spi import adafruit_esp32spi_wifimanager import neopixel -import adafruit_minimqtt.adafruit_minimqtt as MQTT +from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager +from digitalio import DigitalInOut + from adafruit_io.adafruit_io import IO_MQTT # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -35,9 +36,7 @@ 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_pixel = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_pixel = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -47,13 +46,10 @@ # GREEN_LED = PWMOut.PWMOut(esp, 27) # BLUE_LED = PWMOut.PWMOut(esp, 25) # status_pixel = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) -wifi = adafruit_esp32spi_wifimanager.WiFiManager( - esp, ssid, password, status_pixel=status_pixel -) +wifi = adafruit_esp32spi_wifimanager.WiFiManager(esp, ssid, password, status_pixel=status_pixel) # 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 @@ -64,40 +60,37 @@ def connected(client): 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)) + print(f"Subscribed to {topic} with QOS level {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)) + print(f"Unsubscribed from {topic} with PID {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 publish(client, userdata, topic, pid): # This method is called when the client publishes data to a feed. - print("Published to {0} with PID {1}".format(topic, pid)) + print(f"Published to {topic} with PID {pid}") if userdata is not None: print("Published User data: ", end="") print(userdata) -# 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)) + print(f"Feed {feed_id} received new value: {payload}") def on_battery_msg(client, topic, message): # Method called whenever user/feeds/battery has a new value - print("Battery level: {}v".format(message)) + print(f"Battery level: {message}v") # Connect to WiFi diff --git a/examples/adafruit_io_mqtt/adafruit_io_groups.py b/examples/adafruit_io_mqtt/adafruit_io_groups.py index 7294fd7..39a3894 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_groups.py +++ b/examples/adafruit_io_mqtt/adafruit_io_groups.py @@ -7,14 +7,14 @@ from os import getenv from random import randint +import adafruit_connection_manager +import adafruit_minimqtt.adafruit_minimqtt as MQTT import board import busio -from digitalio import DigitalInOut -import adafruit_connection_manager -from adafruit_esp32spi import adafruit_esp32spi -from adafruit_esp32spi import adafruit_esp32spi_wifimanager import neopixel -import adafruit_minimqtt.adafruit_minimqtt as MQTT +from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager +from digitalio import DigitalInOut + from adafruit_io.adafruit_io import IO_MQTT # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -39,9 +39,7 @@ 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_pixel = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_pixel = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -51,13 +49,10 @@ # GREEN_LED = PWMOut.PWMOut(esp, 27) # BLUE_LED = PWMOut.PWMOut(esp, 25) # status_pixel = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) -wifi = adafruit_esp32spi_wifimanager.WiFiManager( - esp, ssid, password, status_pixel=status_pixel -) +wifi = adafruit_esp32spi_wifimanager.WiFiManager(esp, ssid, password, status_pixel=status_pixel) # 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 @@ -69,27 +64,24 @@ def connected(client): io.subscribe(group_key=group_name) -# 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 publish(client, userdata, topic, pid): # This method is called when the client publishes data to a feed. - print("Published to {0} with PID {1}".format(topic, pid)) + print(f"Published to {topic} with PID {pid}") if userdata is not None: print("Published User data: ", end="") print(userdata) -# 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)) + print(f"Feed {feed_id} received new value: {payload}") # Connect to WiFi @@ -135,10 +127,10 @@ def message(client, feed_id, payload): while True: io.loop() temp_reading = randint(0, 100) - print("Publishing value {0} to feed: {1}".format(temp_reading, temp_feed)) + print(f"Publishing value {temp_reading} to feed: {temp_feed}") io.publish(temp_feed, temp_reading) humid_reading = randint(0, 100) - print("Publishing value {0} to feed: {1}".format(humid_reading, humid_feed)) + print(f"Publishing value {humid_reading} to feed: {humid_feed}") io.publish(humid_feed, humid_reading) time.sleep(5) diff --git a/examples/adafruit_io_mqtt/adafruit_io_location.py b/examples/adafruit_io_mqtt/adafruit_io_location.py index b2a1d8c..9b17824 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_location.py +++ b/examples/adafruit_io_mqtt/adafruit_io_location.py @@ -5,14 +5,15 @@ # and sending it to an Adafruit IO feed. import time from os import getenv + +import adafruit_connection_manager +import adafruit_minimqtt.adafruit_minimqtt as MQTT import board import busio -from digitalio import DigitalInOut -import adafruit_connection_manager -from adafruit_esp32spi import adafruit_esp32spi -from adafruit_esp32spi import adafruit_esp32spi_wifimanager import neopixel -import adafruit_minimqtt.adafruit_minimqtt as MQTT +from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager +from digitalio import DigitalInOut + from adafruit_io.adafruit_io import IO_MQTT # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -37,9 +38,7 @@ 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_pixel = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_pixel = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -49,13 +48,10 @@ # GREEN_LED = PWMOut.PWMOut(esp, 27) # BLUE_LED = PWMOut.PWMOut(esp, 25) # status_pixel = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) -wifi = adafruit_esp32spi_wifimanager.WiFiManager( - esp, ssid, password, status_pixel=status_pixel -) +wifi = adafruit_esp32spi_wifimanager.WiFiManager(esp, ssid, password, status_pixel=status_pixel) # 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 @@ -67,27 +63,24 @@ def connected(client): io.subscribe("location") -# 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 publish(client, userdata, topic, pid): # This method is called when the client publishes data to a feed. - print("Published to {0} with PID {1}".format(topic, pid)) + print(f"Published to {topic} with PID {pid}") if userdata is not None: print("Published User data: ", end="") print(userdata) -# 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)) + print(f"Feed {feed_id} received new value: {payload}") # Connect to WiFi diff --git a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py index d4c1258..6792d05 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py +++ b/examples/adafruit_io_mqtt/adafruit_io_pubsub_rp2040.py @@ -3,14 +3,15 @@ import time from os import getenv -from microcontroller import cpu + +import adafruit_connection_manager +import adafruit_minimqtt.adafruit_minimqtt as MQTT import board import busio +from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager from digitalio import DigitalInOut -import adafruit_connection_manager -from adafruit_esp32spi import adafruit_esp32spi -from adafruit_esp32spi import adafruit_esp32spi_wifimanager -import adafruit_minimqtt.adafruit_minimqtt as MQTT +from microcontroller import cpu + from adafruit_io.adafruit_io import IO_MQTT # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -38,37 +39,32 @@ # 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. print("Connected to Adafruit IO! ") -# pylint: disable=unused-argument 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)) + print(f"Subscribed to {topic} with QOS level {granted_qos}") -# pylint: disable=unused-argument def publish(client, userdata, topic, pid): # This method is called when the client publishes data to a feed. - print("Published to {0} with PID {1}".format(topic, pid)) + print(f"Published to {topic} with PID {pid}") if userdata is not None: print("Published User data: ", end="") print(userdata) -# 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_led_msg(client, topic, message): # Method called whenever user/feeds/led has a new value - print("New message on topic {0}: {1} ".format(topic, message)) + print(f"New message on topic {topic}: {message} ") if message == "ON": led_pin.value = True elif message == "OFF": diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py index 3c0b314..63d4e19 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_cellular.py @@ -9,16 +9,15 @@ from os import getenv from random import randint +import adafruit_connection_manager +import adafruit_fona.adafruit_fona_socket as pool +import adafruit_minimqtt.adafruit_minimqtt as MQTT import board import busio import digitalio - -import adafruit_connection_manager from adafruit_fona.adafruit_fona import FONA from adafruit_fona.adafruit_fona_gsm import GSM -import adafruit_fona.adafruit_fona_socket as pool -import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT # Get Fona details and Adafruit IO keys, ensure these are setup in settings.toml @@ -50,7 +49,6 @@ # 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 @@ -61,39 +59,34 @@ def connected(client): client.subscribe("DemoFeed") -# pylint: disable=unused-argument 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)) + print(f"Subscribed to {topic} with QOS level {granted_qos}") -# pylint: disable=unused-argument 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)) + print(f"Unsubscribed from {topic} with PID {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 publish(client, userdata, topic, pid): # This method is called when the client publishes data to a feed. - print("Published to {0} with PID {1}".format(topic, pid)) + print(f"Published to {topic} with PID {pid}") if userdata is not None: print("Published User data: ", end="") print(userdata) -# 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)) + print(f"Feed {feed_id} received new value: {payload}") ssl_context = adafruit_connection_manager.create_fake_ssl_context(pool, fona) @@ -132,6 +125,6 @@ def message(client, feed_id, payload): # Send a new message every 10 seconds. if (time.monotonic() - last) >= 5: value = randint(0, 100) - print("Publishing {0} to DemoFeed.".format(value)) + print(f"Publishing {value} to DemoFeed.") io.publish("DemoFeed", value) last = time.monotonic() diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py index e308c27..d60daf7 100644 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_esp32s2.py @@ -4,9 +4,10 @@ from os import getenv from random import randint -import wifi import adafruit_connection_manager import adafruit_minimqtt.adafruit_minimqtt as MQTT +import wifi + from adafruit_io.adafruit_io import IO_MQTT # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -25,7 +26,6 @@ # 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 @@ -36,39 +36,34 @@ def connected(client): client.subscribe("DemoFeed") -# pylint: disable=unused-argument 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)) + print(f"Subscribed to {topic} with QOS level {granted_qos}") -# pylint: disable=unused-argument 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)) + print(f"Unsubscribed from {topic} with PID {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 publish(client, userdata, topic, pid): # This method is called when the client publishes data to a feed. - print("Published to {0} with PID {1}".format(topic, pid)) + print(f"Published to {topic} with PID {pid}") if userdata is not None: print("Published User data: ", end="") print(userdata) -# 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)) + print(f"Feed {feed_id} received new value: {payload}") # Create a socket pool and ssl_context @@ -110,6 +105,6 @@ def message(client, feed_id, payload): # Send a new message every 10 seconds. if (time.monotonic() - last) >= 5: value = randint(0, 100) - print("Publishing {0} to DemoFeed.".format(value)) + print(f"Publishing {value} to DemoFeed.") io.publish("DemoFeed", value) last = time.monotonic() diff --git a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py index b502983..63dbd54 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py +++ b/examples/adafruit_io_mqtt/adafruit_io_simpletest_eth.py @@ -9,13 +9,13 @@ from os import getenv from random import randint +import adafruit_connection_manager +import adafruit_minimqtt.adafruit_minimqtt as MQTT import board import busio +from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K from digitalio import DigitalInOut -import adafruit_connection_manager -from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K -import adafruit_minimqtt.adafruit_minimqtt as MQTT from adafruit_io.adafruit_io import IO_MQTT # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -33,7 +33,6 @@ # 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 @@ -44,39 +43,34 @@ def connected(client): client.subscribe("DemoFeed") -# pylint: disable=unused-argument 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)) + print(f"Subscribed to {topic} with QOS level {granted_qos}") -# pylint: disable=unused-argument 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)) + print(f"Unsubscribed from {topic} with PID {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 publish(client, userdata, topic, pid): # This method is called when the client publishes data to a feed. - print("Published to {0} with PID {1}".format(topic, pid)) + print(f"Published to {topic} with PID {pid}") if userdata is not None: print("Published User data: ", end="") print(userdata) -# 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)) + print(f"Feed {feed_id} received new value: {payload}") pool = adafruit_connection_manager.get_radio_socketpool(eth) @@ -116,6 +110,6 @@ def message(client, feed_id, payload): # Send a new message every 10 seconds. if (time.monotonic() - last) >= 5: value = randint(0, 100) - print("Publishing {0} to DemoFeed.".format(value)) + print(f"Publishing {value} to DemoFeed.") io.publish("DemoFeed", value) last = time.monotonic() diff --git a/examples/adafruit_io_mqtt/adafruit_io_time.py b/examples/adafruit_io_mqtt/adafruit_io_time.py index e2b69a6..43eaf87 100755 --- a/examples/adafruit_io_mqtt/adafruit_io_time.py +++ b/examples/adafruit_io_mqtt/adafruit_io_time.py @@ -6,14 +6,15 @@ # access to a RTC module. import time from os import getenv + +import adafruit_connection_manager +import adafruit_minimqtt.adafruit_minimqtt as MQTT import board import busio -from digitalio import DigitalInOut -import adafruit_connection_manager -from adafruit_esp32spi import adafruit_esp32spi -from adafruit_esp32spi import adafruit_esp32spi_wifimanager import neopixel -import adafruit_minimqtt.adafruit_minimqtt as MQTT +from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager +from digitalio import DigitalInOut + from adafruit_io.adafruit_io import IO_MQTT # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -38,9 +39,7 @@ 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_pixel = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_pixel = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -50,13 +49,10 @@ # GREEN_LED = PWMOut.PWMOut(esp, 27) # BLUE_LED = PWMOut.PWMOut(esp, 25) # status_pixel = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) -wifi = adafruit_esp32spi_wifimanager.WiFiManager( - esp, ssid, password, status_pixel=status_pixel -) +wifi = adafruit_esp32spi_wifimanager.WiFiManager(esp, ssid, password, status_pixel=status_pixel) # 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 @@ -82,27 +78,24 @@ def connected(client): io.subscribe_to_time("hours") -# 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 publish(client, userdata, topic, pid): # This method is called when the client publishes data to a feed. - print("Published to {0} with PID {1}".format(topic, pid)) + print(f"Published to {topic} with PID {pid}") if userdata is not None: print("Published User data: ", end="") print(userdata) -# 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)) + print(f"Feed {feed_id} received new value: {payload}") # Connect to WiFi diff --git a/examples/adafruit_io_simpletest.py b/examples/adafruit_io_simpletest.py index 702f3ca..8c99e2d 100755 --- a/examples/adafruit_io_simpletest.py +++ b/examples/adafruit_io_simpletest.py @@ -8,14 +8,15 @@ import time from os import getenv from random import randint + +import adafruit_connection_manager +import adafruit_minimqtt.adafruit_minimqtt as MQTT import board import busio -from digitalio import DigitalInOut -import adafruit_connection_manager -from adafruit_esp32spi import adafruit_esp32spi -from adafruit_esp32spi import adafruit_esp32spi_wifimanager import neopixel -import adafruit_minimqtt.adafruit_minimqtt as MQTT +from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager +from digitalio import DigitalInOut + from adafruit_io.adafruit_io import IO_MQTT # Get WiFi details and Adafruit IO keys, ensure these are setup in settings.toml @@ -40,9 +41,7 @@ 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_pixel = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_pixel = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -52,13 +51,10 @@ # GREEN_LED = PWMOut.PWMOut(esp, 27) # BLUE_LED = PWMOut.PWMOut(esp, 25) # status_pixel = adafruit_rgbled.RGBLED(RED_LED, BLUE_LED, GREEN_LED) -wifi = adafruit_esp32spi_wifimanager.WiFiManager( - esp, ssid, password, status_pixel=status_pixel -) +wifi = adafruit_esp32spi_wifimanager.WiFiManager(esp, ssid, password, status_pixel=status_pixel) # 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 @@ -71,21 +67,19 @@ def connected(client): 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)) + print(f"Subscribed to {topic} with QOS level {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)) + print(f"Unsubscribed from {topic} with PID {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 publish(client, userdata, topic, pid): """This method is called when the client publishes data to a feed.""" print(f"Published to {topic} with PID {pid}") @@ -94,12 +88,11 @@ def publish(client, userdata, topic, pid): print(userdata) -# 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)) + print(f"Feed {feed_id} received new value: {payload}") # Connect to WiFi @@ -145,6 +138,6 @@ def message(client, feed_id, payload): # Send a new message every 10 seconds. if (time.monotonic() - last) >= 5: value = randint(0, 100) - print("Publishing {0} to DemoFeed.".format(value)) + print(f"Publishing {value} to DemoFeed.") io.publish("DemoFeed", value) last = time.monotonic() diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..1b887b1 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,107 @@ +# SPDX-FileCopyrightText: 2024 Tim Cocks for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +target-version = "py38" +line-length = 100 + +[lint] +preview = true +select = ["I", "PL", "UP"] + +extend-select = [ + "D419", # empty-docstring + "E501", # line-too-long + "W291", # trailing-whitespace + "PLC0414", # useless-import-alias + "PLC2401", # non-ascii-name + "PLC2801", # unnecessary-dunder-call + "PLC3002", # unnecessary-direct-lambda-call + "E999", # syntax-error + "PLE0101", # return-in-init + "F706", # return-outside-function + "F704", # yield-outside-function + "PLE0116", # continue-in-finally + "PLE0117", # nonlocal-without-binding + "PLE0241", # duplicate-bases + "PLE0302", # unexpected-special-method-signature + "PLE0604", # invalid-all-object + "PLE0605", # invalid-all-format + "PLE0643", # potential-index-error + "PLE0704", # misplaced-bare-raise + "PLE1141", # dict-iter-missing-items + "PLE1142", # await-outside-async + "PLE1205", # logging-too-many-args + "PLE1206", # logging-too-few-args + "PLE1307", # bad-string-format-type + "PLE1310", # bad-str-strip-call + "PLE1507", # invalid-envvar-value + "PLE2502", # bidirectional-unicode + "PLE2510", # invalid-character-backspace + "PLE2512", # invalid-character-sub + "PLE2513", # invalid-character-esc + "PLE2514", # invalid-character-nul + "PLE2515", # invalid-character-zero-width-space + "PLR0124", # comparison-with-itself + "PLR0202", # no-classmethod-decorator + "PLR0203", # no-staticmethod-decorator + "UP004", # useless-object-inheritance + "PLR0206", # property-with-parameters + "PLR0904", # too-many-public-methods + "PLR0911", # too-many-return-statements + "PLR0912", # too-many-branches + "PLR0913", # too-many-arguments + "PLR0914", # too-many-locals + "PLR0915", # too-many-statements + "PLR0916", # too-many-boolean-expressions + "PLR1702", # too-many-nested-blocks + "PLR1704", # redefined-argument-from-local + "PLR1711", # useless-return + "C416", # unnecessary-comprehension + "PLR1733", # unnecessary-dict-index-lookup + "PLR1736", # unnecessary-list-index-lookup + + # ruff reports this rule is unstable + #"PLR6301", # no-self-use + + "PLW0108", # unnecessary-lambda + "PLW0120", # useless-else-on-loop + "PLW0127", # self-assigning-variable + "PLW0129", # assert-on-string-literal + "B033", # duplicate-value + "PLW0131", # named-expr-without-context + "PLW0245", # super-without-brackets + "PLW0406", # import-self + "PLW0602", # global-variable-not-assigned + "PLW0603", # global-statement + "PLW0604", # global-at-module-level + + # fails on the try: import typing used by libraries + #"F401", # unused-import + + "F841", # unused-variable + "E722", # bare-except + "PLW0711", # binary-op-exception + "PLW1501", # bad-open-mode + "PLW1508", # invalid-envvar-default + "PLW1509", # subprocess-popen-preexec-fn + "PLW2101", # useless-with-lock + "PLW3301", # nested-min-max +] + +ignore = [ + "PLR2004", # magic-value-comparison + "UP030", # format literals + "PLW1514", # unspecified-encoding + "PLR0913", # too-many-arguments + "PLR0915", # too-many-statements + "PLR0917", # too-many-positional-arguments + "PLR0904", # too-many-public-methods + "PLR0912", # too-many-branches + "PLR0916", # too-many-boolean-expressions + "PLR6301", # could-be-static no-self-use + "PLC0415", # import outside toplevel +] + +[format] +line-ending = "lf"