What is the Adafruit Connection Manager? It is a helper class designed around making connections to the internet easier and does this by simplifying a few things.
First, what are the underlying pieces we need to connect to the internet?
Sockets
Everything that connects to the internet needs a socket. A socket is what handles the basic sending and receiving of messages between 2 devices (like your microcontroller and a web API).
Microcontrollers, unlike desktop computers, have limited memory and can't have 100s of sockets open. The average chip can have maybe 2-3 and the bigger ones top out around 10.
Previously the sockets were controlled at a per library level. Meaning if you used adafruit_requests (to get info from the web) and adafruit_minimqtt (to send something to AdafruitIO) they both managed sockets separately, which means that one might block the other from getting one. And on top of that, the way you interfaced with them was different!
Here comes ConnectionManager to the rescue! Both these libraries now ask the ConnectionManager for a socket and it handles tracking what's open and what's not. And to make code even simpler, it's what's called a singleton. There is only one, where previously you needed to create your requests.Session() early in your code and use that one everywhere, now it doesn't matter.
Socket Pool and SSL Context Helpers
What are these?
The socketpool is what creates the sockets for each internet connected chip, and the ssl_context is what has all the certificate information to validate that the connection is secure.
import wifi
import adafruit_connection_manager
import adafruit_requests
radio = wifi.radio
# this could also be
#
# import board
# import busio
# from adafruit_esp32spi.adafruit_esp32spi import ESP_SPIcontrol
# from digitalio import DigitalInOut
# esp32_cs = DigitalInOut(board.D13)
# esp32_ready = DigitalInOut(board.D11)
# esp32_reset = DigitalInOut(board.D12)
# spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
# radio = ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
#
# or
#
# import board
# import busio
# from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
# from digitalio import DigitalInOut
# cs = DigitalInOut(board.D10)
# spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# radio = WIZNET5K(spi_bus, cs)
# code to make sure your radio is connected
pool = adafruit_connection_manager.get_radio_socketpool(radio)
ssl_context = adafruit_connection_manager.get_radio_ssl_context(radio)
requests = adafruit_requests.Session(pool, ssl_context)
requests.get("http://wifitest.adafruit.com/testwifi/index.html")
# Do something with response
If you had used the previous methods, see how you have fewer imports? And getting the socket pool and ssl context is the same regardless of configuration?
There is still the fact that if you are using a SPI device like the esp32spi or wiznet5k, these will need to setup in the same fashion (getting all the pins and such), and aren't as easy as just import wifi.
For more examples on using requests, checkout the example folder in the adafruit_requests code repository:
These same methods work with adafruit_minimqtt as well:
import wifi
import adafruit_connection_manager
import adafruit_requests
radio = wifi.radio
# code to make sure your radio is connected
pool = adafruit_connection_manager.get_radio_socketpool(radio)
ssl_context = adafruit_connection_manager.get_radio_ssl_context(radio)
mqtt_client = MQTT.MQTT(
broker="io.adafruit.com",
port=1883,
username=aio_username,
password=aio_key,
socket_pool=pool,
ssl_context=ssl_context,
)
# do something with mqtt_client
For more detailed information on MQTT and Adafruit IO, checkout the guide:
How do I get this new cool update? Well, you can download the newest bundle. Or...
Use CircUp!
Here you can see I just have an old version of adafruit_requests installed. But after running circup update, it both updated adafruit_requests and installed adafruit_connection_manager!
Bam that was easy. Want to learn more about CircUp? Checkout the learn guide:
# ----------
# This example is deprecated. Although these methods still work,
# it's recomended you update to the new standard
# ----------
import socketpool
import ssl
import wifi
import adafruit_requests
# code to make sure your wifi.radio is connected
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
response = requests.get("http://wifitest.adafruit.com/testwifi/index.html")
# Do something with response
# ----------
# This example is deprecated. Do not use
# ----------
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from adafruit_esp32spi.adafruit_esp32spi import ESP_SPIcontrol
import adafruit_requests as requests
# code to setup your esp32spi and make sure it is connected
# esp = ESP_SPIcontrol(...)
requests.set_socket(socket, esp)
requests.get("http://wifitest.adafruit.com/testwifi/index.html")
# ----------
# This example is deprecated. Do not use
# ----------
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
import adafruit_requests as requests
# code to setup your wiznet5k and make sure it is connected
# eth = WIZNET5K(...)
requests.set_socket(socket, eth)
requests.get("http://wifitest.adafruit.com/testwifi/index.html")
# Do something with response
For the esp32spi and wiznet5k the requests.set_socket() method would build out the socket pool and generate a SSL wrapper and pass it to requests.Session().
Imagine you want to write code that easily transfers between devices? Not impossible, but not simple.
import os
import adafruit_connection_manager
import adafruit_requests
import wifi
wifi_ssid = os.getenv("CIRCUITPY_WIFI_SSID")
wifi_password = os.getenv("CIRCUITPY_WIFI_PASSWORD")
print("\nConecting to WiFi...")
radio = wifi.radio
while not radio.connected:
radio.connect(wifi_ssid, wifi_password)
print("Connected!")
pool = adafruit_connection_manager.get_radio_socketpool(radio)
ssl_context = adafruit_connection_manager.get_radio_ssl_context(radio)
print("\nGetting sessions...")
sessions = {}
session_id = 0
while True:
session_id += 1
try:
requests = adafruit_requests.Session(pool, ssl_context, session_id=str(session_id))
response = requests.get("http://www.adafruit.com/api/quotes.php")
sessions[session_id] = {
"requests": requests,
"response": response,
"result": "",
"more": True,
}
print(f"Started session {session_id}")
except Exception as e:
print(f"Error getting {session_id} session: {e}")
break
print("\nFetching...")
chunk_size = 5
b = bytearray(chunk_size)
while True:
any_more = False
for session_id, data in sessions.items():
if data["more"]:
size = data["response"]._readinto(b)
if size:
any_more = True
data["result"] += str(b[:size], "utf-8")
else:
data["more"] = False
data["response"].close()
print(f"{session_id}: {data["result"]}")
if not any_more:
break
For non-integrated WiFi (esp32spi and wiznet5k) I used:
For onboard WiFi I used a few boards of different levels. I started with a ESP32-S3 TFT Feather, Then a Pico W and finally the FeatherS3 by Unexpected Maker
This page (Adafruit Connection Manager) was last updated on March 05, 2024.