Add profile/preset/sequence JSON import and export; map preset mode to
wire n6 with a mode dropdown for multi-mode patterns; zone edit shows
presets or sequences only with content_kind on save; update catalogue
and tests for merged pattern names.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Optional profile_id on groups; UI and API for shared vs profile-only groups\n- Zone content_kind (presets vs sequences); edit modal shows matching sections; devices via groups only\n- Server sequence playback folds zone brightness into preset wire b (per MAC where needed)\n- Related preset/sequence/audio/beat-route and client updates
Co-authored-by: Cursor <cursoragent@cursor.com>
- asyncio.gather for group brightness and driver-config Wi-Fi pushes
- Batch identify envelope for group members
Co-authored-by: Cursor <cursoragent@cursor.com>
Route beat-triggered manual selects from the controller server, add preset background and beat-counter UI support, and bump led-driver to include the matching pattern/runtime fixes.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Serve GET /settings as JSON by removing duplicate HTML route (use /settings/page for the standalone UI).
- Save global_brightness via PUT; broadcast to connected drivers; push saved level when outbound WS connects.
- Zones UI loads brightness from GET /settings only (no localStorage).
- Bump led-driver submodule for settings.save on brightness with save flag.
- Extend API doc and endpoint tests for global_brightness.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Run app on Raspberry Pi: serial to ESP32 bridge at 912000 baud, /dev/ttyS0
- Remove ESP-NOW/MicroPython-only code from src (espnow, p2p, wifi, machine/Pin)
- Transport: always send 6-byte MAC + payload; optional to/destination_mac in API and WebSocket
- Settings and model DB use project paths (no root); fix sys.print_exception for CPython
- Preset/settings controllers use get_current_sender(); template paths for cwd=src
- Pipfile: run from src, PORT from env; scripts for port 80 (setcap) and test
- ESP32 bridge: receive 6-byte addr + payload, LRU peer management (20 max), handle ESP_ERR_ESPNOW_EXIST
- Add esp32/main.py, esp32/benchmark_peers.py, scripts/setup-port80.sh, scripts/test-port80.sh
Made-with: Cursor
- Activate STA interface before ESP-NOW to fix ESP_ERR_ESPNOW_IF
- Notify browser on send failure: WebSocket sends error JSON; preset API returns 503
- Use exceptions for failure (not return value) to avoid false errors when send succeeds
- presets.js: handle server error messages in WebSocket onmessage
Made-with: Cursor
- Drop station connect/status/credentials from wifi util and settings API
- Remove station activation from main
- Remove station UI and JS from index, settings template, and help.js
- Device settings now only configure WiFi Access Point
Co-authored-by: Cursor <cursoragent@cursor.com>
Move WiFi and device name configuration into a modal menu, reuse existing settings endpoints, and harden settings serialization and startup for MicroPython.
- Fix decorator parameter order issues with @with_session
- Return JSON responses instead of HTML fragments
- Add proper error handling with JSON error responses
- Fix route parameter conflicts in delete and update endpoints
- Add drag-and-drop to reorder presets in tabs (2D grid layout)
- Add drag-and-drop to reorder colors within presets
- Add max_colors field to pattern definitions
- Hide color section when max_colors is 0
- Validate color count against pattern max_colors limit
- Store presets in 2D grid format (3 columns)
- Remove left panel from tab content, show only presets
- Update color palette to show swatches instead of hex codes
- Improve preset editor UI with visual color swatches
- Add REST API controllers for all models
- Controllers use Microdot subroutes
- Support CRUD operations via HTTP endpoints
- Controllers: preset, profile, group, sequence, tab, palette