Aspide is a smart, tactile, rotary controller built with
CircuitPython for the Adafruit QT Py ESP32-S2
board.
This device provides a physical interface to control
Home Assistant scenes and lights with rich
visual feedback via a NeoPixel strip.
Aspide is inspired by two of the many, great, tutorials created by Adafruit:
- Triple Control Modes: Switch between controlling Home Assistant scenes, light effects, and brightness presets.
- NeoPixel Visual Feedback:
- Mode indicators (Blue for scenes, Amber for effects, White for brightness).
- Scene/Effect/Brightness previews with colors matching the selected setting.
- Home Assistant Integration: Uses the HA REST API for reliable, low-latency control.
- Manufacturer-Agnostic Light Control: Controls any HA
light.*entity through Home Assistant — no direct UDP or vendor-specific libraries required. - Inactivity Timer: Automatically dims NeoPixels after a period of inactivity to save power and reduce light pollution.
- HA Health Check: Periodically verifies Home Assistant connectivity and reboots if unreachable after retries (automatic recovery).
- Microcontroller: Adafruit QT Py ESP32-S2 WiFi Dev Board with STEMMA QT
- Input: Adafruit I2C Stemma QT Rotary Encoder Breakout with Encoder - STEMMA QT / Qwiic
- Output: Adafruit NeoPixel LED Side Light Strip
- STEMMA cable: STEMMA QT / Qwiic JST SH 4-Pin Cable
- USB cable: USB A to USB C Cable
- Power cable: Stranded-Core Ribbon Cable - 4 Wires or 3 single cables (stranded)
- Enclosure: 3D printed case for the USB Rotary Media Dial
- Enclosure Screws: 4 M2.5 x 6mm steel machine screws
The device is configured via a settings.toml file located in the root of the
CIRCUITPY drive.
CIRCUITPY_WIFI_SSID = "Your_SSID"
CIRCUITPY_WIFI_PASSWORD = "Your_Password"To connect to Home Assistant, you need your server URL and a Long-Lived Access Token (generated from your HA user profile).
HA_URL = "http://192.168.1.78:8123"
HA_TOKEN = "your_long_lived_access_token_here"
# List of HA scenes to iterate through in 'home_assistant' mode
HA_SCENES = "scene.nightlights,scene.lightsoff,scene.atdesk_soft_lights,scene.softlights1"
# Light entity for ha_light and ha_brightness modes
HA_LIGHT_ENTITY_ID = "light.wiz_01"
# Effects to browse in ha_light mode (comma-separated, must match HA effect_list)
# Leave empty to use built-in defaults: Warm White, Daylight, Sunset, Focus
HA_LIGHT_EFFECTS = "Warm White,Daylight,Sunset,Focus"
# NeoPixel preview colors for effects (1:1 with HA_LIGHT_EFFECTS; optional)
HA_LIGHT_EFFECT_COLORS = "bright_yellow,bright_white,dim_orange,dim_green"
# Brightness presets for ha_brightness mode (off=0, low=64, mid=128, high=191, max=255)
HA_LIGHT_BRIGHTNESS = "off,low,mid,high,max"
# Optional NeoPixel preview override (1:1 with HA_LIGHT_BRIGHTNESS)
# If omitted, preview scales white to match each preset's HA brightness
# HA_LIGHT_BRIGHTNESS_COLORS = ""Customize the behavior and appearance of the LED ring.
# Seconds of inactivity before NeoPixels turn off
NEOPIXEL_TIMEOUT = 30
# Colors for HA scenes (maps 1-to-1 with HA_SCENES above)
# Available intensities: bright_, soft_, dim_
# Available colors: white, green, red, blue, purple, cyan, yellow, orange, pink, gold, black
HA_SCENE_COLORS = "dim_blue,black,soft_white,dim_white"- Rotate: Browse through the available scenes, effects, or brightness presets. The NeoPixel ring will change color to provide a preview.
- Single Push: Activate the currently selected scene, effect, or brightness preset.
- Double Push: Perform a hard reset of the device (reboots and reconnects to WiFi).
- Long Push: Cycle through Home Assistant Mode (Blue), Light Effects Mode (Amber), and Brightness Mode (White).
- Home Assistant Mode: Cycles through the scenes defined in
HA_SCENES. The NeoPixels will match the colors defined inHA_SCENE_COLORS. - Light Effects Mode (
ha_light): Cycles through effects defined inHA_LIGHT_EFFECTS, or uses built-in defaults (Warm White, Daylight, Sunset, Focus) when empty. Effect names must match what your light integration exposes. NeoPixel preview colors come fromHA_LIGHT_EFFECT_COLORS. - Brightness Mode (
ha_brightness): Cycles through five presets inHA_LIGHT_BRIGHTNESS(default: off, low, mid, high, max — 0% to 100% in 25% steps). Single push sendslight.turn_onwith the corresponding brightness level. NeoPixel preview scales white to match each preset unless overridden viaHA_LIGHT_BRIGHTNESS_COLORS.
Every 5 minutes (configurable via optional HA_PHONE_HOME_INTERVAL), the device
pings Home Assistant. If the API is unreachable, it retries twice at 5-second
intervals (reconnecting WiFi if needed), then reboots to recover device-side
network state. If Home Assistant remains down, this cycle repeats each interval
until HA responds.
- Install CircuitPython on your QT Py ESP32-S2
- Copy the contents of the
src/directory to the root of yourCIRCUITPYdrive - Make sure all the required libraries have been copied into the
lib/folder - Use
settings.sample.tomlas template to configure yoursettings.toml - Enjoy!








