# LED Driver System - Specification Document

**Version:** 1.0  
**Date:** December 2025  
**Status:** Draft

## Table of Contents

1. [Overview](#overview)
2. [System Architecture](#system-architecture)
3. [User Interface Specifications](#user-interface-specifications)
4. [Feature Specifications](#feature-specifications)
5. [Preset System](#preset-system)
6. [Profile and Scene System](#profile-and-scene-system)
7. [Data Format Specifications](#data-format-specifications)
8. [API Specifications](#api-specifications)
9. [User Flows](#user-flows)
10. [Design Guidelines](#design-guidelines)
11. [Technical Requirements](#technical-requirements)
12. [Testing Requirements](#testing-requirements)

---

## Overview

### Purpose

The LED Driver system is a MicroPython-based application for controlling LED strips via ESP32-C3 microcontrollers. The system uses a custom firmware image with usqlite and microdot built-in as frozen modules. The system provides:

- Real-time LED pattern control
- Multi-device management via peer-to-peer communication (ESPNow)
- Group-based device control
- Web-based configuration interface
- Binary message protocol for efficient communication

### Target Users

- **Primary:** Hobbyists and makers controlling LED installations
- **Secondary:** Developers building LED-based projects
- **Tertiary:** Commercial installations requiring remote LED control

### Key Features

- Pattern configuration and control (patterns run on remote devices)
- Real-time brightness and speed control
- Global brightness setting (system-wide brightness multiplier)
- Multi-colour support with customizable colour palettes
- Device grouping for synchronized control
- Preset system for saving and loading pattern configurations
- Profile and Scene system for complex lighting setups
- Preset sequencing within groups for time-based transitions
- Peer-to-peer communication via ESPNow
- Binary message protocol for bandwidth efficiency
- Persistent settings storage (usqlite database)
- Web-based configuration interface (Microdot web server)
- SQLite database for presets and event logging

---

## System Architecture

### Technology Stack

**Core Framework:**
- **MicroPython:** Python runtime for ESP32-C3
- **Microdot:** Lightweight web framework for HTTP/WebSocket server (**built into ESP32-C3 firmware**)
- **usqlite:** [μSQLite library](https://github.com/spatialdude/usqlite) for MicroPython - SQLite database implementation (**built into ESP32-C3 firmware**)
- **ESPNow:** Peer-to-peer WiFi communication protocol

**Note:** The ESP32-C3 firmware image includes usqlite and microdot as frozen modules, meaning they are part of the firmware and available immediately without installation. usqlite is integrated via CMake during firmware build.

**Key Libraries:**
- `neopixel`: WS2812 LED control
- `machine`: GPIO and hardware control
- `network`: WiFi and ESPNow
- `json`: Settings serialization
- `struct`: Binary message encoding

### Components

```
┌─────────────────────────────────────────────────────────┐
│                    Web Browser                          │
│  (Dashboard, Pattern Selector, Device Management)      │
└────────────────────┬────────────────────────────────────┘
                     │ HTTP/WebSocket
                     ▼
┌─────────────────────────────────────────────────────────┐
│         Master ESP32 Device (MicroPython)                │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐ │
│  │   Microdot   │  │   Settings   │  │   HTTP/WS    │ │
│  │  Web Server  │  │  Management  │  │  Communication│ │
│  └──────────────┘  └──────────────┘  └──────────────┘ │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐ │
│  │   usqlite    │  │   Settings   │  │  Access      │ │
│  │  Database    │  │  Management  │  │  Point (AP)  │ │
│  └──────────────┘  └──────────────┘  └──────────────┘ │
│  ┌──────────────┐                                     │
│  │  WebSocket   │  Receives BPM from beat detector     │
│  │  BPM Handler │                                     │
│  └──────────────┘                                     │
│  ┌──────────────┐                                     │
│  │  Beat Counter│  Tracks beats, phases, scene queue │
│  │  & Phases    │                                     │
│  └──────────────┘                                     │
└────────────────────┬────────────────────────────────────┘
                     │ ESPNow / Binary Messages
                     │ (Commands to slave devices)
                     │ (BPM sync data)
                     ▼
┌─────────────────────────────────────────────────────────┐
│         Remote LED Devices                              │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐ │
│  │   HTTP/WS    │  │   Settings   │  │   Pattern    │ │
│  │   Client     │  │  Receiver    │  │  Execution   │ │
│  └──────────────┘  └──────────────┘  └──────────────┘ │
│  ┌──────────────┐                                     │
│  │  BPM Sync    │  Receives BPM via ESPNow            │
│  └──────────────┘                                     │
│  Note: AP disabled, receives commands from master      │
└────────────────────┬────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────┐
│                  LED Strip (WS2812)                      │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│         Beat Detection Device (Separate Device)         │
│  ┌──────────────┐  ┌──────────────┐                      │
│  │   Audio      │  │  BPM         │                      │
│  │   Input      │  │  Calculator │                      │
│  └──────────────┘  └──────────────┘                      │
│  ┌──────────────┐                                     │
│  │  WebSocket   │  Sends BPM to master device          │
│  │  Client      │                                     │
│  └──────────────┘                                     │
└────────────────────┬────────────────────────────────────┘
                     │ WebSocket Connection
                     │ (BPM data: beats per minute)
                     ▼
              Master Device WebSocket Server
```

### Master/Slave Architecture

The LED Driver system uses a master/slave architecture where one device acts as the central controller and web interface host, while other devices act as pattern executors that receive commands.

**Master Device:**
- **Primary Role:** Central controller and web interface host
- **Access Point:** Enabled (creates WiFi network, typically 192.168.4.1)
- **Device Name / SSID / Hostname:** All the same value (e.g., "led-device1")
  - Single value used for: device name, WiFi SSID, and network hostname
  - Changing device name updates SSID and hostname simultaneously
- **Web Server:** Microdot web server running on port 80
- **Database:** usqlite database for presets, settings, and device registry
- **ESPNow:** Sends commands to slave devices
- **Groups:** Master device can be assigned to groups (same as slaves)
- **Light Control:** Master behaves the same as slaves regarding pattern/light control
  - Master can receive group-based commands
  - Master applies commands to itself when sending to groups it belongs to
  - Master checks its own group membership before sending to slaves
- **Control:** Can control itself and all slave devices
- **Configuration:** Full access to all settings and device management
- **IP Address:** Typically 192.168.4.1 (AP mode) or configured IP (STA mode)

**Slave Devices:**
- **Primary Role:** LED pattern executors
- **Access Point:** Disabled (connects to master's AP or existing WiFi)
- **Web Server:** Optional (can be enabled for direct access, but not required)
- **Database:** Optional (can use for local settings, but master is authoritative)
- **ESPNow:** Receives commands from master device
- **Control:** Only controls itself (receives commands from master)
- **Configuration:** Receives settings via ESPNow messages from master
- **IP Address:** Assigned by master's DHCP (192.168.4.x) or existing network

**Communication Flow:**
1. User accesses web interface on master device (via browser at master's IP)
2. User configures patterns/settings in web UI
3. User selects target device(s) or group(s)
4. Master device checks if it belongs to the selected group(s)
5. If master is in the group, master applies the preset/pattern to itself
6. Master device sends ESPNow messages to target slave device(s) in the group
7. Slave devices receive and execute commands
8. All devices (master + slaves) in the group display synchronized patterns

**Group-Based Command Flow:**
1. User selects a group (e.g., "group1") and applies a preset
2. Master device checks its own group membership
3. If master belongs to "group1", master applies the preset to itself
4. Master sends ESPNow messages to all slave devices in "group1"
5. All devices in the group (including master) update simultaneously

**Network Topology:**
- Master device creates WiFi Access Point (AP mode)
- **Master SSID = Master Hostname** (same value, e.g., "led-device1")
- Slave devices connect to master's AP (STA mode) using master's SSID
- All devices must be on same WiFi channel for ESPNow communication
- Master device IP: Typically 192.168.4.1 (AP mode)
- Master device hostname: Same as SSID (accessible via mDNS if supported)
- Slave device IPs: Assigned by master's DHCP (192.168.4.x)
- Alternative: All devices can connect to existing WiFi network (STA mode)

### Communication Protocols

**ESPNow (Master-to-Slave):**
- **Direction:** Master device sends commands to slave devices
- **Message Format:** Binary (preferred) or JSON (fallback)
- **Targeting:** Device names or groups
- **Persistence:** Settings saved to `/settings.json` or usqlite database (on master)
- **Network:** Master and slaves must be on same WiFi channel

**HTTP/WebSocket (Web Interface - Master Only):**
- **Framework:** Microdot web server (master device only)
- **Protocol:** HTTP/1.1 with WebSocket support
- **Port:** 80 (default, configurable)
- **Access:** Direct browser connection to master device IP (typically 192.168.4.1 in AP mode)
- **Real-time Updates:** WebSocket for live status updates
- **Control:** Web interface controls master device and sends commands to slaves via ESPNow
- **BPM Input:** WebSocket receives BPM (beats per minute) from external beat detection device
  - Beat detection device connects to master's WebSocket server
  - Sends BPM updates in real-time
  - Master device uses BPM to sync pattern delays/transitions to music
  - Master forwards BPM data to slave devices via ESPNow for synchronized patterns

---

## User Interface Specifications

### 1. Dashboard (Main Control Panel)

**File:** `dashboard.html`

#### Purpose
Primary interface for real-time LED control and monitoring.

#### Layout
- **Header:** System title and description
- **Grid Layout:** 4-column responsive grid
  - Pattern Selection Card
  - Brightness & Speed Card
  - Colour Selection Card
  - Device Status Card
- **Action Bar:** Apply and Save buttons

#### Components

**Pattern Selection**
- **Type:** Button grid or dropdown
- **Patterns:** Configurable pattern types (sent to remote devices)
- **Behavior:** Single selection, visual feedback on selected pattern
- **Visual:** Card-based buttons with hover effects

**Pattern Mode Selection**
- **Type:** Toggle switch or radio buttons
- **Options:** Auto / Single Shot
- **Default:** Auto
- **Auto Mode:** Pattern configuration is sent continuously (default behavior)
- **Single Shot Mode:** Receiving a beat triggers the preset/pattern once (requires beat detection)
- **Visual Indicator:** Shows current mode, disabled state if beat detection unavailable
- **Tooltip:** "Auto: Continuous pattern. Single Shot: Receiving a beat triggers preset/pattern once (requires beat detection)."

**Global Brightness Control**
- **Type:** Range slider (0-100%)
- **Display:** Real-time value display next to label
- **Default:** 100%
- **Update:** Live preview (if supported)
- **Description:** System-wide brightness that applies to all patterns uniformly

**Delay/Speed Control**
- **Type:** Range slider (10-1000ms)
- **Display:** Real-time value display in milliseconds
- **Default:** 100ms
- **Step:** 10ms increments

**Colour Selection**
- **Type:** Colour picker inputs (HTML5 colour input)
- **Quantity:** Multiple colours (minimum 2, expandable)
- **Format:** Hex colour codes (e.g., #FF0000)
- **Display:** Large colour swatches (60x60px)
- **Action:** "Add Colour" button for additional colours

**Device Status List**
- **Type:** List of connected devices
- **Information Displayed:**
  - Device name
  - Group assignment
  - Online/Offline status (visual indicator)
- **Visual Indicators:**
  - Green dot: Online
  - Red dot: Offline

**Action Buttons**
- **Apply Settings:** Apply changes without saving
- **Save to Device:** Persist settings to device storage

#### Design Specifications
- **Colour Scheme:** Purple gradient background (#667eea to #764ba2)
- **Cards:** White background, rounded corners (12px), shadow
- **Hover Effects:** Card lift (translateY -2px), increased shadow
- **Typography:** System font stack, 1.25rem headings

---

### 2. Pattern Selector

**File:** `pattern-selector.html`

#### Purpose
Dedicated interface for visual pattern selection with descriptions.

#### Layout
- **Header:** Title and description
- **Pattern Grid:** Responsive grid (minimum 280px per card)
- **Action Bar:** Cancel and Apply buttons

#### Pattern Cards

Each pattern card displays:
- **Icon/Visual:** Pattern-specific visual representation
- **Name:** Pattern name (e.g., "Rainbow")
- **Description:** Brief explanation of pattern behavior
- **Preview:** Visual preview dots showing pattern concept

**Pattern Types:**
Patterns are configured and sent to remote devices. The specific pattern types supported depend on the remote device implementation. Common pattern types include:
- Static patterns (On, Off)
- Animated patterns (Blink, Chase, Pulse, Rainbow, etc.)
- Custom patterns defined by device capabilities

#### Selection Behavior
- **Single Selection:** Only one pattern can be selected at a time
- **Visual Feedback:** Selected card has purple gradient background, white text
- **Hover Effect:** Border highlight, slight lift

#### Design Specifications
- **Background:** Light gradient (#f5f7fa to #c3cfe2)
- **Card Size:** Minimum 280px width, auto height
- **Spacing:** 24px gap between cards
- **Selected State:** Purple gradient (#667eea to #764ba2), white text

---

### 3. Device Management

**File:** `device-management.html`

#### Purpose
Manage connected devices and create/manage device groups.

#### Layout
- **Header:** Title with "Add Device" button
- **Zones:** Devices and Groups zones (zone buttons / zone strip)
- **Content Area:** Zone-specific content

#### Devices Zone

**Device List**
- **Display:** List of all known devices
- **Device Item Information:**
  - Device name (bold, 1.125rem)
  - Status badge (Online/Offline)
  - MAC address
  - Group assignment
  - Current pattern configuration
- **Status Indicator:** Colored dot (green=online, red=offline)
- **Actions:** Edit, Settings, Remove buttons (icon buttons)

**Add Device Modal**
- **Fields:**
  - Device Name (text input)
  - MAC Address (text input, format: AA:BB:CC:DD:EE:FF)
  - Device Role (dropdown: Master/Slave, default: Slave)
  - Group (dropdown, includes "No group" option)
- **Actions:** Cancel, Save
- **Note:** Only one master device per system. Adding a new master will demote existing master to slave.

#### Groups Zone

**Group List**
- **Display:** List of all device groups
- **Group Item Information:**
  - Group name (bold)
  - Pattern settings (pattern, delay)
  - Assigned devices (tags showing master and/or slaves)
  - Master device indicator if master is in the group
- **Actions:** Edit, Apply, Delete buttons
- **Note:** Master device can be assigned to groups and will apply commands to itself when sending to groups it belongs to

**Create Group Modal**
- **Fields:**
  - Group name (text input)
  - Pattern selection
  - Brightness (slider)
  - Delay (slider)
  - Device selection (multi-select)
- **Actions:** Cancel, Create

#### Design Specifications
- **Zone Style:** Active zone has purple background, white text
- **List Items:** Bordered cards with hover effects
- **Modal:** Centered overlay with white card, shadow
- **Status Badges:** Colored pills (green for online, red for offline)

---

### 4. Profile and Scene Management

**File:** `profiles.html` (to be created)

#### Purpose
Create and manage profiles containing scenes, where each scene assigns presets to groups with optional sequencing.

#### Layout
- **Header:** Title with "Create Profile" button
- **Profile List:** List of all profiles with expandable scenes
- **Scene Editor:** Modal for creating/editing scenes
- **Group Assignment Panel:** Assign groups to presets with sequencing options

#### Profile Card

Each profile card displays:
- **Profile Name:** Bold, large font
- **Description:** Optional description text
- **Scene Count:** Number of scenes in profile
- **Actions:** Edit, Delete, Activate buttons
- **Scenes List:** Expandable list of scenes within profile

#### Scene Card

Each scene card displays:
- **Scene Name:** Bold font
- **Group Assignments:** List showing group → preset mappings
- **Sequencing Indicator:** Badge if scene has sequenced groups
- **Actions:** Edit, Activate, Delete buttons

#### Create/Edit Profile Modal

**Fields:**
- Profile Name (text input, required)
- Description (textarea, optional)
- Scenes List:
  - Add Scene button
  - List of scenes with edit/delete buttons

#### Create/Edit Scene Modal

**Fields:**
- Scene Name (text input, required)
- Description (textarea, optional)
- Default Transition Time (slider, 0-5000ms)
- Group Assignments:
  - Group selector (dropdown)
  - Preset selector (single or multiple)
  - Sequencing toggle
  - If sequencing enabled:
    - Duration per preset (slider, 100-60000ms)
    - Transition time (slider, 0-5000ms)
    - Loop checkbox
    - Repeat count (number input, 0 = infinite)

#### Activate Scene

**Immediate Activation:**
- User selects profile
- User selects scene
- User clicks "Activate Scene"
- Master device processes scene configuration
- All groups in scene receive their assigned presets
- Sequencing begins automatically if configured
- UI shows active scene indicator and sequence progress

**Queue Scene (Phase-Based Activation):**
- User selects profile
- User selects scene
- User clicks "Queue Scene" (instead of "Activate Scene")
- Scene is queued to activate at the end of the current phase
- UI shows queued scene indicator with phase countdown
- When phase ends (phase_beat reaches phase_length - 1):
  - Queued scene activates automatically
  - All groups in scene receive their assigned presets
  - Sequencing begins automatically if configured
  - Queue is cleared
- User can clear queue before phase ends

#### Design Specifications
- **Profile Cards:** White background, rounded corners, shadow
- **Scene Cards:** Nested within profile cards, slightly indented
- **Sequence Indicator:** Animated badge showing sequence is active
- **Group Assignment:** Visual mapping showing group → preset(s) relationships

---

### 5. Settings

**File:** `settings.html`

#### Purpose
Comprehensive device configuration interface.

#### Layout
- **Header:** Title and description
- **Sections:** Multiple collapsible/expandable sections
- **Action Bar:** Reset and Save buttons

#### Sections

**1. Basic Settings**
- Device Name (text input)
- LED Pin (number input, 0-40)
- Number of LEDs (number input, 1-1000)
- Colour Order (visual selector with 6 options: RGB, RBG, GRB, GBR, BRG, BGR)

**2. Pattern Settings**
- Pattern (dropdown selection)
- Pattern Mode (radio buttons or toggle: Auto / Single Shot)
  - Auto: Pattern configuration is sent continuously
  - Single Shot: Receiving a beat triggers the preset once (requires beat detection)
  - Tooltip: "Single Shot mode: Receiving a beat triggers preset once"
- Delay (slider, 10-1000ms, with value display)
  - Note: Delay is ignored in Single Shot mode (beats trigger preset)

**3. Global Brightness**
- Global Brightness (slider, 0-100%, with value display)
- Tooltip: "System-wide brightness that applies to all patterns uniformly."
- Default: 100% (full brightness)

**3a. Beat Detection (BPM)**
- Enable BPM Sync (checkbox)
- Current BPM Display (read-only, shows current BPM from beat detector)
- BPM Multiplier (slider, 0.1x to 10.0x, default: 1.0x)
- Manual BPM Override (number input, 0-300, optional)
- BPM Source Status (indicator showing beat detector connection status)
- Tooltip: "Sync pattern delays and transitions to music beats. BPM is received from external beat detection device via WebSocket."

**3b. Beat Counter and Phases**
- Beat Counter Display (read-only, shows current beat number)
- Phase Length (number input, 1-64 beats, default: 4)
- Current Phase Display (read-only, shows current phase number)
- Phase Beat Position (read-only, shows beat position within phase, 0 to phase_length-1)
- Sync Beat Counter (button, resets beat counter to 0)
- Queued Scene Display (shows scene queued to activate at end of phase)
- Clear Queue (button, clears queued scene)
- Tooltip: "Beat counter tracks beats for phase-based scene changes. Scenes can be queued to activate at phase boundaries."

**4. Advanced Settings**
- Pattern Parameters:
  - N1-N8 (number inputs, 0-255)
  - Tooltip: "Pattern-specific parameters (varies by pattern). N7 and N8 reserved for future enhancements."
- Device ID (number input)
- Debug Mode (checkbox)

**5. Network Settings**

**Master Device:**
- Device Name / SSID (text input, required, single field)
  - Note: Device name and SSID are the same value
  - Changing device name updates both hostname and SSID
- Access Point Password (password input, optional)
- Enable Access Point (checkbox, checked and locked for master)
- Device Role Indicator: "Master Device" badge
- Tooltip: "Master device creates WiFi network. Device name is used as both hostname and SSID."

**Slave Device:**
- Device Name (text input, separate from SSID)
- Access Point Name (text input, disabled - not applicable for slaves)
- Access Point Password (text input, disabled)
- Enable Access Point (checkbox, unchecked and disabled for slaves)
- Device Role Indicator: "Slave Device" badge
- Tooltip: "Slave devices connect to master's network. Device name is separate from SSID."

#### Form Controls

**Input Types:**
- Text: Standard text input
- Number: Number input with min/max validation
- Range: Slider with real-time value display
- Select: Dropdown menu
- Checkbox: Toggle switch
- Colour: HTML5 colour picker

**Colour Order Selector**
- **Type:** Visual button grid
- **Options:** RGB, RBG, GRB, GBR, BRG, BGR
- **Display:** Colour boxes showing order (R=red, G=green, B=blue)
- **Selection:** Single selection with visual feedback

#### Design Specifications
- **Section Headers:** Purple colour (#667eea), 1.5rem font, bottom border
- **Form Groups:** 24px spacing between fields
- **Labels:** Bold, 500 weight, dark gray (#333)
- **Help Text:** Small gray text below inputs
- **Action Buttons:** Full-width, Reset (secondary), Save (primary)

---

### 5. Preset Management

**File:** `presets.html` (to be created)

#### Purpose
Save, load, and manage preset configurations for quick pattern switching.

#### Layout
- **Header:** Title with "Create Preset" button and "Sync Presets to All Devices" button
- **Preset Grid:** Responsive grid of preset cards
- **Action Bar:** Quick apply buttons

#### Preset Card

Each preset card displays:
- **Name:** Preset name (bold, 1.25rem)
- **Pattern Badge:** Current pattern type
- **Colour Preview:** Swatches showing preset colours
- **Quick Info:** Delay and brightness values
- **Actions:** Apply, Edit, Delete buttons

#### Create/Edit Preset Modal

**Fields:**
- Preset Name (text input, required)
- Pattern (dropdown selection)
- Colours (multiple colour pickers, minimum 2)
- Delay (slider, 10-1000ms)
- Step Offset (number input, optional, default: 0)
  - Tooltip: "Step offset for group synchronization. Applied per device when preset is used in a group."
- Step Increment (number input, optional, default: 1, minimum: 1)
  - Tooltip: "Amount step counter increments per cycle. Controls pattern advancement speed."
- Pattern Parameters:
  - N1 (number input, 0-255)
  - N2 (number input, 0-255)
  - N3 (number input, 0-255)
  - N4 (number input, 0-255)
  - N5 (number input, 0-255)
  - N6 (number input, 0-255)
  - N7 (number input, 0-255)
  - N8 (number input, 0-255)

**Actions:**
- Cancel
- Save Preset

#### Preset List View

**Display Options:**
- Grid view (default): Visual cards with previews
- List view: Compact list with details

**Sorting:**
- Alphabetical (A-Z)
- Recently used
- Recently created

**Filtering:**
- By pattern type
- By name (search)

#### Preset Synchronization
- **Sync Button:** "Sync Presets to All Devices" button in header
- **Behavior:** 
  - Master sends all presets to all devices via ESPNow
  - Each device stores presets in local database
  - Ensures all devices have same preset definitions
  - Shows sync progress and status for each device
- **Use Case:** After creating/editing presets on master, sync to ensure all devices have updated preset definitions

#### Design Specifications
- **Card Style:** White background, rounded corners, shadow
- **Pattern Badge:** Colored pill with pattern name
- **Colour Swatches:** 40x40px squares in card header
- **Hover Effect:** Card lift, border highlight
- **Selected State:** Purple border, subtle background tint

---

## Feature Specifications

### Pattern Configuration

Patterns are configured on the controller and sent to remote devices for execution. The controller manages pattern settings including:

- **Pattern Type:** Identifier for the pattern (e.g., "on", "off", "blink", "chase", "pulse", "rainbow", etc.)
- **Pattern Parameters:** Numeric parameters (N1-N8) that configure pattern-specific behavior
- **Colours:** Colour palette for the pattern
- **Timing:** Delay and speed settings

**Note:** Pattern execution happens on the remote devices. The controller sends configuration commands to devices.

#### Pattern Parameters (N1-N8)

Pattern-specific numeric parameters:
- **N1-N8:** Integer values (0-255)
- **Usage:** Varies by pattern type (sent to remote devices for pattern-specific configuration)
- **Default:** 0 (pattern-specific defaults apply)
- **Note:** N7 and N8 are reserved for future pattern enhancements and preset system

### Preset System

#### Overview

Presets allow users to save complete pattern configurations for quick recall and application. A preset encapsulates all pattern settings including pattern type, colours, timing, and all pattern parameters.

**Note:** Presets are optional. Devices can be controlled directly without presets.

#### Preset Structure

A preset contains the following fields:

- **name** (string, required): Unique identifier for the preset
- **pattern** (string, required): Pattern type identifier (sent to remote devices)
- **colours** (array of strings, required): Array of hex colour codes (minimum 2 colours)
- **delay** (integer, required): Delay in milliseconds (10-1000)
- **n1** (integer, optional): Pattern parameter 1 (0-255, default: 0)
- **n2** (integer, optional): Pattern parameter 2 (0-255, default: 0)
- **n3** (integer, optional): Pattern parameter 3 (0-255, default: 0)
- **n4** (integer, optional): Pattern parameter 4 (0-255, default: 0)
- **n5** (integer, optional): Pattern parameter 5 (0-255, default: 0)
- **n6** (integer, optional): Pattern parameter 6 (0-255, default: 0)
- **n7** (integer, optional): Pattern parameter 7 (0-255, default: 0)
- **n8** (integer, optional): Pattern parameter 8 (0-255, default: 0)

#### Preset Operations

- **Create:** User configures settings, clicks "Save as Preset", enters name → saved on master device
- **Load:** User selects preset → settings loaded and applied to device/group
- **Apply:** User selects preset, clicks "Apply" → configuration sent to device(s), updates immediately
- **Edit:** User selects preset, clicks "Edit", modifies settings, saves → updated on master device
- **Delete:** User selects preset, clicks "Delete", confirms → removed from master device
- **Sync:** User clicks "Sync Presets to All Devices" → master sends all presets to all devices via ESPNow
  - Each device stores presets in local database
  - Ensures all devices have same preset definitions
  - Useful after creating/editing presets to keep devices in sync

#### Preset Storage

**Primary Storage:** usqlite database on device (`/presets.db` or integrated in main database)  
**Backup/Export:** JSON file format for portability (`/presets.json`)

**Preset Synchronization:**
- Presets are created/edited on master device
- Master can sync all presets to all devices via ESPNow
- Each device stores presets in local database
- Ensures all devices have same preset definitions available
- Sync operation sends all presets to target devices

**Preset Synchronization:**
- Presets are created/edited on master device
- Master can sync all presets to all devices via ESPNow
- Each device stores presets in local database
- Ensures all devices have same preset definitions available
- Sync operation sends all presets to target devices

**Format:**
```json
{
  "presets": [
    {
      "name": "Fast Rainbow",
      "pattern": "rainbow",
      "colors": ["FF0000", "00FF00", "0000FF"],
      "delay": 50,
      "n1": 5,
      "n2": 0,
      "n3": 0,
      "n4": 0,
      "n5": 0,
      "n6": 0,
      "n7": 0,
      "n8": 0
    },
    {
      "name": "Slow Pulse",
      "pattern": "pulse",
      "colors": ["FF0000", "0000FF"],
      "delay": 200,
      "n1": 500,
      "n2": 300,
      "n3": 500,
      "n4": 0,
      "n5": 0,
      "n6": 0,
      "n7": 0,
      "n8": 0
    }
  ]
}
```

#### Preset Examples

**Example 1: Fast Rainbow**
```json
{
  "name": "Fast Rainbow",
  "pattern": "rainbow",
  "colors": ["FF0000", "00FF00", "0000FF"],
  "delay": 30,
  "n1": 10,
  "n2": 0,
  "n3": 0,
  "n4": 0,
  "n5": 0,
  "n6": 0,
  "n7": 0,
  "n8": 0
}
```

**Example 2: Chase Pattern**
```json
{
  "name": "Red Blue Chase",
  "pattern": "chase",
  "colors": ["FF0000", "0000FF"],
  "delay": 100,
  "n1": 5,
  "n2": 5,
  "n3": 2,
  "n4": -1,
  "n5": 0,
  "n6": 0,
  "n7": 0,
  "n8": 0
}
```

**Example 3: Circle Loading**
```json
{
  "name": "Loading Circle",
  "pattern": "circle",
  "colors": ["00FF00"],
  "delay": 50,
  "n1": 50,
  "n2": 100,
  "n3": 200,
  "n4": 0,
  "n5": 0,
  "n6": 0,
  "n7": 0,
  "n8": 0
}
```

**Example 4: Pulse with Custom Timing**
```json
{
  "name": "Smooth Pulse",
  "pattern": "pulse",
  "colors": ["FF00FF"],
  "delay": 100,
  "n1": 500,
  "n2": 200,
  "n3": 500,
  "n4": 0,
  "n5": 0,
  "n6": 0,
  "n7": 0,
  "n8": 0
}
```

#### Preset Integration

**Dashboard Integration:**
- Quick preset selector dropdown
- "Save Current as Preset" button
- Preset preview on hover

**Pattern Selector Integration:**
- "Load Preset" option
- Preset suggestions based on selected pattern

**Device Management Integration:**
- Apply preset to group
- Preset templates for new groups

### Device Management

#### Device Properties
- **Name:** Unique identifier (string)
- **MAC Address:** Hardware identifier (format: AA:BB:CC:DD:EE:FF)
- **Group:** Optional group assignment
- **Status:** Online/Offline (real-time)
- **Current Pattern:** Active pattern configuration
- **Step Counter:** Device-side counter tracking pattern step/position (integer, 0+, managed by remote device)
- **Settings:** Full settings object

#### Group Properties
- **Name:** Unique group identifier
- **Devices:** List of device names (can include master and/or slaves)
- **Settings:** Pattern, delay, colours
- **Step Offset:** Per-device step offset sent to devices for synchronized patterns (integer, can be negative)
  - Each device in group can receive different step offset
  - Creates wave/chase effect across multiple LED strips
  - Offset is sent as part of configuration to remote devices
- **Step Increment:** Amount step counter increments per cycle (integer, default: 1, can be > 1)
  - Sent to devices to control pattern speed/advancement rate
  - Remote devices manage their own step counters
- **Apply Behavior:** Send configuration to all group members
  - Controller sends configuration to all devices in the group via HTTP/WebSocket
  - All devices in the group receive configuration simultaneously
  - Step offsets are sent per device when preset is applied to group
- **Note:** Global brightness is device-specific, not group-specific

### Communication

#### Message Format

**Binary Message Structure:**
```
Byte 0: Version (currently 0)
Byte 1: Flags (bit 0: names, bit 1: groups, bit 2: settings, bit 3: save)
[Variable]: Names list (if flag set)
[Variable]: Groups list (if flag set)
[Variable]: Settings dict (if flag set)
```

**JSON Message Structure (Fallback):**
```json
{
  "names": ["led-device1"],
  "groups": ["group1"],
  "settings": {
    "pt": "on",
    "pm": "auto",
    "cl": ["000000", "FF0000"],
    "br": 100,
    "dl": 100,
    "n1": 0,
    "n2": 0,
    "n3": 0,
    "n4": 0,
    "n5": 0,
    "n6": 0,
    "n7": 0,
    "n8": 0
  },
  "save": false
}
```

#### Message Targeting
- **By Name:** Target specific device(s) by device ID
- **By Group:** Target all devices in group(s)
- **Broadcast:** Send to all devices (empty names/groups)
- **Controller Role:** Controller sends configuration messages to remote devices via HTTP/WebSocket
- **Device Role:** Remote devices receive and process configuration messages from controller

#### Settings Keys

| Key | Type | Description | Range/Values |
|-----|------|-------------|--------------|
| `pt` | string | Pattern type | on, off, blink, chase, circle, pulse, rainbow, transition |
| `pm` | string | Pattern mode | auto, single_shot |
| `cl` | array | Colours (hex strings) | Array of hex colour codes |
| `br` | int | Global brightness | 0-100 |
| `dl` | int | Delay (ms) | 10-1000 |
| `n1` | int | Parameter 1 | 0-255 |
| `n2` | int | Parameter 2 | 0-255 |
| `n3` | int | Parameter 3 | 0-255 |
| `n4` | int | Parameter 4 | 0-255 |
| `n5` | int | Parameter 5 | 0-255 |
| `n6` | int | Parameter 6 | 0-255 |
| `n7` | int | Parameter 7 | 0-255 |
| `n8` | int | Parameter 8 | 0-255 |
| `led_pin` | int | GPIO pin | 0-40 |
| `num_leds` | int | LED count | 1-1000 |
| `color_order` | string | Colour order | rgb, rbg, grb, gbr, brg, bgr |
| `name` | string | Device name | Any string |
| `brightness` | int | Global brightness | 0-100 |
| `delay` | int | Delay | 10-1000 |
| `step_counter` | int | Current step counter value | 0+ |
| `step_offset` | int | Step offset for group synchronization | Any integer |
| `step_increment` | int | Step counter increment per cycle | 1+ (default: 1) |
| `sequence_active` | boolean | Sequence is currently running | true/false |
| `sequence_index` | int | Current preset index in sequence | 0-N |
| `sequence_start_time` | int | Timestamp when sequence started | milliseconds |
| `bpm` | int | Current BPM from beat detector | 0-300 |
| `bpm_synced` | boolean | Pattern delays synced to BPM | true/false |
| `bpm_multiplier` | float | BPM multiplier for delay calculation | 0.1-10.0 |

---

## Data Format Specifications

### Settings File Format

**Location:** `/settings.json` on device

**Master Device Structure:**
```json
{
  "led_pin": 10,
  "num_leds": 50,
  "pattern": "on",
  "delay": 100,
  "brightness": 100,
  "color_order": "rgb",
  "name": "led-device1",
  "ap_name": "led-device1",  // Must match name (SSID = hostname for master)
  "ap_password": "",
  "ap_enabled": true,
  "groups": ["group1"],  // Master can be in groups (same as slaves)
  "debug": false,
  "n1": 0,
  "n2": 0,
  "n3": 0,
  "n4": 0,
  "n5": 0,
  "n6": 0,
  "n7": 0,
  "n8": 0,
  "step_counter": 0,
  "step_increment": 1
}
```

**Note:** For master devices, `name` and `ap_name` must always be the same value. The device name serves as both the WiFi SSID (Access Point name) and the network hostname. Changing the device name automatically updates both SSID and hostname.

**Step Counter Fields:**
- `step_counter`: Current step position in pattern (integer, 0+, managed by remote device)
- `step_increment`: Amount to increment step counter per cycle (integer, 1+, default: 1, sent to device)
- `step_offset`: Sent to device when preset is used in a group (integer, can be negative, default: 0)

**Slave Device Structure:**
```json
{
  "led_pin": 10,
  "num_leds": 50,
  "pattern": "on",
  "delay": 100,
  "brightness": 100,
  "color_order": "rgb",
  "name": "led-device2",
  "ap_name": "",  // Not used (AP disabled for slaves)
  "ap_password": "",
  "ap_enabled": false,
  "groups": [],
  "debug": false,
  "n1": 0,
  "n2": 0,
  "n3": 0,
  "n4": 0,
  "n5": 0,
  "n6": 0,
  "n7": 0,
  "n8": 0,
  "step_counter": 0,
  "step_increment": 1
}
```

### Group File Format

**Location:** `/groups.json` (if implemented)

**Structure:**
```json
{
  "grps": [
    {
      "n": "group1",
      "pt": "on",
      "cl": ["000000", "FF0000"],
      "br": 100,
      "dl": 100,
      "n1": 0,
      "n2": 0,
      "n3": 0,
      "n4": 0,
      "n5": 0,
      "n6": 0,
      "n7": 0,
      "n8": 0
    }
  ]
}
```

### Profile and Scene Storage Format

**Database Storage (usqlite):**
Profiles and scenes are stored in SQLite database with the following schemas:

**Profiles Table:**
```sql
CREATE TABLE IF NOT EXISTS profiles (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT UNIQUE NOT NULL,
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

**Scenes Table:**
```sql
CREATE TABLE IF NOT EXISTS scenes (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    profile_id INTEGER NOT NULL,
    name TEXT NOT NULL,
    description TEXT,
    transition_time INTEGER DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE,
    UNIQUE(profile_id, name)
);
```

**Scene Group Assignments Table:**
```sql
CREATE TABLE IF NOT EXISTS scene_groups (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    scene_id INTEGER NOT NULL,
    group_name TEXT NOT NULL,
    presets TEXT NOT NULL,  -- JSON array of preset names
    sequence_duration INTEGER DEFAULT 0,  -- Duration per preset in ms
    sequence_transition INTEGER DEFAULT 0,  -- Transition time in ms
    sequence_loop BOOLEAN DEFAULT 0,
    sequence_repeat_count INTEGER DEFAULT 0,  -- 0 = infinite
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (scene_id) REFERENCES scenes(id) ON DELETE CASCADE
);
```

**JSON Export Format (for backup/portability):**
```json
{
  "profiles": [
    {
      "name": "Party Mode",
      "description": "Party lighting profiles",
      "scenes": [
        {
          "name": "Warm Welcome",
          "transition_time": 0,
          "groups": [
            {
              "group_name": "entrance",
              "presets": ["Warm White"],
              "sequence_timing": null
            },
            {
              "group_name": "main",
              "presets": ["Soft Rainbow"],
              "sequence_timing": null
            }
          ]
        },
        {
          "name": "Dance Floor",
          "transition_time": 500,
          "groups": [
            {
              "group_name": "entrance",
              "presets": ["Fast Rainbow"],
              "sequence_timing": null
            },
            {
              "group_name": "accent",
              "presets": ["Pulse Purple", "Pulse Blue"],
              "sequence_timing": {
                "duration": 3000,
                "transition": 500,
                "loop": true,
                "repeat_count": 0
              }
            }
          ]
        }
      ]
    }
  ]
}
```

### Preset Storage Format

**Database Storage (usqlite):**
Presets are stored in SQLite database with the following schema:

```sql
CREATE TABLE IF NOT EXISTS presets (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT UNIQUE NOT NULL,
    pattern TEXT NOT NULL,
    pattern_mode TEXT DEFAULT 'auto',  -- 'auto' or 'single_shot'
    colors TEXT NOT NULL,  -- JSON array of hex color strings
    delay INTEGER NOT NULL,
    step_offset INTEGER DEFAULT 0,  -- Step offset for group synchronization
    step_increment INTEGER DEFAULT 1,  -- Step counter increment per cycle
    n1 INTEGER DEFAULT 0,
    n2 INTEGER DEFAULT 0,
    n3 INTEGER DEFAULT 0,
    n4 INTEGER DEFAULT 0,
    n5 INTEGER DEFAULT 0,
    n6 INTEGER DEFAULT 0,
    n7 INTEGER DEFAULT 0,
    n8 INTEGER DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    usage_count INTEGER DEFAULT 0
);
```

**JSON Export Format (for backup/portability):**
**Location:** `/presets.json` (optional export file)

**Structure:**
```json
{
  "presets": [
    {
      "name": "Fast Rainbow",
      "pattern": "rainbow",
      "colors": ["FF0000", "00FF00", "0000FF"],
      "delay": 50,
      "n1": 5,
      "n2": 0,
      "n3": 0,
      "n4": 0,
      "n5": 0,
      "n6": 0,
      "n7": 0,
      "n8": 0
    },
    {
      "name": "Slow Pulse",
      "pattern": "pulse",
      "colors": ["FF0000", "0000FF"],
      "delay": 200,
      "n1": 500,
      "n2": 300,
      "n3": 500,
      "n4": 0,
      "n5": 0,
      "n6": 0,
      "n7": 0,
      "n8": 0
    }
  ]
}
```

**Preset Fields:**
- `name` (string, required): Unique preset identifier
- `pattern` (string, required): Pattern type
- `colors` (array of strings, required): Hex colour codes (minimum 2)
- `delay` (integer, required): Delay in milliseconds (10-1000)
- `n1` through `n8` (integer, optional): Pattern parameters (0-255, default: 0)

---

## API Specifications

### Web Interface API (Microdot-based)

**Framework:** Microdot (lightweight web framework for MicroPython)  
**Base URL:** `http://device-ip/` or `http://192.168.4.1/` (when in AP mode)  
**Protocol:** HTTP/1.1 with optional WebSocket support for real-time updates

**Note:** The web interface will be implemented using Microdot, providing a lightweight HTTP server directly on the ESP32 device. This enables direct browser access without requiring a separate host computer.

#### Endpoints

**GET /api/status**
- Returns device status and current settings
- Response: JSON object with device info

**POST /api/settings**
- Update device settings
- Body: JSON settings object
- Response: Success/error message

**GET /api/devices**
- List all known devices
- Response: Array of device objects

**POST /api/pattern**
- Apply pattern immediately
- Body: Pattern name and parameters
- Response: Success confirmation

**GET /api/presets**
- List all saved presets
- Response: Array of preset objects

**POST /api/presets**
- Create a new preset
- Body: Preset object (name, pattern, colours, delay, n1-n8)
- Response: Created preset object

**GET /api/presets/{name}**
- Get specific preset by name
- Response: Preset object

**PUT /api/presets/{name}**
- Update existing preset
- Body: Updated preset object
- Response: Updated preset object

**DELETE /api/presets/{name}**
- Delete preset
- Response: Success confirmation

**POST /api/presets/{name}/apply**
- Apply preset to device(s)
- Body: Target device names or groups, optional step_offset overrides per device
- Response: Success confirmation
- Behavior: Applies preset with step offsets when used in groups (each device gets different offset)

**POST /api/presets/sync**
- Sync all presets from master to all devices
- Body: Optional device names array (if empty, syncs to all devices)
- Response: Success confirmation with sync status for each device
- Behavior: Master sends all presets via ESPNow to target devices, devices store presets in their local database
- Use case: Ensure all devices have same preset definitions available

**GET /api/profiles**
- List all profiles
- Response: Array of profile objects with scenes

**POST /api/profiles**
- Create a new profile
- Body: Profile object (name, description, scenes)
- Response: Created profile object

**GET /api/profiles/{name}**
- Get specific profile by name
- Response: Profile object with all scenes

**PUT /api/profiles/{name}**
- Update existing profile
- Body: Updated profile object
- Response: Updated profile object

**DELETE /api/profiles/{name}**
- Delete profile
- Response: Success confirmation

**POST /api/profiles/{name}/scenes/{scene_name}/activate**
- Activate a scene within a profile (immediate)
- Body: Optional override parameters
- Response: Success confirmation
- Behavior: Applies presets to all groups in scene, starts sequences if configured

**POST /api/profiles/{name}/scenes/{scene_name}/queue**
- Queue a scene to activate at end of current phase
- Body: Optional override parameters
- Response: Success confirmation with phase information
- Behavior: Scene queued, will activate when phase_beat reaches phase_length - 1

**GET /api/beat-counter**
- Get current beat counter and phase information
- Response: JSON object with beat_counter, phase_length, current_phase, phase_beat, queued_scene

**POST /api/beat-counter/sync**
- Sync/reset beat counter
- Body: JSON object with beat_number (optional, default: 0) and phase_length (optional)
- Response: Success confirmation
- Behavior: Resets beat counter and/or updates phase_length on all devices

**POST /api/beat-counter/clear-queue**
- Clear queued scene
- Response: Success confirmation
- Behavior: Removes queued scene, prevents activation at phase end

**GET /api/device/{name}/step-counter**
- Get current step counter value for device
- Response: JSON object with `step_counter` (integer)

**POST /api/device/{name}/step-counter/sync**
- Sync/reset step counter for device
- Body: JSON object with `step_counter` (optional, default: 0)
- Response: Success confirmation

**POST /api/group/{name}/step-offsets**
- Set step offsets for devices in group
- Body: JSON object mapping device names to step offsets: `{"device1": 0, "device2": 10, "device3": 20}`
- Response: Success confirmation
- Behavior: Sets step offsets for each device in group, creating synchronized wave effect

**Direct Device Control:**
All device control operations support direct value setting without presets or scenes:
- Individual device values can be set independently
- Multiple devices can be controlled with different values simultaneously
- Direct control bypasses preset and scene systems
- Presets and scenes are optional organizational features

**GET /api/brightness**
- Get current global brightness setting
- Response: JSON object with `global_brightness` (0-100)

**POST /api/brightness**
- Set global brightness
- Body: JSON object with `global_brightness` (0-100)
- Response: Success confirmation

**WebSocket /ws**
- Real-time status updates
- Pattern change notifications
- Device status changes
- Message format: JSON

**GET /**
- Web UI root (serves HTML interface)
- Returns: HTML dashboard interface

**GET /static/{file}**
- Static assets (CSS, JS, images)
- Returns: Static file content

#### Microdot Implementation Notes

- **Built-in Module:** Microdot is frozen into the ESP32-C3 firmware image
- **Server Startup:** Microdot server runs on port 80 (default) or configurable port
- **Concurrent Requests:** Microdot handles requests asynchronously
- **WebSocket Support:** Microdot includes WebSocket support for real-time updates
- **Template Rendering:** Can use utemplate (included with Microdot) for server-side rendering
- **Static Files:** Static assets can be served from `/static` directory or frozen into firmware
- **No Installation Required:** Microdot is available immediately after firmware flash

#### Database Integration (usqlite)

**Database Library:** [usqlite](https://github.com/spatialdude/usqlite) - μSQLite library module for MicroPython (**built into ESP32-C3 firmware**)

**Repository:** https://github.com/spatialdude/usqlite

**Database Usage:**
- Preset storage in SQLite database
- Event logging and history
- Settings persistence (optional, can use JSON file as fallback)
- Pattern usage statistics

**Database Schema:**
- `presets` table: Stores preset configurations
- `events` table: Logs device events and actions
- `pattern_history` table: Tracks pattern usage
- `settings` table: Optional persistent settings storage

**usqlite Features:**
- **API Compatibility:** Highly compatible with standard Python `sqlite3` library
- **Memory Management:** Uses MicroPython's GC heap by default, optimized for constrained environments
- **Memory Monitoring:** Built-in functions for tracking memory usage (`mem_current()`, `mem_peak()`, `mem_status()`)
- **Row Types:** Supports tuple (default), dict, or custom row objects
- **Parameter Substitution:** Supports `?`, `?NNN`, `:name`, `@name`, and `$name` parameter styles
- **Built into ESP32-C3 firmware image** (frozen module via CMake integration)
- **No installation required** - available immediately after firmware flash
- **ESP32 Support:** Officially supported port (along with Raspberry Pi Pico, Unix, Windows, Pybricks)

**usqlite API Usage:**
```python
import usqlite

# Connect to database
conn = usqlite.connect('/led_driver.db')

# Set row type to dict for easier access
conn.row_type = 'dict'

# Execute queries
cursor = conn.execute("SELECT * FROM presets WHERE name = ?", ("Fast Rainbow",))
preset = cursor.fetchone()

# Memory monitoring
current_mem = usqlite.mem_current()
peak_mem = usqlite.mem_peak()
```

---

## User Flows

### Flow 1: Change Pattern (Master Controls Slaves)

1. User opens Dashboard on master device (via web browser)
2. User clicks pattern button (e.g., "Rainbow")
3. Pattern button highlights (active state)
4. User selects target device(s) or group
5. User adjusts global brightness or speed if needed
6. User clicks "Apply Settings"
7. Master device sends ESPNow message to selected slave device(s)
8. Master device also updates its own pattern
9. Slave device(s) receive message and update pattern immediately
10. UI shows confirmation for each device

### Flow 1a: Adjust Global Brightness

1. User adjusts Global Brightness slider on Dashboard
2. User clicks "Apply Settings" or "Save to Device"
3. System sends brightness to device(s), all patterns adjust uniformly
4. UI shows confirmation

### Flow 2: Create Device Group

1. User navigates to Device Management → Groups zone
2. User clicks "Create Group", enters name, selects pattern/settings
3. User selects devices to add (can include master), clicks "Create"
4. Group appears in list
5. User clicks "Apply" → master applies to itself (if in group), sends ESPNow to slaves
6. All devices in group update simultaneously

### Flow 3: Configure Device Settings

1. User navigates to Settings page
2. User modifies settings in sections:
   - Basic Settings (pin, LED count, colour order)
   - Pattern Settings (pattern, delay)
   - Global Brightness
   - Advanced Settings (N1-N8 parameters)
   - Network Settings (AP configuration)
3. User clicks "Save Settings"
4. System sends settings with `save: true` flag
5. Device persists settings to `/settings.json`
6. UI shows success message

### Flow 4: Multi-Device Control

1. User selects multiple devices or a group
2. User changes pattern/colours/global brightness
3. User clicks "Apply Settings"
4. System sends message targeting selected devices/groups
5. All targeted devices update simultaneously
6. UI shows status for each device

### Flow 5: Create and Use Preset

1. User configures pattern settings, clicks "Save as Preset"
2. User enters unique name, clicks "Save" → preset saved on master
3. User optionally clicks "Sync Presets to All Devices" → master sends all presets to all devices
4. User selects preset from list, clicks "Apply Preset"
5. Preset values applied to device(s), UI updates


### Flow 6: Apply Preset to Group

1. User navigates to Device Management or Presets page
2. User selects a group (e.g., "group1")
3. User opens preset selector
4. User selects preset from list
5. User clicks "Apply to Group"
6. Master device checks if it belongs to the selected group
7. If master is in the group, master applies preset configuration to itself
8. Master device sends preset configuration via ESPNow to all slave devices in the group
9. All devices in group (including master) update simultaneously
10. UI shows confirmation for each device (master + slaves)

### Flow 7: Create and Activate Profile Scene

1. User navigates to Profiles page
2. User clicks "Create Profile"
3. User enters profile name and description
4. User clicks "Add Scene"
5. User enters scene name
6. User assigns groups to presets:
   - Selects group "entrance" → assigns Preset "Warm White"
   - Selects group "main" → assigns Preset "Soft Rainbow"
   - Selects group "accent" → assigns multiple presets with sequencing
7. User configures sequencing for groups that need it:
   - Sets duration: 3000ms per preset
   - Sets transition: 500ms between presets
   - Enables loop: true
8. User saves scene
9. User saves profile
10. User clicks "Activate Scene"
11. Master device processes scene:
    - Checks which groups master belongs to
    - Applies presets to itself for groups it's in
    - Sends ESPNow messages to slave devices in each group
12. All devices update to scene configuration
13. Sequencing begins automatically for groups with multiple presets
14. UI shows active scene and sequence progress

### Flow 8: Sequence Between Presets

1. Scene activated with group having multiple presets
2. Master applies first preset to itself (if in group), sends to slaves
3. After duration expires, master transitions to next preset with fade effect
4. Process repeats for all presets, loops if enabled
5. Continues until scene changes or manual stop

---

## Design Guidelines

### Colour Palette

- **Primary:** Purple gradient `#667eea` to `#764ba2`, Light gradient `#f5f7fa` to `#c3cfe2`
- **UI:** Primary `#667eea`, Hover `#5568d3`, Secondary `#e0e0e0`
- **Text:** Primary `#333333`, Secondary `#666666`
- **Status:** Success `#4caf50`, Error `#f44336`
- **Background:** White `#ffffff`

### Typography

- **Font:** System stack (-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif)
- **Sizes:** H1 2.5rem, H2 1.5rem, H3 1.25rem, Body 1rem, Small 0.875rem, Tiny 0.75rem

### Spacing

- Card padding: 24px, Section gap: 24px, Form field gap: 20px
- Button padding: 12px vertical, 24px horizontal
- Border radius: 8px (buttons), 12px (cards)

### Interactive Elements

**Buttons:**
- Hover: Slight lift (translateY -2px), increased shadow
- Active: Slight press (translateY 0px)
- Disabled: 50% opacity, no pointer events

**Inputs:**
- Focus: Border colour changes to primary purple
- Hover: Slight border colour change
- Error: Red border

**Cards:**
- Hover: Lift effect, increased shadow
- Selected: Border highlight, background change

### Responsive Design

**Breakpoints:**
- Mobile: < 768px (single column)
- Tablet: 768px - 1024px (2 columns)
- Desktop: > 1024px (3-4 columns)

**Grid Behavior:**
- Auto-fit columns with minimum width
- Cards stack vertically on mobile
- Maintains readability at all sizes

---

## Technical Requirements

### Hardware Requirements

**ESP32 Device:**
- **ESP32-C3 microcontroller** (recommended)
- Custom MicroPython firmware with usqlite and microdot built-in
- GPIO pin for LED data line
- WiFi capability (for ESPNow and web server)

**LED Strip:**
- WS2812/NeoPixel compatible
- Any length (1-1000 LEDs supported)
- 5V power supply (external)

**Host Computer:**
- Python 3.x
- pipenv for dependency management
- Network connection (for web interface, if implemented)

### Software Requirements

**MicroPython Modules:**
- `machine` (GPIO, WDT)
- `network` (WiFi, ESPNow)
- `json` (settings storage)
- `struct` (binary encoding)
- `espnow` (peer-to-peer communication)
- `usqlite` (SQLite database support - **built into ESP32-C3 firmware**)
- `microdot` (web framework for HTTP/WebSocket server - **built into ESP32-C3 firmware**)

**Python Libraries:**
- `mpremote` (device communication)
- `pyserial` (serial communication)
- `esptool` (firmware flashing)
- `playwright` (for image generation, optional)

**MicroPython Firmware Requirements:**
- **ESP32-C3 MicroPython firmware** with usqlite and microdot built-in (frozen modules)
- ESPNow support enabled
- Network stack configured for AP/STA modes
- **Note:** usqlite and microdot are included in the firmware image, no separate installation required

### Performance Requirements

**Message Processing:**
- Binary message decode: < 10ms
- Pattern update: < 50ms
- Settings save: < 100ms

**Pattern Configuration:**
- Configuration sent to remote devices via HTTP/WebSocket
- Remote devices handle pattern execution and LED updates

**Communication:**
- ESPNow message size: < 250 bytes (ESP32 limit)
- Binary format: ~70% smaller than JSON
- Message delivery: < 100ms latency

### Storage Requirements

**Device Storage:**
- Settings file: ~500 bytes (JSON) or SQLite database
- Firmware: ~1-2MB (usqlite and microdot are frozen into firmware)
- Available space: ESP32-C3 typically has 1-4MB free flash
- SQLite database: ~10-100KB (depends on usage)
- **Note:** usqlite and microdot are part of the firmware image, not stored separately

**Database Storage (usqlite):**
- Presets table: ~200-300 bytes per preset
- Events table: ~100 bytes per event
- Pattern history: ~150 bytes per entry
- Recommended limits:
  - 50 presets maximum
  - 1000 events (with automatic cleanup)
  - 500 pattern history entries

**Host Storage (Presets - Optional):**
- Preset file: ~1-10KB (depends on number of presets)
- Each preset: ~200-300 bytes
- Can sync with device database via API

---

## Testing Requirements

### Unit Tests

**Pattern Configuration Tests:**
- Pattern configuration is correctly formatted
- Parameters are properly sent to remote devices
- Edge cases (invalid patterns, missing parameters, etc.)

**Message Encoding/Decoding:**
- Binary encoding matches JSON structure
- Decoding handles all data types
- Error handling for malformed messages

**Settings Management:**
- Load/save operations
- Default values
- Validation

**Preset Management:**
- Preset creation with all fields (name, pattern, colours, delay, n1-n8)
- Preset loading and application
- Preset editing and deletion
- Name uniqueness validation
- Preset file format validation

### Integration Tests

**Device Communication:**
- ESPNow message delivery
- Binary vs JSON fallback
- Group targeting
- Multi-device synchronization

**Pattern Configuration Application:**
- Pattern configuration is sent to devices correctly
- Settings persist after reboot
- Configuration parameters are properly formatted

**Preset Application:**
- Preset loads all parameters correctly (pattern, colours, delay, n1-n8)
- Preset applies to single device
- Preset applies to device group
- Preset values match saved configuration

### UI Tests

**Responsiveness:**
- All breakpoints render correctly
- Touch targets adequate (44x44px minimum)
- Forms validate input

**Interactivity:**
- Buttons respond to clicks
- Sliders update values
- Modals open/close
- Zone buttons switch correctly
- Preset selector works
- Preset creation form validates input
- Preset cards display correctly

---

## Future Enhancements

### Planned Features

1. **Web Interface Implementation**
   - Microdot-based web server on device
   - Real-time status updates via WebSocket
   - RESTful API endpoints for device control
   - OTA (Over-The-Air) updates

2. **Pattern Editor**
   - Custom pattern creation
   - Pattern library sharing
   - Visual pattern preview

3. **Advanced Grouping**
   - Group hierarchies
   - Conditional group actions
   - Scheduled group changes

4. **Analytics**
   - Usage statistics
   - Pattern popularity
   - Device health monitoring

5. **Mobile App**
   - Native iOS/Android app
   - Push notifications
   - Offline mode

---

## Appendix

### Abbreviations

- **ESPNow:** ESP32 peer-to-peer communication protocol
- **GPIO:** General Purpose Input/Output
- **LED:** Light Emitting Diode
- **WS2812:** Addressable RGB LED chip
- **WDT:** Watchdog Timer
- **AP:** Access Point
- **OTA:** Over-The-Air

### References

**Core Technologies:**
- [usqlite - μSQLite library for MicroPython](https://github.com/spatialdude/usqlite) - SQLite database implementation
- Microdot - Lightweight web framework for MicroPython
- ESP32 MicroPython Documentation
- WS2812 LED Datasheet
- ESPNow Protocol Specification

**Project Files:**
- Mockup files: `docs/mockups/*.html`
- Generated images: `docs/mockups/images/*.png`

---

**Document Status:** This specification is a living document and will be updated as the project evolves.

**Last Updated:** December 2024

