UI: Color palette REST integration, MIDI 44–51 color slot selection, Color 1/2 previews with next indicator and click-to-select target; use REST for pattern changes and parameter updates (brightness, delay, n1–n3); send colors only on confirm; load palette on startup; fix NoneType await issue in async handlers
This commit is contained in:
751
api.md
Normal file
751
api.md
Normal file
@@ -0,0 +1,751 @@
|
||||
# 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
|
||||
|
||||
```
|
||||
|
||||
**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 <div>Loading...</div>;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Pattern: {state.pattern}</h2>
|
||||
|
||||
<div>
|
||||
<button onClick={() => handlePatternChange('alternating')}>Alternating</button>
|
||||
<button onClick={() => handlePatternChange('rainbow')}>Rainbow</button>
|
||||
<button onClick={() => handlePatternChange('pulse')}>Pulse</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>Colors</h3>
|
||||
{state.color_palette.palette.map((color, i) => (
|
||||
<div
|
||||
key={i}
|
||||
onClick={() => handleColorSelect(i)}
|
||||
style={{
|
||||
background: `rgb(${color.r}, ${color.g}, ${color.b})`,
|
||||
border: state.color_palette.selected_indices[0] === i ? '3px solid gold' : '1px solid black',
|
||||
width: 50,
|
||||
height: 50,
|
||||
display: 'inline-block',
|
||||
cursor: 'pointer'
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>Brightness: {state.parameters.brightness}</label>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value={state.parameters.brightness}
|
||||
onChange={(e) => handleBrightnessChange(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Example 3: Simple HTML + Vanilla JS
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Lighting Controller</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>LED Lighting Control</h1>
|
||||
|
||||
<div id="patterns"></div>
|
||||
<div id="colors"></div>
|
||||
|
||||
<label>Brightness: <span id="brightness-value">100</span></label>
|
||||
<input type="range" id="brightness" min="0" max="100" value="100">
|
||||
|
||||
<script>
|
||||
const BASE_URL = 'http://10.42.0.1:8765';
|
||||
|
||||
// Load initial state
|
||||
async function init() {
|
||||
const response = await fetch(`${BASE_URL}/api/state`);
|
||||
const state = await response.json();
|
||||
|
||||
// Create pattern buttons
|
||||
const patterns = ['on', 'alternating', 'rainbow', 'pulse', 'segmented_movement'];
|
||||
const patternsDiv = document.getElementById('patterns');
|
||||
patterns.forEach(pattern => {
|
||||
const btn = document.createElement('button');
|
||||
btn.textContent = pattern;
|
||||
btn.onclick = () => setPattern(pattern);
|
||||
patternsDiv.appendChild(btn);
|
||||
});
|
||||
|
||||
// Create color palette
|
||||
const colorsDiv = document.getElementById('colors');
|
||||
state.color_palette.palette.forEach((color, i) => {
|
||||
const div = document.createElement('div');
|
||||
div.style.cssText = `
|
||||
background: rgb(${color.r}, ${color.g}, ${color.b});
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
border: ${state.color_palette.selected_indices[0] === i ? '3px solid gold' : '1px solid black'};
|
||||
`;
|
||||
div.onclick = () => selectColor(i);
|
||||
colorsDiv.appendChild(div);
|
||||
});
|
||||
|
||||
// Brightness slider
|
||||
document.getElementById('brightness').oninput = (e) => {
|
||||
document.getElementById('brightness-value').textContent = e.target.value;
|
||||
setBrightness(e.target.value);
|
||||
};
|
||||
}
|
||||
|
||||
async function setPattern(pattern) {
|
||||
await fetch(`${BASE_URL}/api/pattern`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({pattern})
|
||||
});
|
||||
}
|
||||
|
||||
async function selectColor(index) {
|
||||
await fetch(`${BASE_URL}/api/color-palette`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({selected_indices: [index, 1]})
|
||||
});
|
||||
location.reload(); // Refresh to show updated selection
|
||||
}
|
||||
|
||||
async function setBrightness(value) {
|
||||
await fetch(`${BASE_URL}/api/parameters`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({brightness: parseInt(value)})
|
||||
});
|
||||
}
|
||||
|
||||
init();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Endpoint Summary
|
||||
|
||||
| Method | Endpoint | Purpose |
|
||||
|--------|----------|---------|
|
||||
| `GET` | `/api/state` | Get complete system state |
|
||||
| `GET` | `/api/pattern` | Get current pattern |
|
||||
| `POST` | `/api/pattern` | Change pattern |
|
||||
| `GET` | `/api/color-palette` | Get color palette |
|
||||
| `POST` | `/api/color-palette` | Update palette/selection |
|
||||
| `GET` | `/api/parameters` | Get all parameters |
|
||||
| `POST` | `/api/parameters` | Update parameters |
|
||||
| `POST` | `/api/tempo/reset` | Reset tempo detection |
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
All endpoints return standard HTTP status codes:
|
||||
|
||||
- `200 OK` - Success
|
||||
- `400 Bad Request` - Invalid request data
|
||||
- `500 Internal Server Error` - Server error
|
||||
|
||||
**Error Response Format:**
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"message": "Pattern name required"
|
||||
}
|
||||
```
|
||||
|
||||
**JavaScript Error Handling Example:**
|
||||
```javascript
|
||||
async function safeApiCall(url, options) {
|
||||
try {
|
||||
const response = await fetch(url, options);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status === 'error') {
|
||||
console.error('API Error:', data.message);
|
||||
return null;
|
||||
}
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('Network Error:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
const result = await safeApiCall('http://10.42.0.1:8765/api/pattern', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({pattern: 'rainbow'})
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
### Test All Endpoints
|
||||
```bash
|
||||
# Get state
|
||||
curl http://10.42.0.1:8765/api/state | jq
|
||||
|
||||
# Change pattern
|
||||
curl -X POST http://10.42.0.1:8765/api/pattern \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"pattern": "rainbow"}'
|
||||
|
||||
# Change color
|
||||
curl -X POST http://10.42.0.1:8765/api/color-palette \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"selected_indices": [2, 5]}'
|
||||
|
||||
# Update brightness
|
||||
curl -X POST http://10.42.0.1:8765/api/parameters \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"brightness": 75}'
|
||||
|
||||
# Reset tempo
|
||||
curl -X POST http://10.42.0.1:8765/api/tempo/reset
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- **No WebSocket needed** - Everything uses simple HTTP REST API
|
||||
- **CORS**: Not currently enabled. Host UI on same domain or add CORS middleware
|
||||
- **Persistence**: Color palette persists to `lighting_config.json`
|
||||
- **Real-time**: Changes take effect immediately (within one beat cycle)
|
||||
- **Pattern Color**: First selected color (index 0) is used for all patterns
|
||||
|
||||
---
|
||||
|
||||
## Support Files
|
||||
|
||||
- Full API details: `COLOR_PALETTE_API.md`
|
||||
- Migration notes: `AIOHTTP_MIGRATION.md`
|
||||
- Test results: `PATTERN_COLOR_TEST_RESULTS.md`
|
||||
|
||||
- Migration notes: `AIOHTTP_MIGRATION.md`
|
||||
- Test results: `PATTERN_COLOR_TEST_RESULTS.md`
|
||||
|
Reference in New Issue
Block a user