diff --git a/docs/API.md b/docs/API.md new file mode 100644 index 0000000..2914ca6 --- /dev/null +++ b/docs/API.md @@ -0,0 +1,263 @@ +# LED Driver ESPNow API Documentation + +This document describes the ESPNow message format for controlling LED driver devices. + +## Message Format + +All messages are JSON objects sent via ESPNow with the following structure: + +```json +{ + "v": "1", + "presets": { ... }, + "select": { ... } +} +``` + +### Version Field + +- **`v`** (required): Message version, must be `"1"`. Messages with other versions are ignored. + +## Presets + +Presets define LED patterns with their configuration. Each preset has a name and contains pattern-specific settings. + +### Preset Structure + +```json +{ + "presets": { + "preset_name": { + "pattern": "pattern_type", + "colors": ["#RRGGBB", ...], + "delay": 100, + "brightness": 127, + "auto": true, + "n1": 0, + "n2": 0, + "n3": 0, + "n4": 0, + "n5": 0, + "n6": 0 + } + } +} +``` + +### Preset Fields + +- **`pattern`** (required): Pattern type. Options: + - `"off"` - Turn off all LEDs + - `"on"` - Solid color + - `"blink"` - Blinking pattern + - `"rainbow"` - Rainbow color cycle + - `"pulse"` - Pulse/fade pattern + - `"transition"` - Color transition + - `"chase"` - Chasing pattern + - `"circle"` - Circle loading pattern + +- **`colors`** (optional): Array of hex color strings (e.g., `"#FF0000"` for red). Default: `["#FFFFFF"]` + - Colors are automatically converted from hex to RGB and reordered based on device color order setting + - Supports multiple colors for patterns that use them + +- **`delay`** (optional): Delay in milliseconds between pattern updates. Default: `100` + +- **`brightness`** (optional): Brightness level (0-255). Default: `127` + +- **`auto`** (optional): Auto mode flag. Default: `true` + - `true`: Pattern runs continuously + - `false`: Pattern advances one step per beat (manual mode) + +- **`n1` through `n6`** (optional): Pattern-specific numeric parameters. Default: `0` + - See pattern-specific documentation below + +### Pattern-Specific Parameters + +#### Rainbow +- **`n1`**: Step increment (how many color wheel positions to advance per update). Default: `1` + +#### Pulse +- **`n1`**: Attack time in milliseconds (fade in) +- **`n2`**: Hold time in milliseconds (full brightness) +- **`n3`**: Decay time in milliseconds (fade out) +- **`delay`**: Delay time in milliseconds (off between pulses) + +#### Transition +- **`delay`**: Transition duration in milliseconds + +#### Chase +- **`n1`**: Number of LEDs with first color +- **`n2`**: Number of LEDs with second color +- **`n3`**: Movement amount on even steps (can be negative) +- **`n4`**: Movement amount on odd steps (can be negative) + +#### Circle +- **`n1`**: Head movement rate (LEDs per second) +- **`n2`**: Maximum length +- **`n3`**: Tail movement rate (LEDs per second) +- **`n4`**: Minimum length + +## Select Messages + +Select messages control which preset is active on which device. The format uses a list to support step synchronization. + +### Select Format + +```json +{ + "select": { + "device_name": ["preset_name"], + "device_name2": ["preset_name2", step_value] + } +} +``` + +### Select Fields + +- **`select`**: Object mapping device names to selection lists + - **Key**: Device name (as configured in device settings) + - **Value**: List with one or two elements: + - `["preset_name"]` - Select preset (uses default step behavior) + - `["preset_name", step]` - Select preset with explicit step value (for synchronization) + +### Step Synchronization + +The step value allows precise synchronization across multiple devices: + +- **Without step**: `["preset_name"]` + - If switching to different preset: step resets to 0 + - If selecting "off" pattern: step resets to 0 + - If selecting same preset (beat): step is preserved, pattern restarts + +- **With step**: `["preset_name", 10]` + - Explicitly sets step to the specified value + - Useful for synchronizing multiple devices to the same step + +### Beat Functionality + +Calling `select()` again with the same preset name acts as a "beat" - it restarts the pattern generator: + +- **Single-tick patterns** (rainbow, chase in manual mode): Advance one step per beat +- **Multi-tick patterns** (pulse in manual mode): Run through full cycle per beat + +Example beat sequence: +```json +// Beat 1 +{"select": {"device1": ["rainbow_preset"]}} + +// Beat 2 (same preset = beat) +{"select": {"device1": ["rainbow_preset"]}} + +// Beat 3 +{"select": {"device1": ["rainbow_preset"]}} +``` + +## Synchronization + +### Using "off" Pattern + +Selecting the "off" pattern resets the step counter to 0, providing a synchronization point: + +```json +{ + "select": { + "device1": ["off"], + "device2": ["off"] + } +} +``` + +After all devices are "off", switching to a pattern ensures they all start from step 0: + +```json +{ + "select": { + "device1": ["rainbow_preset"], + "device2": ["rainbow_preset"] + } +} +``` + +### Using Step Parameter + +For precise synchronization, use the step parameter: + +```json +{ + "select": { + "device1": ["rainbow_preset", 10], + "device2": ["rainbow_preset", 10], + "device3": ["rainbow_preset", 10] + } +} +``` + +All devices will start at step 10 and advance together on subsequent beats. + +## Complete Example + +```json +{ + "v": "1", + "presets": { + "red_blink": { + "pattern": "blink", + "colors": ["#FF0000"], + "delay": 200, + "brightness": 255, + "auto": true + }, + "rainbow_manual": { + "pattern": "rainbow", + "delay": 100, + "n1": 2, + "auto": false + }, + "pulse_slow": { + "pattern": "pulse", + "colors": ["#00FF00"], + "delay": 500, + "n1": 1000, + "n2": 500, + "n3": 1000, + "auto": false + } + }, + "select": { + "device1": ["red_blink"], + "device2": ["rainbow_manual", 0], + "device3": ["pulse_slow"] + } +} +``` + +## Message Processing + +1. **Version Check**: Messages with `v != "1"` are rejected +2. **Preset Processing**: Presets are created or updated (upsert behavior) +3. **Color Conversion**: Hex colors are converted to RGB tuples and reordered based on device color order +4. **Selection**: Devices select their assigned preset, optionally with step value + +## Best Practices + +1. **Always include version**: Set `"v": "1"` in all messages +2. **Use "off" for sync**: Select "off" pattern to synchronize devices before starting patterns +3. **Beats for manual mode**: Send select messages repeatedly with same preset name to advance manual patterns +4. **Step for precision**: Use step parameter when exact synchronization is required +5. **Color format**: Always use hex strings (`"#RRGGBB"`), conversion is automatic + +## Error Handling + +- Invalid version: Message is ignored +- Missing preset: Selection fails, device keeps current preset +- Invalid pattern: Selection fails, device keeps current preset +- Missing colors: Pattern uses default white color +- Invalid step: Step value is used as-is (may cause unexpected behavior) + +## Notes + +- Colors are automatically converted from hex strings to RGB tuples +- Color order reordering happens automatically based on device settings +- Step counter wraps around (0-255 for rainbow, unbounded for others) +- Manual mode patterns stop after one step/cycle, waiting for next beat +- Auto mode patterns run continuously until changed