From f88e6b407434b692463a14942ecdb18a2975ff6a Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Fri, 15 Mar 2024 22:48:10 -0400 Subject: [PATCH 01/10] messge here --- .../expanded/requests_wifi_api_mastodon.py | 142 +++++++++--------- 1 file changed, 69 insertions(+), 73 deletions(-) diff --git a/examples/wifi/expanded/requests_wifi_api_mastodon.py b/examples/wifi/expanded/requests_wifi_api_mastodon.py index 56f3e8d..f6bce9f 100644 --- a/examples/wifi/expanded/requests_wifi_api_mastodon.py +++ b/examples/wifi/expanded/requests_wifi_api_mastodon.py @@ -1,121 +1,117 @@ -# SPDX-FileCopyrightText: 2022 DJDevon3 +# SPDX-FileCopyrightText: 2024 DJDevon3 # SPDX-License-Identifier: MIT -# Coded for Circuit Python 8.0 -"""DJDevon3 Adafruit Feather ESP32-S2 Mastodon_API_Example""" -import gc +# Coded for Circuit Python 8.2.x +"""Mastodon API Example""" +# pylint: disable=import-error + import os -import ssl import time -import socketpool +import adafruit_connection_manager import wifi import adafruit_requests # Mastodon V1 API - Public access (no dev creds or app required) # Visit https://docs.joinmastodon.org/client/public/ for API docs -# For finding your Mastodon User ID -# Login to your mastodon server in a browser, visit your profile, UserID is in the URL. -# Example: https://mastodon.YOURSERVER/web/accounts/YOURUSERIDISHERE +# For finding your Mastodon numerical UserID +# Example: https://mastodon.YOURSERVER/api/v1/accounts/lookup?acct=YourUserName -Mastodon_Server = "mastodon.social" # Set server instance -Mastodon_UserID = "000000000000000000" # Set User ID you want endpoints from +MASTODON_SERVER = "mastodon.social" # Set server instance +MASTODON_USERID = "000000000000000000" # Numerical UserID you want endpoints from # Test in browser first, this will pull up a JSON webpage # https://mastodon.YOURSERVER/api/v1/accounts/YOURUSERIDHERE/statuses?limit=1 -# Initialize WiFi Pool (There can be only 1 pool & top of script) -pool = socketpool.SocketPool(wifi.radio) - -# Time between API refreshes -# 900 = 15 mins, 1800 = 30 mins, 3600 = 1 hour -sleep_time = 900 - # Get WiFi details, ensure these are setup in settings.toml ssid = os.getenv("CIRCUITPY_WIFI_SSID") password = os.getenv("CIRCUITPY_WIFI_PASSWORD") +# API Polling Rate +# 900 = 15 mins, 1800 = 30 mins, 3600 = 1 hour +SLEEP_TIME = 900 + +# Initalize Wifi, Socket Pool, Request Session +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) + -# Converts seconds in minutes/hours/days def time_calc(input_time): + """Converts seconds to minutes/hours/days""" if input_time < 60: - sleep_int = input_time - time_output = f"{sleep_int:.0f} seconds" - elif 60 <= input_time < 3600: - sleep_int = input_time / 60 - time_output = f"{sleep_int:.0f} minutes" - elif 3600 <= input_time < 86400: - sleep_int = input_time / 60 / 60 - time_output = f"{sleep_int:.0f} hours" - elif 86400 <= input_time < 432000: - sleep_int = input_time / 60 / 60 / 24 - time_output = f"{sleep_int:.1f} days" - else: # if > 5 days convert float to int & display whole days - sleep_int = input_time / 60 / 60 / 24 - time_output = f"{sleep_int:.0f} days" - return time_output + return f"{input_time:.0f} seconds" + if input_time < 3600: + return f"{input_time / 60:.0f} minutes" + if input_time < 86400: + return f"{input_time / 60 / 60:.0f} hours" + return f"{input_time / 60 / 60 / 24:.1f} days" # Publicly available data no header required MAST_SOURCE = ( "https://" - + Mastodon_Server + + MASTODON_SERVER + "/api/v1/accounts/" - + Mastodon_UserID + + MASTODON_USERID + "/statuses?limit=1" ) -# Connect to Wi-Fi -print("\n===============================") -print("Connecting to WiFi...") -requests = adafruit_requests.Session(pool, ssl.create_default_context()) -while not wifi.radio.ipv4_address: - try: - wifi.radio.connect(ssid, password) - except ConnectionError as e: - print("Connection Error:", e) - print("Retrying in 10 seconds") - time.sleep(10) - gc.collect() -print("Connected!\n") - while True: + # Connect to Wi-Fi + print("\nConnecting to WiFi...") + while not wifi.radio.ipv4_address: + try: + wifi.radio.connect(ssid, password) + except ConnectionError as e: + print("❌ Connection Error:", e) + print("Retrying in 10 seconds") + print("✅ Wifi!") try: - print("\nAttempting to GET MASTODON Stats!") # ----------------------------- # Print Request to Serial - debug_mastodon_full_response = ( - False # STREAMER WARNING: your client secret will be viewable - ) - print("===============================") - mastodon_response = requests.get(url=MAST_SOURCE) + print(" | Attempting to GET MASTODON JSON!") + + # Set debug to True for full JSON response. + # WARNING: may include visible credentials + # MICROCONTROLLER WARNING: might crash by returning too much data + DEBUG_RESPONSE = False + try: + mastodon_response = requests.get(url=MAST_SOURCE) mastodon_json = mastodon_response.json() except ConnectionError as e: - print("Connection Error:", e) + print(f"Connection Error: {e}") print("Retrying in 10 seconds") mastodon_json = mastodon_json[0] - if debug_mastodon_full_response: - print("Full API GET URL: ", MAST_SOURCE) - print(mastodon_json) + print(" | ✅ Mastodon JSON!") + + if DEBUG_RESPONSE: + print(" | | Full API GET URL: ", MAST_SOURCE) mastodon_userid = mastodon_json["account"]["id"] - print("User ID: ", mastodon_userid) + print(f" | | User ID: {mastodon_userid}") + print(mastodon_json) - mastodon_username = mastodon_json["account"]["display_name"] - print("Name: ", mastodon_username) + mastodon_name = mastodon_json["account"]["display_name"] + print(f" | | Name: {mastodon_name}") mastodon_join_date = mastodon_json["account"]["created_at"] - print("Member Since: ", mastodon_join_date) - mastodon_toot_count = mastodon_json["account"]["statuses_count"] - print("Toots: ", mastodon_toot_count) + print(f" | | Member Since: {mastodon_join_date}") mastodon_follower_count = mastodon_json["account"]["followers_count"] - print("Followers: ", mastodon_follower_count) - print("Monotonic: ", time.monotonic()) + print(f" | | Followers: {mastodon_follower_count}") + mastodon_following_count = mastodon_json["account"]["following_count"] + print(f" | | Following: {mastodon_following_count}") + mastodon_toot_count = mastodon_json["account"]["statuses_count"] + print(f" | | Toots: {mastodon_toot_count}") + mastodon_last_toot = mastodon_json["account"]["last_status_at"] + print(f" | | Last Toot: {mastodon_last_toot}") + mastodon_bio = mastodon_json["account"]["note"] + print(f" | | Bio: {mastodon_bio[3:-4]}") # removes included html "

&

" print("\nFinished!") - print("Next Update in: ", time_calc(sleep_time)) + print(f"Board Uptime: {time.monotonic()}") + print(f"Next Update: {time_calc(SLEEP_TIME)}") print("===============================") - gc.collect() except (ValueError, RuntimeError) as e: - print("Failed to get data, retrying\n", e) + print(f"Failed to get data, retrying\n {e}") time.sleep(60) - continue - time.sleep(sleep_time) + break + time.sleep(SLEEP_TIME) From 84d0689027cf8c85472f688ac1d6a189ce8ecc3f Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Sat, 16 Mar 2024 01:11:49 -0400 Subject: [PATCH 02/10] Update Discord Shields.io Example with Connection Manager --- ...sts_wifi_adafruit_discord_active_online.py | 129 +++++++----------- 1 file changed, 53 insertions(+), 76 deletions(-) diff --git a/examples/wifi/expanded/requests_wifi_adafruit_discord_active_online.py b/examples/wifi/expanded/requests_wifi_adafruit_discord_active_online.py index d43f73f..dec0e6e 100644 --- a/examples/wifi/expanded/requests_wifi_adafruit_discord_active_online.py +++ b/examples/wifi/expanded/requests_wifi_adafruit_discord_active_online.py @@ -1,16 +1,13 @@ -# SPDX-FileCopyrightText: 2023 DJDevon3 +# SPDX-FileCopyrightText: 2024 DJDevon3 # SPDX-License-Identifier: MIT -""" -Coded for Circuit Python 8.2.3 -requests_adafruit_discord_active_online -""" -import gc -import json +# Coded for Circuit Python 8.2.x +"""Discord Active Online Shields.IO Example""" +# pylint: disable=import-error + import os -import ssl import time -import socketpool +import adafruit_connection_manager import wifi import adafruit_requests @@ -19,95 +16,75 @@ # JSON web scrape from SHIELDS.IO # Adafruit uses Shields.IO to see online users -# Initialize WiFi Pool (There can be only 1 pool & top of script) -pool = socketpool.SocketPool(wifi.radio) - -# Time in seconds between updates (polling) -# 600 = 10 mins, 900 = 15 mins, 1800 = 30 mins, 3600 = 1 hour -sleep_time = 900 - # Get WiFi details, ensure these are setup in settings.toml ssid = os.getenv("CIRCUITPY_WIFI_SSID") password = os.getenv("CIRCUITPY_WIFI_PASSWORD") +# API Polling Rate +# 900 = 15 mins, 1800 = 30 mins, 3600 = 1 hour +SLEEP_TIME = 900 + +# Initalize Wifi, Socket Pool, Request Session +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) + -# Converts seconds to minutes/hours/days def time_calc(input_time): + """Converts seconds to minutes/hours/days""" if input_time < 60: - sleep_int = input_time - time_output = f"{sleep_int:.0f} seconds" - elif 60 <= input_time < 3600: - sleep_int = input_time / 60 - time_output = f"{sleep_int:.0f} minutes" - elif 3600 <= input_time < 86400: - sleep_int = input_time / 60 / 60 - time_output = f"{sleep_int:.0f} hours" - else: - sleep_int = input_time / 60 / 60 / 24 - time_output = f"{sleep_int:.1f} days" - return time_output + return f"{input_time:.0f} seconds" + if input_time < 3600: + return f"{input_time / 60:.0f} minutes" + if input_time < 86400: + return f"{input_time / 60 / 60:.0f} hours" + return f"{input_time / 60 / 60 / 24:.1f} days" # Originally attempted to use SVG. Found JSON exists with same filename. # https://img.shields.io/discord/327254708534116352.svg ADA_DISCORD_JSON = "https://img.shields.io/discord/327254708534116352.json" -# Connect to Wi-Fi -print("\n===============================") -print("Connecting to WiFi...") -requests = adafruit_requests.Session(pool, ssl.create_default_context()) -while not wifi.radio.ipv4_address: - try: - wifi.radio.connect(ssid, password) - except ConnectionError as e: - print("Connection Error:", e) - print("Retrying in 10 seconds") - time.sleep(10) - gc.collect() -print("Connected!\n") - while True: + # Connect to Wi-Fi + print("\nConnecting to WiFi...") + while not wifi.radio.ipv4_address: + try: + wifi.radio.connect(ssid, password) + except ConnectionError as e: + print("❌ Connection Error:", e) + print("Retrying in 10 seconds") + print("✅ Wifi!") try: - print( - "\nAttempting to GET DISCORD SHIELD JSON!" - ) # -------------------------------- - # Print Request to Serial - debug_request = True # Set true to see full request - if debug_request: - print("Full API GET URL: ", ADA_DISCORD_JSON) - print("===============================") + print(" | Attempting to GET Adafruit Discord JSON!") + # Set debug to True for full JSON response. + DEBUG_RESPONSE = True + try: - ada_response = requests.get(ADA_DISCORD_JSON).json() + shieldsio_response = requests.get(url=ADA_DISCORD_JSON) + shieldsio_json = shieldsio_response.json() except ConnectionError as e: - print("Connection Error:", e) + print(f"Connection Error: {e}") print("Retrying in 10 seconds") + print(" | ✅ Adafruit Discord JSON!") + + if DEBUG_RESPONSE: + print(" | | Full API GET URL: ", ADA_DISCORD_JSON) + print(" | | JSON Dump: ", shieldsio_json) - # Print Full JSON to Serial - full_ada_json_response = True # Change to true to see full response - if full_ada_json_response: - ada_dump_object = json.dumps(ada_response) - print("JSON Dump: ", ada_dump_object) - - # Print Debugging to Serial - ada_debug = True # Set to True to print Serial data - if ada_debug: - ada_users = ada_response["value"] - print("JSON Value: ", ada_users) - online_string = " online" - replace_with_nothing = "" - string_replace_users = ada_users.replace( - online_string, replace_with_nothing - ) - print("Replaced Value: ", string_replace_users) - print("Monotonic: ", time.monotonic()) + ada_users = shieldsio_json["value"] + ONLINE_STRING = " online" + REPLACE_WITH_NOTHING = "" + active_users = ada_users.replace(ONLINE_STRING, REPLACE_WITH_NOTHING) + print(f" | | Active Online Users: {active_users}") print("\nFinished!") - print("Next Update: ", time_calc(sleep_time)) + print(f"Board Uptime: {time.monotonic()}") + print(f"Next Update: {time_calc(SLEEP_TIME)}") print("===============================") - gc.collect() except (ValueError, RuntimeError) as e: - print("Failed to get data, retrying\n", e) + print(f"Failed to get data, retrying\n {e}") time.sleep(60) - continue - time.sleep(sleep_time) + break + time.sleep(SLEEP_TIME) From 6b1b92e334e2994ac77de68d9db11cad623747cb Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Sat, 16 Mar 2024 02:31:35 -0400 Subject: [PATCH 03/10] Update Discord Web Scrape Example with Connection Manager --- .../expanded/requests_wifi_api_discord.py | 139 +++++++++--------- 1 file changed, 66 insertions(+), 73 deletions(-) diff --git a/examples/wifi/expanded/requests_wifi_api_discord.py b/examples/wifi/expanded/requests_wifi_api_discord.py index 91b2b6c..a7b3fa6 100644 --- a/examples/wifi/expanded/requests_wifi_api_discord.py +++ b/examples/wifi/expanded/requests_wifi_api_discord.py @@ -1,110 +1,103 @@ -# SPDX-FileCopyrightText: 2023 DJDevon3 +# SPDX-FileCopyrightText: 2024 DJDevon3 # SPDX-License-Identifier: MIT -# Coded for Circuit Python 8.2 -# DJDevon3 Adafruit Feather ESP32-S3 Discord API Example -import json +# Coded for Circuit Python 8.2.x +"""Discord Web Scrape Example""" +# pylint: disable=import-error + import os -import ssl import time - -import socketpool +import adafruit_connection_manager import wifi - import adafruit_requests -# Active Logged in User Account Required, no tokens required +# Active Logged in User Account Required # WEB SCRAPE authorization key required. Visit URL below. # Learn how: https://github.com/lorenz234/Discord-Data-Scraping # Ensure this is in settings.toml -# "Discord_Authorization": "Request Header Auth here" +# DISCORD_AUTHORIZATION = "Approximately 70 Character Hash Here" # Get WiFi details, ensure these are setup in settings.toml ssid = os.getenv("CIRCUITPY_WIFI_SSID") password = os.getenv("CIRCUITPY_WIFI_PASSWORD") -Discord_Auth = os.getenv("Discord_Authorization") - -# Initialize WiFi Pool (There can be only 1 pool & top of script) -pool = socketpool.SocketPool(wifi.radio) +discord_auth = os.getenv("DISCORD_AUTHORIZATION") # API Polling Rate # 900 = 15 mins, 1800 = 30 mins, 3600 = 1 hour -sleep_time = 900 +SLEEP_TIME = 900 +# Initalize Wifi, Socket Pool, Request Session +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) -# Converts seconds to human readable minutes/hours/days -def time_calc(input_time): # input_time in seconds + +def time_calc(input_time): + """Converts seconds to minutes/hours/days""" if input_time < 60: - sleep_int = input_time - time_output = f"{sleep_int:.0f} seconds" - elif 60 <= input_time < 3600: - sleep_int = input_time / 60 - time_output = f"{sleep_int:.0f} minutes" - elif 3600 <= input_time < 86400: - sleep_int = input_time / 60 / 60 - time_output = f"{sleep_int:.1f} hours" - else: - sleep_int = input_time / 60 / 60 / 24 - time_output = f"{sleep_int:.1f} days" - return time_output - - -discord_header = {"Authorization": "" + Discord_Auth} -ADA_SOURCE = ( + return f"{input_time:.0f} seconds" + if input_time < 3600: + return f"{input_time / 60:.0f} minutes" + if input_time < 86400: + return f"{input_time / 60 / 60:.0f} hours" + return f"{input_time / 60 / 60 / 24:.1f} days" + + +DISCORD_HEADER = {"Authorization": "" + discord_auth} +DISCORD_SOURCE = ( "https://discord.com/api/v10/guilds/" + "327254708534116352" # Adafruit Discord ID + "/preview" ) -# Connect to Wi-Fi -print("\n===============================") -print("Connecting to WiFi...") -requests = adafruit_requests.Session(pool, ssl.create_default_context()) -while not wifi.radio.ipv4_address: - try: - wifi.radio.connect(ssid, password) - except ConnectionError as e: - print("Connection Error:", e) - print("Retrying in 10 seconds") - time.sleep(10) -print("Connected!✅") - while True: + # Connect to Wi-Fi + print("\nConnecting to WiFi...") + while not wifi.radio.ipv4_address: + try: + wifi.radio.connect(ssid, password) + except ConnectionError as e: + print("❌ Connection Error:", e) + print("Retrying in 10 seconds") + print("✅ Wifi!") try: - print("\nAttempting to GET Discord Data!") # -------------------------------- - # STREAMER WARNING this will show your credentials! - debug_request = False # Set True to see full request - if debug_request: - print("Full API GET URL: ", ADA_SOURCE) - print("===============================") + print(" | Attempting to GET Discord JSON!") + # Set debug to True for full JSON response. + # WARNING: may include visible credentials + # MICROCONTROLLER WARNING: might crash by returning too much data + DEBUG_RESPONSE = False + try: - ada_res = requests.get(url=ADA_SOURCE, headers=discord_header).json() + discord_response = requests.get(url=DISCORD_SOURCE, headers=DISCORD_HEADER) + discord_json = discord_response.json() except ConnectionError as e: - print("Connection Error:", e) + print(f"Connection Error: {e}") print("Retrying in 10 seconds") + print(" | ✅ Discord JSON!") + + if DEBUG_RESPONSE: + print(f" | | Full API GET URL: {DISCORD_SOURCE}") + print(f" | | JSON Dump: {discord_json}") + + discord_name = discord_json["name"] + print(f" | | Name: {discord_name}") - # Print Full JSON to Serial - discord_debug_response = False # Set True to see full response - if discord_debug_response: - ada_discord_dump_object = json.dumps(ada_res) - print("JSON Dump: ", ada_discord_dump_object) + discord_description = discord_json["description"] + print(f" | | Description: {discord_description}") - # Print keys to Serial - discord_debug_keys = True # Set True to print Serial data - if discord_debug_keys: - ada_discord_all_members = ada_res["approximate_member_count"] - print("Members: ", ada_discord_all_members) + discord_all_members = discord_json["approximate_member_count"] + print(f" | | Members: {discord_all_members}") - ada_discord_all_members_online = ada_res["approximate_presence_count"] - print("Online: ", ada_discord_all_members_online) + discord_all_members_online = discord_json["approximate_presence_count"] + print(f" | | Online: {discord_all_members_online}") - print("Finished ✅") - print("Board Uptime: ", time_calc(time.monotonic())) - print("Next Update: ", time_calc(sleep_time)) + print("\nFinished!") + print(f"Board Uptime: {time.monotonic()}") + print(f"Next Update: {time_calc(SLEEP_TIME)}") print("===============================") - except (ConnectionError, ValueError, NameError) as e: - print("Failed to get data, retrying\n", e) + except (ValueError, RuntimeError) as e: + print(f"Failed to get data, retrying\n {e}") time.sleep(60) - continue - time.sleep(sleep_time) + break + time.sleep(SLEEP_TIME) From 095570e2fb568544ccbfc30426adcad1ebe122e0 Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Sat, 16 Mar 2024 02:40:27 -0400 Subject: [PATCH 04/10] Update Discord Web Scrape Example with Connection Manager --- examples/wifi/expanded/requests_wifi_api_discord.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/wifi/expanded/requests_wifi_api_discord.py b/examples/wifi/expanded/requests_wifi_api_discord.py index a7b3fa6..83b8f8f 100644 --- a/examples/wifi/expanded/requests_wifi_api_discord.py +++ b/examples/wifi/expanded/requests_wifi_api_discord.py @@ -6,8 +6,10 @@ import os import time + import adafruit_connection_manager import wifi + import adafruit_requests # Active Logged in User Account Required From 44dff094987a5f971440e4afd6c5ce70e0f2af12 Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Sun, 17 Mar 2024 16:50:43 -0400 Subject: [PATCH 05/10] Update Fitbit API Example with Connection Manager --- .../wifi/expanded/requests_wifi_api_fitbit.py | 576 ++++++++++-------- 1 file changed, 308 insertions(+), 268 deletions(-) diff --git a/examples/wifi/expanded/requests_wifi_api_fitbit.py b/examples/wifi/expanded/requests_wifi_api_fitbit.py index 022ee22..af6227b 100644 --- a/examples/wifi/expanded/requests_wifi_api_fitbit.py +++ b/examples/wifi/expanded/requests_wifi_api_fitbit.py @@ -1,31 +1,21 @@ -# SPDX-FileCopyrightText: 2023 DJDevon3 +# SPDX-FileCopyrightText: 2024 DJDevon3 # SPDX-License-Identifier: MIT -# Coded for Circuit Python 8.2 +# Coded for Circuit Python 8.2.x +"""Fitbit API Example""" +# pylint: disable=import-error, disable=no-member import os -import ssl import time import microcontroller -import socketpool +import adafruit_connection_manager import wifi import adafruit_requests -# Initialize WiFi Pool (There can be only 1 pool & top of script) -pool = socketpool.SocketPool(wifi.radio) - -# STREAMER WARNING: private data will be viewable while debug True -debug = False # Set True for full debug view - -# Can use to confirm first instance of NVM is correct refresh token -top_nvm = microcontroller.nvm[0:64].decode() -if debug: - print(f"Top NVM: {top_nvm}") # NVM before settings.toml loaded - # --- Fitbit Developer Account & oAuth App Required: --- # Required: Google Login (Fitbit owned by Google) & Fitbit Device -# Step 1: Create a personal app here: https://dev.fitbit.com +# Step 1: Register a personal app here: https://dev.fitbit.com # Step 2: Use their Tutorial to get the Token and first Refresh Token # Fitbit's Tutorial Step 4 is as far as you need to go. # https://dev.fitbit.com/build/reference/web-api/troubleshooting-guide/oauth2-tutorial/ @@ -39,277 +29,327 @@ # Get WiFi details, ensure these are setup in settings.toml ssid = os.getenv("CIRCUITPY_WIFI_SSID") password = os.getenv("CIRCUITPY_WIFI_PASSWORD") - -Fitbit_ClientID = os.getenv("Fitbit_ClientID") -Fitbit_Token = os.getenv("Fitbit_Token") +Fitbit_ClientID = os.getenv("FITBIT_CLIENTID") +Fitbit_Token = os.getenv("FITBIT_ACCESS_TOKEN") Fitbit_First_Refresh_Token = os.getenv( - "Fitbit_First_Refresh_Token" + "FITBIT_FIRST_REFRESH_TOKEN" ) # overides nvm first run only -Fitbit_UserID = os.getenv("Fitbit_UserID") +Fitbit_UserID = os.getenv("FITBIT_USERID") + +# Set debug to True for full INTRADAY JSON response. +# WARNING: may include visible credentials +# MICROCONTROLLER WARNING: might crash by returning too much data +DEBUG = False + +# Set debug to True for full DEVICE (Watch) JSON response. +# WARNING: may include visible credentials +# This will not return enough data to crash your device. +DEBUG_DEVICE = False + +# No data from midnight to 00:15 due to lack of 15 values. +# Debug midnight to display something else in this time frame. +MIDNIGHT_DEBUG = False -# Time between API refreshes -# 300 = 5 mins, 900 = 15 mins, 1800 = 30 mins, 3600 = 1 hour -sleep_time = 900 +# WARNING: Optional: Resets board nvm to factory default. Clean slate. +# Instructions will be printed to console while reset is True. +RESET_NVM = False # Set True once, then back to False +if RESET_NVM: + microcontroller.nvm[0:64] = bytearray(b"\x00" * 64) +# API Polling Rate +# 900 = 15 mins, 1800 = 30 mins, 3600 = 1 hour +SLEEP_TIME = 900 + +# Initalize Wifi, Socket Pool, Request Session +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) -# Converts seconds in minutes/hours/days def time_calc(input_time): + """Converts seconds to minutes/hours/days""" if input_time < 60: - sleep_int = input_time - time_output = f"{sleep_int:.0f} seconds" - elif 60 <= input_time < 3600: - sleep_int = input_time / 60 - time_output = f"{sleep_int:.0f} minutes" - elif 3600 <= input_time < 86400: - sleep_int = input_time / 60 / 60 - time_output = f"{sleep_int:.1f} hours" - else: - sleep_int = input_time / 60 / 60 / 24 - time_output = f"{sleep_int:.1f} days" - return time_output + return f"{input_time:.0f} seconds" + if input_time < 3600: + return f"{input_time / 60:.0f} minutes" + if input_time < 86400: + return f"{input_time / 60 / 60:.0f} hours" + return f"{input_time / 60 / 60 / 24:.1f} days" # Authenticates Client ID & SHA-256 Token to POST -fitbit_oauth_header = {"Content-Type": "application/x-www-form-urlencoded"} -fitbit_oauth_token = "https://api.fitbit.com/oauth2/token" +FITBIT_OAUTH_HEADER = {"Content-Type": "application/x-www-form-urlencoded"} +FITBIT_OAUTH_TOKEN = "https://api.fitbit.com/oauth2/token" -# Connect to Wi-Fi -print("\n===============================") -print("Connecting to WiFi...") -requests = adafruit_requests.Session(pool, ssl.create_default_context()) -while not wifi.radio.ipv4_address: - try: - wifi.radio.connect(ssid, password) - except ConnectionError as e: - print("Connection Error:", e) - print("Retrying in 10 seconds") - time.sleep(10) -print("Connected!\n") - -# First run uses settings.toml token +# Use to confirm first instance of NVM is the correct refresh token +FIRST_RUN = True Refresh_Token = Fitbit_First_Refresh_Token - -if debug: - print(f"Top NVM Again (just to make sure): {top_nvm}") - print(f"Settings.toml Initial Refresh Token: {Fitbit_First_Refresh_Token}") - -latest_15_avg = "Latest 15 Minute Averages" -while True: - # Use Settings.toml refresh token on first run - if top_nvm != Fitbit_First_Refresh_Token: +top_nvm = microcontroller.nvm[0:64].decode() +nvm_bytes = microcontroller.nvm[0:64] +top_nvm_3bytes = nvm_bytes[0:3] +print(f"Top NVM Length: {len(top_nvm)}") +print(f"Top NVM: {top_nvm}") +print(f"Top NVM bytes: {top_nvm_3bytes}") +if RESET_NVM: + microcontroller.nvm[0:64] = bytearray(b"\x00" * 64) + if top_nvm_3bytes == b"\x00\x00\x00": + print("TOP NVM IS BRAND NEW! WAITING FOR A FIRST TOKEN") + Fitbit_First_Refresh_Token = top_nvm + print(f"Top NVM RESET: {top_nvm}") # No token should appear Refresh_Token = microcontroller.nvm[0:64].decode() - if debug: - # NVM 64 should match Current Refresh Token - print(f"NVM 64: {microcontroller.nvm[0:64].decode()}") - print(f"Current Refresh_Token: {Refresh_Token}") - else: - if debug: - # First run use settings.toml refresh token instead - print(f"Initial_Refresh_Token: {Refresh_Token}") - - try: - if debug: - print("\n-----Token Refresh POST Attempt -------") - fitbit_oauth_refresh_token = ( - "&grant_type=refresh_token" - + "&client_id=" - + str(Fitbit_ClientID) - + "&refresh_token=" - + str(Refresh_Token) - ) - - # ----------------------------- POST FOR REFRESH TOKEN ----------------------- - if debug: - print( - f"FULL REFRESH TOKEN POST:{fitbit_oauth_token}" - + f"{fitbit_oauth_refresh_token}" - ) - print(f"Current Refresh Token: {Refresh_Token}") - # TOKEN REFRESH POST - fitbit_oauth_refresh_POST = requests.post( - url=fitbit_oauth_token, - data=fitbit_oauth_refresh_token, - headers=fitbit_oauth_header, - ) - try: - fitbit_refresh_oauth_json = fitbit_oauth_refresh_POST.json() - - fitbit_new_token = fitbit_refresh_oauth_json["access_token"] - if debug: - print("Your Private SHA-256 Token: ", fitbit_new_token) - fitbit_access_token = fitbit_new_token # NEW FULL TOKEN - - # If current token valid will respond - fitbit_new_refesh_token = fitbit_refresh_oauth_json["refresh_token"] - Refresh_Token = fitbit_new_refesh_token - fitbit_token_expiration = fitbit_refresh_oauth_json["expires_in"] - fitbit_scope = fitbit_refresh_oauth_json["scope"] - fitbit_token_type = fitbit_refresh_oauth_json["token_type"] - fitbit_user_id = fitbit_refresh_oauth_json["user_id"] - if debug: - print("Next Refresh Token: ", Refresh_Token) - - # Store Next Token into NVM + print(f"Refresh_Token Reset: {Refresh_Token}") # No token should appear +while True: + if not RESET_NVM: + # Connect to Wi-Fi + print("\n📡 Connecting to WiFi...") + while not wifi.radio.ipv4_address: try: - nvmtoken = b"" + fitbit_new_refesh_token + wifi.radio.connect(ssid, password) + except ConnectionError as e: + print("❌ Connection Error:", e) + print("Retrying in 10 seconds") + print("✅ WiFi!") + + if top_nvm is not Refresh_Token and FIRST_RUN is False: + FIRST_RUN = False + Refresh_Token = microcontroller.nvm[0:64].decode() + print(" | INDEFINITE RUN -------") + if DEBUG: + print("Top NVM is Fitbit First Refresh Token") + # NVM 64 should match Current Refresh Token + print(f"NVM 64: {microcontroller.nvm[0:64].decode()}") + print(f"Current Refresh_Token: {Refresh_Token}") + if top_nvm != Fitbit_First_Refresh_Token and FIRST_RUN is True: + if top_nvm_3bytes == b"\x00\x00\x00": + print(" | TOP NVM IS BRAND NEW! WAITING FOR A FIRST TOKEN") + Refresh_Token = Fitbit_First_Refresh_Token + nvmtoken = b"" + Refresh_Token microcontroller.nvm[0:64] = nvmtoken - if debug: - print(f"Next Token for NVM: {nvmtoken.decode()}") - print("Next token written to NVM Successfully!") - except OSError as e: - print("OS Error:", e) - continue - - if debug: - # Extraneous token data for debugging - print("Token Expires in: ", time_calc(fitbit_token_expiration)) - print("Scope: ", fitbit_scope) - print("Token Type: ", fitbit_token_type) - print("UserID: ", fitbit_user_id) - - except KeyError as e: - print("Key Error:", e) - print("Expired token, invalid permission, or (key:value) pair error.") - time.sleep(300) - continue - - # ----------------------------- GET DATA ------------------------------------- - # POST should respond with current & next refresh token we can GET for data - # 64-bit Refresh tokens will "keep alive" SHA-256 token indefinitely - # Fitbit main SHA-256 token expires in 8 hours unless refreshed! - # ---------------------------------------------------------------------------- - detail_level = "1min" # Supported: 1sec | 1min | 5min | 15min - requested_date = "today" # Date format yyyy-MM-dd or today - fitbit_header = { - "Authorization": "Bearer " + fitbit_access_token + "", - "Client-Id": "" + Fitbit_ClientID + "", - } - # Heart Intraday Scope - FITBIT_SOURCE = ( - "https://api.fitbit.com/1/user/" - + Fitbit_UserID - + "/activities/heart/date/today" - + "/1d/" - + detail_level - + ".json" - ) - - print("\nAttempting to GET FITBIT Stats!") - print("===============================") - fitbit_get_response = requests.get(url=FITBIT_SOURCE, headers=fitbit_header) + else: + if DEBUG: + print(f"Top NVM: {top_nvm}") + print(f"First Refresh: {Refresh_Token}") + print(f"First Run: {FIRST_RUN}") + Refresh_Token = top_nvm + FIRST_RUN = False + print(" | MANUAL REBOOT TOKEN DIFFERENCE -------") + if DEBUG: + # NVM 64 should not match Current Refresh Token + print("Top NVM is NOT Fitbit First Refresh Token") + print(f"NVM 64: {microcontroller.nvm[0:64].decode()}") + print(f"Current Refresh_Token: {Refresh_Token}") + if top_nvm == Refresh_Token and FIRST_RUN is True: + if DEBUG: + print(f"Top NVM: {top_nvm}") + print(f"First Refresh: {Refresh_Token}") + print(f"First Run: {FIRST_RUN}") + Refresh_Token = Fitbit_First_Refresh_Token + nvmtoken = b"" + Refresh_Token + microcontroller.nvm[0:64] = nvmtoken + FIRST_RUN = False + print(" | FIRST RUN SETTINGS.TOML TOKEN-------") + if DEBUG: + # NVM 64 should match Current Refresh Token + print("Top NVM IS Fitbit First Refresh Token") + print(f"NVM 64: {microcontroller.nvm[0:64].decode()}") + print(f"Current Refresh_Token: {Refresh_Token}") try: - fitbit_json = fitbit_get_response.json() - intraday_response = fitbit_json["activities-heart-intraday"]["dataset"] - except ConnectionError as e: - print("Connection Error:", e) - print("Retrying in 10 seconds") + if DEBUG: + print("\n-----Token Refresh POST Attempt -------") + FITBIT_OAUTH_REFRESH_TOKEN = ( + "&grant_type=refresh_token" + + "&client_id=" + + str(Fitbit_ClientID) + + "&refresh_token=" + + str(Refresh_Token) + ) - if debug: - print(f"Full API GET URL: {FITBIT_SOURCE}") - print(f"Header: {fitbit_header}") - # print(f"JSON Full Response: {fitbit_json}") - # print(f"Intraday Full Response: {intraday_response}") + # ------------------------- POST FOR REFRESH TOKEN -------------------- + print(" | Requesting authorization for next token") + if DEBUG: + print( + "FULL REFRESH TOKEN POST:" + + f"{FITBIT_OAUTH_TOKEN}{FITBIT_OAUTH_REFRESH_TOKEN}" + ) + print(f"Current Refresh Token: {Refresh_Token}") + # TOKEN REFRESH POST + try: + fitbit_oauth_refresh_POST = requests.post( + url=FITBIT_OAUTH_TOKEN, + data=FITBIT_OAUTH_REFRESH_TOKEN, + headers=FITBIT_OAUTH_HEADER, + ) + except adafruit_requests.OutOfRetries as ex: + print(f"OutOfRetries: {ex}") + break + try: + fitbit_refresh_oauth_json = fitbit_oauth_refresh_POST.json() + + fitbit_new_token = fitbit_refresh_oauth_json["access_token"] + if DEBUG: + print("Your Private SHA-256 Token: ", fitbit_new_token) + fitbit_access_token = fitbit_new_token # NEW FULL TOKEN + + # Overwrites Initial/Old Refresh Token with Next/New Refresh Token + fitbit_new_refesh_token = fitbit_refresh_oauth_json["refresh_token"] + Refresh_Token = fitbit_new_refesh_token + + fitbit_token_expiration = fitbit_refresh_oauth_json["expires_in"] + fitbit_scope = fitbit_refresh_oauth_json["scope"] + fitbit_token_type = fitbit_refresh_oauth_json["token_type"] + fitbit_user_id = fitbit_refresh_oauth_json["user_id"] + if DEBUG: + print("Next Refresh Token: ", Refresh_Token) + try: + # Stores Next token in NVM + nvmtoken = b"" + Refresh_Token + microcontroller.nvm[0:64] = nvmtoken + if DEBUG: + print(f"nvmtoken: {nvmtoken}") + # It's better to always have next token visible. + # You can manually set this token into settings.toml + print(f" | Next Token: {nvmtoken.decode()}") + print(" | 🔑 Next token written to NVM Successfully!") + except (OSError) as e: + print("OS Error:", e) + continue + if DEBUG: + print("Token Expires in: ", time_calc(fitbit_token_expiration)) + print("Scope: ", fitbit_scope) + print("Token Type: ", fitbit_token_type) + print("UserID: ", fitbit_user_id) + except (KeyError) as e: + print("Key Error:", e) + print("Expired token, invalid permission, or (key:value) pair error.") + time.sleep(SLEEP_TIME) + continue + # ----------------------------- GET DATA --------------------------------- + # Now that we have POST response with next refresh token we can GET for data + # 64-bit Refresh tokens will "keep alive" SHA-256 token indefinitely + # Fitbit main SHA-256 token expires in 8 hours unless refreshed! + # ------------------------------------------------------------------------ + DETAIL_LEVEL = "1min" # Supported: 1sec | 1min | 5min | 15min + REQUESTED_DATE = "today" # Date format yyyy-MM-dd or "today" + fitbit_header = { + "Authorization": "Bearer " + fitbit_access_token + "", + "Client-Id": "" + Fitbit_ClientID + "", + } + # Heart Intraday Scope + FITBIT_INTRADAY_SOURCE = ( + "https://api.fitbit.com/1/user/" + + Fitbit_UserID + + "/activities/heart/date/" + + REQUESTED_DATE + + "/1d/" + + DETAIL_LEVEL + + ".json" + ) + # Device Details + FITBIT_DEVICE_SOURCE = ( + "https://api.fitbit.com/1/user/" + Fitbit_UserID + "/devices.json" + ) - try: - # Fitbit's sync to your mobile device & server every 15 minutes in chunks. - # Pointless to poll their API faster than 15 minute intervals. - activities_heart_value = fitbit_json["activities-heart-intraday"]["dataset"] - response_length = len(activities_heart_value) - if response_length >= 15: - activities_timestamp = fitbit_json["activities-heart"][0]["dateTime"] - print(f"Fitbit Date: {activities_timestamp}") - activities_latest_heart_time = fitbit_json["activities-heart-intraday"][ + print(" | Attempting to GET Fitbit JSON!") + FBIS = FITBIT_INTRADAY_SOURCE + FBH = fitbit_header + fitbit_get_response = requests.get(url=FBIS, headers=FBH) + try: + fitbit_json = fitbit_get_response.json() + except ConnectionError as e: + print("Connection Error:", e) + print("Retrying in 10 seconds") + print(" | ✅ Fitbit Intraday JSON!") + + if DEBUG: + print(f"Full API GET URL: {FBIS}") + print(f"Header: {fitbit_header}") + # This might crash your microcontroller. + # Commented out even in debug. Use only if absolutely necessary. + + # print(f"JSON Full Response: {fitbit_json}") + Intraday_Response = fitbit_json["activities-heart-intraday"]["dataset"] + # print(f"Intraday Full Response: {Intraday_Response}") + try: + # Fitbit's sync to mobile device & server every 15 minutes in chunks. + # Pointless to poll their API faster than 15 minute intervals. + activities_heart_value = fitbit_json["activities-heart-intraday"][ "dataset" - ][response_length - 1]["time"] - print(f"Fitbit Time: {activities_latest_heart_time[0:-3]}") - print(f"Today's Logged Pulses : {response_length}") - - # Each 1min heart rate is a 60 second average - activities_latest_heart_value0 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 1]["value"] - activities_latest_heart_value1 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 2]["value"] - activities_latest_heart_value2 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 3]["value"] - activities_latest_heart_value3 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 4]["value"] - activities_latest_heart_value4 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 5]["value"] - activities_latest_heart_value5 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 6]["value"] - activities_latest_heart_value6 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 7]["value"] - activities_latest_heart_value7 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 8]["value"] - activities_latest_heart_value8 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 9]["value"] - activities_latest_heart_value9 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 10]["value"] - activities_latest_heart_value10 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 11]["value"] - activities_latest_heart_value11 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 12]["value"] - activities_latest_heart_value12 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 13]["value"] - activities_latest_heart_value13 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 14]["value"] - activities_latest_heart_value14 = fitbit_json[ - "activities-heart-intraday" - ]["dataset"][response_length - 15]["value"] - latest_15_avg = "Latest 15 Minute Averages" + ] + if MIDNIGHT_DEBUG: + RESPONSE_LENGTH = 0 + else: + RESPONSE_LENGTH = len(activities_heart_value) + if RESPONSE_LENGTH >= 15: + activities_timestamp = fitbit_json["activities-heart"][0][ + "dateTime" + ] + print(f" | | Fitbit Date: {activities_timestamp}") + if MIDNIGHT_DEBUG: + ACTIVITIES_LATEST_HEART_TIME = str("00:05:00") + else: + ACTIVITIES_LATEST_HEART_TIME = fitbit_json[ + "activities-heart-intraday" + ]["dataset"][RESPONSE_LENGTH - 1]["time"] + print(f" | | Fitbit Time: {ACTIVITIES_LATEST_HEART_TIME[0:-3]}") + print(f" | | Today's Logged Pulses: {RESPONSE_LENGTH}") + + # Each 1min heart rate is a 60 second average + LATEST_15_AVG = " | | Latest 15 Minute Averages: " + LATEST_15_VALUES = ", ".join( + str(activities_heart_value[i]["value"]) + for i in range(RESPONSE_LENGTH - 1, RESPONSE_LENGTH - 16, -1) + ) + print(f"{LATEST_15_AVG}{LATEST_15_VALUES}") + else: + print(" | Waiting for latest sync...") + print(" | ❌ Not enough values for today to display yet.") + except (KeyError) as keyerror: + print(f"Key Error: {keyerror}") print( - f"{latest_15_avg}" - + f"{activities_latest_heart_value14}," - + f"{activities_latest_heart_value13}," - + f"{activities_latest_heart_value12}," - + f"{activities_latest_heart_value11}," - + f"{activities_latest_heart_value10}," - + f"{activities_latest_heart_value9}," - + f"{activities_latest_heart_value8}," - + f"{activities_latest_heart_value7}," - + f"{activities_latest_heart_value6}," - + f"{activities_latest_heart_value5}," - + f"{activities_latest_heart_value4}," - + f"{activities_latest_heart_value3}," - + f"{activities_latest_heart_value2}," - + f"{activities_latest_heart_value1}," - + f"{activities_latest_heart_value0}" + "Too Many Requests, " + + "Expired token, " + + "invalid permission, " + + "or (key:value) pair error." ) - else: - print("Waiting for latest 15 values sync...") - print("Not enough values for today to display yet.") - print("No display from midnight to 00:15") - - except KeyError as keyerror: - print(f"Key Error: {keyerror}") - print( - "Too Many Requests, Expired token," - + "invalid permission," - + "or (key:value) pair error." - ) + time.sleep(60) + continue + # Getting Fitbit Device JSON (separate from intraday) + # Separate call for Watch Battery Percentage. + print(" | Attempting to GET Device JSON!") + FBDS = FITBIT_DEVICE_SOURCE + FBH = fitbit_header + fitbit_get_device_response = requests.get(url=FBDS, headers=FBH) + try: + fitbit_device_json = fitbit_get_device_response.json() + except ConnectionError as e: + print("Connection Error:", e) + print("Retrying in 10 seconds") + print(" | ✅ Fitbit Device JSON!") + + if DEBUG_DEVICE: + print(f"Full API GET URL: {FITBIT_DEVICE_SOURCE}") + print(f"Header: {fitbit_header}") + print(f"JSON Full Response: {fitbit_device_json}") + Device_Response = fitbit_device_json[1]["batteryLevel"] + print(f" | | Watch Battery %: {Device_Response}") + + print("\nFinished!") + print(f"Board Uptime: {time_calc(time.monotonic())}") + print(f"Next Update: {time_calc(SLEEP_TIME)}") + print("===============================") + except (ValueError, RuntimeError) as e: + print("Failed to get data, retrying\n", e) + time.sleep(60) continue - - print("Board Uptime: ", time_calc(time.monotonic())) # Board Up-Time seconds - print("\nFinished!") - print("Next Update in: ", time_calc(sleep_time)) - print("===============================") - - except (ValueError, RuntimeError) as e: - print("Failed to get data, retrying\n", e) - time.sleep(60) - continue - time.sleep(sleep_time) + time.sleep(SLEEP_TIME) + else: + print("🚮 NVM Cleared!") + print( + "⚠️ Save your new access token & refresh token from" + "Fitbits Tutorial (Step 4) to settings.toml now." + ) + print( + "⚠️ If the script runs again" + "(due to settings.toml file save) while reset=True that's ok!" + ) + print("⚠️ Then set RESET_NVM back to False.") + break From 339294d48f9719edf528b89e2296d82a3470c55c Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Sun, 17 Mar 2024 16:57:38 -0400 Subject: [PATCH 06/10] Update Discord Web Scrape Example with Connection Manager --- examples/wifi/expanded/requests_wifi_api_fitbit.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/wifi/expanded/requests_wifi_api_fitbit.py b/examples/wifi/expanded/requests_wifi_api_fitbit.py index af6227b..391a46e 100644 --- a/examples/wifi/expanded/requests_wifi_api_fitbit.py +++ b/examples/wifi/expanded/requests_wifi_api_fitbit.py @@ -86,9 +86,10 @@ def time_calc(input_time): top_nvm = microcontroller.nvm[0:64].decode() nvm_bytes = microcontroller.nvm[0:64] top_nvm_3bytes = nvm_bytes[0:3] -print(f"Top NVM Length: {len(top_nvm)}") -print(f"Top NVM: {top_nvm}") -print(f"Top NVM bytes: {top_nvm_3bytes}") +if DEBUG: + print(f"Top NVM Length: {len(top_nvm)}") + print(f"Top NVM: {top_nvm}") + print(f"Top NVM bytes: {top_nvm_3bytes}") if RESET_NVM: microcontroller.nvm[0:64] = bytearray(b"\x00" * 64) if top_nvm_3bytes == b"\x00\x00\x00": From 62927ff9e77f679aefe5dec3e0b298b3be5b2bb7 Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Sun, 17 Mar 2024 17:02:21 -0400 Subject: [PATCH 07/10] ran black and pylint again --- examples/wifi/expanded/requests_wifi_api_fitbit.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/wifi/expanded/requests_wifi_api_fitbit.py b/examples/wifi/expanded/requests_wifi_api_fitbit.py index 391a46e..ac79c95 100644 --- a/examples/wifi/expanded/requests_wifi_api_fitbit.py +++ b/examples/wifi/expanded/requests_wifi_api_fitbit.py @@ -7,8 +7,8 @@ import os import time -import microcontroller import adafruit_connection_manager +import microcontroller import wifi import adafruit_requests @@ -210,7 +210,7 @@ def time_calc(input_time): # You can manually set this token into settings.toml print(f" | Next Token: {nvmtoken.decode()}") print(" | 🔑 Next token written to NVM Successfully!") - except (OSError) as e: + except OSError as e: print("OS Error:", e) continue if DEBUG: @@ -218,7 +218,7 @@ def time_calc(input_time): print("Scope: ", fitbit_scope) print("Token Type: ", fitbit_token_type) print("UserID: ", fitbit_user_id) - except (KeyError) as e: + except KeyError as e: print("Key Error:", e) print("Expired token, invalid permission, or (key:value) pair error.") time.sleep(SLEEP_TIME) @@ -303,7 +303,7 @@ def time_calc(input_time): else: print(" | Waiting for latest sync...") print(" | ❌ Not enough values for today to display yet.") - except (KeyError) as keyerror: + except KeyError as keyerror: print(f"Key Error: {keyerror}") print( "Too Many Requests, " From 446a88904cc2ebd613dc8a47f9256efd52575354 Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Sun, 17 Mar 2024 17:14:40 -0400 Subject: [PATCH 08/10] minor spelling edit --- examples/wifi/expanded/requests_wifi_api_fitbit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/wifi/expanded/requests_wifi_api_fitbit.py b/examples/wifi/expanded/requests_wifi_api_fitbit.py index ac79c95..7658eeb 100644 --- a/examples/wifi/expanded/requests_wifi_api_fitbit.py +++ b/examples/wifi/expanded/requests_wifi_api_fitbit.py @@ -7,8 +7,8 @@ import os import time -import adafruit_connection_manager import microcontroller +import adafruit_connection_manager import wifi import adafruit_requests @@ -345,7 +345,7 @@ def time_calc(input_time): else: print("🚮 NVM Cleared!") print( - "⚠️ Save your new access token & refresh token from" + "⚠️ Save your new access token & refresh token from " "Fitbits Tutorial (Step 4) to settings.toml now." ) print( From 717e4c4d50345380772bfdc1140df2ef1299d17b Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Sun, 17 Mar 2024 17:23:30 -0400 Subject: [PATCH 09/10] minor spelling edit --- examples/wifi/expanded/requests_wifi_api_fitbit.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/wifi/expanded/requests_wifi_api_fitbit.py b/examples/wifi/expanded/requests_wifi_api_fitbit.py index 7658eeb..81050fd 100644 --- a/examples/wifi/expanded/requests_wifi_api_fitbit.py +++ b/examples/wifi/expanded/requests_wifi_api_fitbit.py @@ -7,11 +7,10 @@ import os import time -import microcontroller import adafruit_connection_manager -import wifi - import adafruit_requests +import microcontroller +import wifi # --- Fitbit Developer Account & oAuth App Required: --- # Required: Google Login (Fitbit owned by Google) & Fitbit Device From a7e20145e9946d9d25b8852fcbd9e8be3036c303 Mon Sep 17 00:00:00 2001 From: DJDevon3 <49322231+DJDevon3@users.noreply.github.com> Date: Sun, 17 Mar 2024 17:28:36 -0400 Subject: [PATCH 10/10] isort is giving me trouble --- examples/wifi/expanded/requests_wifi_api_fitbit.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/wifi/expanded/requests_wifi_api_fitbit.py b/examples/wifi/expanded/requests_wifi_api_fitbit.py index 81050fd..802995c 100644 --- a/examples/wifi/expanded/requests_wifi_api_fitbit.py +++ b/examples/wifi/expanded/requests_wifi_api_fitbit.py @@ -8,10 +8,11 @@ import time import adafruit_connection_manager -import adafruit_requests import microcontroller import wifi +import adafruit_requests + # --- Fitbit Developer Account & oAuth App Required: --- # Required: Google Login (Fitbit owned by Google) & Fitbit Device # Step 1: Register a personal app here: https://dev.fitbit.com