{"id":51514586,"url":"https://github.com/xenos76/aspide","last_synced_at":"2026-07-08T10:00:49.690Z","repository":{"id":365455505,"uuid":"1268087917","full_name":"xenOs76/aspide","owner":"xenOs76","description":"Home Assistant \u0026 Python powered Dialer","archived":false,"fork":false,"pushed_at":"2026-06-17T11:01:12.000Z","size":5474,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-17T13:05:32.329Z","etag":null,"topics":["3d-printing","adafruit","assistant","automation","circuitpython","home","maker","makers","neopixel","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xenOs76.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-13T06:05:15.000Z","updated_at":"2026-06-17T11:01:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/xenOs76/aspide","commit_stats":null,"previous_names":["xenos76/aspide"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/xenOs76/aspide","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xenOs76%2Faspide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xenOs76%2Faspide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xenOs76%2Faspide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xenOs76%2Faspide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xenOs76","download_url":"https://codeload.github.com/xenOs76/aspide/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xenOs76%2Faspide/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35260671,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-08T02:00:06.796Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["3d-printing","adafruit","assistant","automation","circuitpython","home","maker","makers","neopixel","python"],"created_at":"2026-07-08T10:00:47.850Z","updated_at":"2026-07-08T10:00:49.673Z","avatar_url":"https://github.com/xenOs76.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Aspide\n\n\u003cp align=\"center\"\u003e\n    \u003cimg width=\"450\" alt=\"Aspide Logo\" src=\"./assets/img/aspide-logo.jpg\"/\u003e\n\u003c/p\u003e\n\n**Aspide** is a smart, tactile, rotary controller built with\n[CircuitPython](https://circuitpython.org/) for the Adafruit QT Py ESP32-S2\nboard.\\\nThis device provides a physical interface to control\n[Home Assistant](https://www.home-assistant.io/) scenes and lights with rich\nvisual feedback via a NeoPixel strip.\n\n**Aspide** is inspired by two of the many, great, tutorials created by\n[Adafruit](https://www.adafruit.com/):\n\n- [USB Rotary Media Dial](https://learn.adafruit.com/usb-rotary-media-dial)\n- [Control Wiz Lights With CircuitPython](https://learn.adafruit.com/control-wiz-lights-with-circuitpython/overview)\n\n## Features\n\n- **Triple Control Modes**: Switch between controlling _Home Assistant scenes_,\n  _light effects_, and _brightness presets_.\n- **NeoPixel Visual Feedback**:\n  - Mode indicators (Blue for scenes, Amber for effects, White for brightness).\n  - Scene/Effect/Brightness previews with colors matching the selected setting.\n- **Home Assistant Integration**: Uses the HA REST API for reliable, low-latency\n  control.\n- **Manufacturer-Agnostic Light Control**: Controls any HA `light.*` entity\n  through Home Assistant — no direct UDP or vendor-specific libraries required.\n- **Inactivity Timer**: Automatically dims NeoPixels after a period of\n  inactivity to save power and reduce light pollution.\n- **HA Health Check**: Periodically verifies Home Assistant connectivity and\n  reboots if unreachable after retries (automatic recovery).\n\n## Screenshots\n\n\u003cdetails\u003e\n    \u003cp align=\"center\"\u003e\n        \u003cimg width=\"450\" alt=\"Aspide Screeenshot 1\" src=\"./assets/img/aspide-screenshot1-small.jpg\"/\u003e\n        \u003cimg width=\"450\" alt=\"Aspide Screeenshot 1\" src=\"./assets/img/aspide-screenshot2-small.jpg\"/\u003e\n        \u003cimg width=\"450\" alt=\"Aspide Screeenshot 1\" src=\"./assets/img/aspide-screenshot3-small.jpg\"/\u003e\n        \u003cimg width=\"450\" alt=\"Aspide Screeenshot 1\" src=\"./assets/img/aspide-screenshot4-small.jpg\"/\u003e\n        \u003cimg width=\"450\" alt=\"Aspide Screeenshot 1\" src=\"./assets/img/aspide-screenshot5-small.jpg\"/\u003e\n        \u003cimg width=\"450\" alt=\"Aspide Screeenshot 1\" src=\"./assets/img/aspide-screenshot6-small.jpg\"/\u003e\n        \u003cimg width=\"450\" alt=\"Aspide Screeenshot 1\" src=\"./assets/img/aspide-screenshot7-small.jpg\"/\u003e\n    \u003c/p\u003e\n\u003c/details\u003e\n\n## Hardware Requirements\n\n- **Microcontroller**:\n  [Adafruit QT Py ESP32-S2 WiFi Dev Board with STEMMA QT](https://www.adafruit.com/product/5325)\n- **Input**:\n  [Adafruit I2C Stemma QT Rotary Encoder Breakout with Encoder - STEMMA QT / Qwiic](https://www.adafruit.com/product/5880)\n- **Output**:\n  [Adafruit NeoPixel LED Side Light Strip](https://www.adafruit.com/product/3634)\n- **STEMMA cable**:\n  [STEMMA QT / Qwiic JST SH 4-Pin Cable](https://www.adafruit.com/product/4399)\n- **USB cable**:\n  [USB A to USB C Cable](https://www.amazon.de/dp/B0D72YLKWL?ref=ppx_yo2ov_dt_b_fed_asin_title\u0026th=1)\n- **Power cable**:\n  [Stranded-Core Ribbon Cable - 4 Wires](https://www.adafruit.com/product/3891)\n  or 3 single cables (stranded)\n- **Enclosure**:\n  [3D printed case](https://learn.adafruit.com/usb-rotary-media-dial/cad-files)\n  for the\n  [USB Rotary Media Dial](https://learn.adafruit.com/usb-rotary-media-dial)\n- **Enclosure Screws**:\n  [4 M2.5 x 6mm steel machine screws](https://www.amazon.de/-/en/dp/B01D4R5A1E?ref=ppx_yo2ov_dt_b_fed_asin_title)\n\n### Cabling\n\n\u003cdetails\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg width=\"450\" alt=\"Aspide Logo\" src=\"./assets/fritzting/aspide-cabling.png\"/\u003e\n\u003c/p\u003e\n\n\u003c/details\u003e\n\n## Configuration\n\nThe device is configured via a `settings.toml` file located in the root of the\n`CIRCUITPY` drive.\n\n### WiFi Settings\n\n```toml\nCIRCUITPY_WIFI_SSID = \"Your_SSID\"\nCIRCUITPY_WIFI_PASSWORD = \"Your_Password\"\n```\n\n### Home Assistant Settings\n\nTo connect to Home Assistant, you need your server URL and a **Long-Lived Access\nToken** (generated from your HA user profile).\n\n```toml\nHA_URL = \"http://192.168.1.78:8123\"\nHA_TOKEN = \"your_long_lived_access_token_here\"\n\n# List of HA scenes to iterate through in 'home_assistant' mode\nHA_SCENES = \"scene.nightlights,scene.lightsoff,scene.atdesk_soft_lights,scene.softlights1\"\n\n# Light entity for ha_light and ha_brightness modes\nHA_LIGHT_ENTITY_ID = \"light.wiz_01\"\n\n# Effects to browse in ha_light mode (comma-separated, must match HA effect_list)\n# Leave empty to use built-in defaults: Warm White, Daylight, Sunset, Focus\nHA_LIGHT_EFFECTS = \"Warm White,Daylight,Sunset,Focus\"\n\n# NeoPixel preview colors for effects (1:1 with HA_LIGHT_EFFECTS; optional)\nHA_LIGHT_EFFECT_COLORS = \"bright_yellow,bright_white,dim_orange,dim_green\"\n\n# Brightness presets for ha_brightness mode (off=0, low=64, mid=128, high=191, max=255)\nHA_LIGHT_BRIGHTNESS = \"off,low,mid,high,max\"\n\n# Optional NeoPixel preview override (1:1 with HA_LIGHT_BRIGHTNESS)\n# If omitted, preview scales white to match each preset's HA brightness\n# HA_LIGHT_BRIGHTNESS_COLORS = \"\"\n```\n\n### NeoPixel Customization\n\nCustomize the behavior and appearance of the LED ring.\n\n```toml\n# Seconds of inactivity before NeoPixels turn off\nNEOPIXEL_TIMEOUT = 30\n\n# Colors for HA scenes (maps 1-to-1 with HA_SCENES above)\n# Available intensities: bright_, soft_, dim_\n# Available colors: white, green, red, blue, purple, cyan, yellow, orange, pink, gold, black\nHA_SCENE_COLORS = \"dim_blue,black,soft_white,dim_white\"\n```\n\n## Operation\n\n### Controls\n\n- **Rotate**: Browse through the available scenes, effects, or brightness\n  presets. The NeoPixel ring will change color to provide a preview.\n- **Single Push**: Activate the currently selected scene, effect, or brightness\n  preset.\n- **Double Push**: Perform a hard reset of the device (reboots and reconnects to\n  WiFi).\n- **Long Push**: Cycle through **Home Assistant Mode** (Blue), **Light Effects\n  Mode** (Amber), and **Brightness Mode** (White).\n\n### Modes\n\n1. **Home Assistant Mode**: Cycles through the scenes defined in `HA_SCENES`.\n   The NeoPixels will match the colors defined in `HA_SCENE_COLORS`.\n2. **Light Effects Mode** (`ha_light`): Cycles through effects defined in\n   `HA_LIGHT_EFFECTS`, or uses built-in defaults (Warm White, Daylight, Sunset,\n   Focus) when empty. Effect names must match what your light integration\n   exposes. NeoPixel preview colors come from `HA_LIGHT_EFFECT_COLORS`.\n3. **Brightness Mode** (`ha_brightness`): Cycles through five presets in\n   `HA_LIGHT_BRIGHTNESS` (default: off, low, mid, high, max — 0% to 100% in 25%\n   steps). Single push sends `light.turn_on` with the corresponding brightness\n   level. NeoPixel preview scales white to match each preset unless overridden\n   via `HA_LIGHT_BRIGHTNESS_COLORS`.\n\n### HA connectivity\n\nEvery 5 minutes (configurable via optional `HA_PHONE_HOME_INTERVAL`), the device\npings Home Assistant. If the API is unreachable, it retries twice at 5-second\nintervals (reconnecting WiFi if needed), then reboots to recover device-side\nnetwork state. If Home Assistant remains down, this cycle repeats each interval\nuntil HA responds.\n\n## Installation\n\n1. [Install CircuitPython on your QT Py ESP32-S2](https://learn.adafruit.com/adafruit-qt-py-esp32-s2/circuitpython)\n2. Copy the contents of the `src/` directory to the root of your `CIRCUITPY`\n   drive\n3. Make sure all the required libraries have been copied into the `lib/` folder\n4. Use `settings.sample.toml` as template to configure your `settings.toml`\n5. Enjoy!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxenos76%2Faspide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxenos76%2Faspide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxenos76%2Faspide/lists"}