# Lighting Controller REST API - Frontend Documentation ## Overview Complete REST API for controlling the LED lighting system. **No WebSocket required** - all operations use simple HTTP requests. **Base URL:** `http://10.42.0.1:8765` **Local Testing:** `http://localhost:8765` --- ## Table of Contents 1. [Quick Start](#quick-start) 2. [Pattern Control](#pattern-control) 3. [Color Palette](#color-palette) 4. [Parameters](#parameters) 5. [System State](#system-state) 6. [Tempo Control](#tempo-control) 7. [Complete Examples](#complete-examples) --- ## Quick Start ### Load Initial State ```javascript // Get everything in one call const response = await fetch('http://10.42.0.1:8765/api/state'); const state = await response.json(); console.log(state.pattern); // Current pattern console.log(state.parameters); // All parameters console.log(state.color_palette); // 8 colors + 2 selected console.log(state.beat_index); // Current beat number ``` ### Change Pattern ```javascript await fetch('http://10.42.0.1:8765/api/pattern', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({pattern: 'alternating'}) }); ``` ### Change Color ```javascript await fetch('http://10.42.0.1:8765/api/color-palette', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({selected_indices: [2, 5]}) // Blue and Cyan }); ``` --- ## Pattern Control ### GET /api/pattern Get the currently active pattern. **Request:** ```http GET /api/pattern HTTP/1.1 ``` **Response:** ```json { "pattern": "alternating" } ``` --- ### POST /api/pattern Change the active pattern. **Request:** ```http POST /api/pattern HTTP/1.1 Content-Type: application/json { "pattern": "alternating" } ``` **Available Patterns:** - `"on"` / `"o"` - Solid color - `"off"` / `"f"` - All LEDs off - `"flicker"` / `"f"` - Flickering effect - `"fill_range"` / `"fr"` - Fill effect - `"n_chase"` / `"nc"` - Chase pattern - `"alternating"` / `"a"` - Alternating on/off - `"pulse"` / `"p"` - Pulsing effect - `"rainbow"` / `"r"` - Rainbow cycle - `"specto"` / `"s"` - Spectograph effect - `"radiate"` / `"rd"` - Radiate from center - `"segmented_movement"` / `"sm"` - Moving segments **Response:** ```json { "status": "ok", "pattern": "alternating" } ``` **JavaScript Example:** ```javascript async function setPattern(patternName) { const response = await fetch('http://10.42.0.1:8765/api/pattern', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({pattern: patternName}) }); return await response.json(); } // Usage await setPattern('alternating'); await setPattern('rainbow'); ``` --- ## Color Palette ### GET /api/color-palette Get the 8-color palette and selected colors. **Response:** ```json { "palette": [ {"r": 255, "g": 0, "b": 0}, // Slot 0: Red {"r": 0, "g": 255, "b": 0}, // Slot 1: Green {"r": 0, "g": 0, "b": 255}, // Slot 2: Blue {"r": 255, "g": 255, "b": 0}, // Slot 3: Yellow {"r": 255, "g": 0, "b": 255}, // Slot 4: Magenta {"r": 0, "g": 255, "b": 255}, // Slot 5: Cyan {"r": 255, "g": 128, "b": 0}, // Slot 6: Orange {"r": 255, "g": 255, "b": 255} // Slot 7: White ], "selected_indices": [0, 1] // [0] = pattern color, [1] = reserved } ``` **Important:** The **first selected color** (index 0) is used for all patterns! --- ### POST /api/color-palette Update palette colors and/or selected colors. **Request (Change Selected Colors):** ```json { "selected_indices": [2, 5] // Use slot 2 (Blue) for patterns } ``` **Request (Update a Color):** ```json { "palette": [ {"r": 255, "g": 0, "b": 0}, {"r": 0, "g": 255, "b": 0}, {"r": 128, "g": 0, "b": 128}, // Changed to purple // ... all 8 colors (must send complete array) ] } ``` **Response:** ```json { "status": "ok", "palette": { "palette": [...], "selected_indices": [2, 5] } } ``` **JavaScript Example:** ```javascript // Change pattern color to slot 5 (Cyan) async function selectColor(slotIndex) { const response = await fetch('http://10.42.0.1:8765/api/color-palette', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({selected_indices: [slotIndex, 1]}) }); return await response.json(); } // Edit a color in the palette async function updatePaletteColor(slotIndex, r, g, b) { // First get current palette const current = await fetch('http://10.42.0.1:8765/api/color-palette') .then(res => res.json()); // Update the specific slot const newPalette = [...current.palette]; newPalette[slotIndex] = {r, g, b}; // Send updated palette await fetch('http://10.42.0.1:8765/api/color-palette', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({palette: newPalette}) }); } // Usage await selectColor(2); // Use blue for patterns await updatePaletteColor(3, 128, 0, 128); // Change slot 3 to purple ``` --- ## Parameters ### GET /api/parameters Get all current parameter values. **Response:** ```json { "brightness": 100, // 0-100 "delay": 50, // milliseconds "n1": 10, // Pattern parameter 1 "n2": 5, // Pattern parameter 2 "n3": 2, // Pattern parameter 3 (forward movement) "n4": 1 // Pattern parameter 4 (backward movement) } ``` --- ### POST /api/parameters Update one or more parameters. Only send the parameters you want to change. **Request:** ```json { "brightness": 75, "n1": 15 } ``` **Response:** ```json { "status": "ok", "parameters": { "brightness": 75, "delay": 50, "n1": 15, "n2": 5, "n3": 2, "n4": 1 } } ``` **Parameter Descriptions:** | Parameter | Range | Description | |-----------|-------|-------------| | `brightness` | 0-100 | LED brightness percentage | | `delay` | 1-1000 | Pattern speed (milliseconds) | | `n1` | 0-255 | Pattern-specific (e.g., segment length) | | `n2` | 0-255 | Pattern-specific (e.g., spacing) | | `n3` | 0-255 | Pattern-specific (e.g., forward steps) | | `n4` | 0-255 | Pattern-specific (e.g., backward steps) | **JavaScript Example:** ```javascript async function setBrightness(value) { const response = await fetch('http://10.42.0.1:8765/api/parameters', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({brightness: value}) }); return await response.json(); } async function setSpeed(delayMs) { await fetch('http://10.42.0.1:8765/api/parameters', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({delay: delayMs}) }); } // Usage await setBrightness(75); // Set to 75% await setSpeed(100); // Slow down pattern ``` --- ## System State ### GET /api/state Get complete system state in a single call. Perfect for initial UI load. **Response:** ```json { "pattern": "alternating", "parameters": { "brightness": 100, "delay": 50, "n1": 10, "n2": 5, "n3": 2, "n4": 1 }, "color_palette": { "palette": [...8 colors...], "selected_indices": [0, 1] }, "beat_index": 42 } ``` **JavaScript Example:** ```javascript // Load all state when UI starts async function loadInitialState() { const response = await fetch('http://10.42.0.1:8765/api/state'); const state = await response.json(); // Update UI with current state updatePatternButtons(state.pattern); updateColorPalette(state.color_palette); updateSliders(state.parameters); return state; } ``` --- ## Tempo Control ### POST /api/tempo/reset Reset the tempo/beat detection in the sound system. **Request:** ```http POST /api/tempo/reset HTTP/1.1 ``` **Response:** ```json { "status": "ok", "message": "Tempo reset sent" } ``` **JavaScript Example:** ```javascript async function resetTempo() { const response = await fetch('http://10.42.0.1:8765/api/tempo/reset', { method: 'POST' }); return await response.json(); } // Usage: Call this when tempo detection seems off await resetTempo(); ``` --- ## Complete Examples ### Example 1: Full UI Controller Class ```javascript class LightingController { constructor(baseUrl = 'http://10.42.0.1:8765') { this.baseUrl = baseUrl; } // Load complete state async loadState() { const response = await fetch(`${this.baseUrl}/api/state`); return await response.json(); } // Pattern control async setPattern(pattern) { const response = await fetch(`${this.baseUrl}/api/pattern`, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({pattern}) }); return await response.json(); } // Color selection async selectColor(slotIndex) { const response = await fetch(`${this.baseUrl}/api/color-palette`, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({selected_indices: [slotIndex, 1]}) }); return await response.json(); } // Brightness control async setBrightness(value) { const response = await fetch(`${this.baseUrl}/api/parameters`, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({brightness: value}) }); return await response.json(); } // Pattern parameters async setParameters(params) { const response = await fetch(`${this.baseUrl}/api/parameters`, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(params) }); return await response.json(); } } // Usage const lights = new LightingController(); // On page load const state = await lights.loadState(); // User interactions await lights.setPattern('rainbow'); await lights.selectColor(2); // Blue await lights.setBrightness(75); ``` --- ### Example 2: React Component ```jsx import { useState, useEffect } from 'react'; function LightingControl() { const [state, setState] = useState(null); const BASE_URL = 'http://10.42.0.1:8765'; // Load initial state useEffect(() => { fetch(`${BASE_URL}/api/state`) .then(res => res.json()) .then(setState); }, []); // Change pattern const handlePatternChange = async (pattern) => { await fetch(`${BASE_URL}/api/pattern`, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({pattern}) }); // Reload state const newState = await fetch(`${BASE_URL}/api/state`).then(r => r.json()); setState(newState); }; // Change color const handleColorSelect = async (slotIndex) => { await fetch(`${BASE_URL}/api/color-palette`, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({selected_indices: [slotIndex, 1]}) }); const newState = await fetch(`${BASE_URL}/api/state`).then(r => r.json()); setState(newState); }; // Change brightness const handleBrightnessChange = async (value) => { await fetch(`${BASE_URL}/api/parameters`, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({brightness: value}) }); }; if (!state) return