Add complete REST API for lighting control

- Migrated from websockets to aiohttp for unified HTTP/WebSocket server
- Added REST endpoints: /api/pattern, /api/parameters, /api/state, /api/tempo/reset
- Implemented color palette API with 8-slot system and selected colors
- First selected color (index 0) is used as primary RGB for patterns
- All operations now available via simple HTTP requests (no WebSocket needed)
- Added comprehensive documentation: FRONTEND_API.md, COLOR_PALETTE_API.md
- Added test scripts: test_rest_api.sh, test_color_patterns.py
- Updated test/test_control_server.py for new /ws WebSocket path
- Configuration persistence via lighting_config.json
- Pattern parameters (n1-n4, brightness, delay) controllable via API
- WebSocket still available at /ws for legacy support
This commit is contained in:
Pi User
2025-10-03 23:38:54 +13:00
parent aa9f892454
commit 6f9133b43e
19 changed files with 3512 additions and 44 deletions

105
test_color_patterns.py Normal file
View File

@@ -0,0 +1,105 @@
#!/usr/bin/env python3
"""
Complete test: Change palette selection and verify pattern color updates
"""
import asyncio
import aiohttp
import json
async def test_color_pattern_integration():
"""Test that changing selected color updates pattern color"""
print("=" * 60)
print("Color Palette Pattern Integration Test")
print("=" * 60)
# Step 1: Get current palette
print("\n1⃣ Getting current palette...")
session = aiohttp.ClientSession()
async with session.get('http://localhost:8765/api/color-palette') as response:
data = await response.json()
print(f" Current palette has {len(data['palette'])} colors")
print(f" Selected indices: {data['selected_indices']}")
current_index = data['selected_indices'][0]
current_color = data['palette'][current_index]
print(f" Current color (slot {current_index}): RGB({current_color['r']}, {current_color['g']}, {current_color['b']})")
# Step 2: Connect to WebSocket and send a pattern
print("\n2⃣ Connecting to WebSocket and activating pattern...")
try:
async with session.ws_connect('http://localhost:8765/ws') as ws:
print(" ✅ Connected to WebSocket")
# Send 'on' pattern
await ws.send_json({
"type": "pattern_change",
"data": {"pattern": "on"}
})
print(f" 📤 Sent pattern: 'on'")
print(f" 🎨 LED bar should show: RGB({current_color['r']}, {current_color['g']}, {current_color['b']})")
await asyncio.sleep(2)
# Step 3: Change to RED (slot 0)
print("\n3⃣ Changing selected color to RED (slot 0)...")
async with session.post(
'http://localhost:8765/api/color-palette',
json={"selected_indices": [0, 1]}
) as response:
if response.status == 200:
print(" ✅ Color changed to slot 0")
red_color = data['palette'][0]
print(f" 🎨 LED bar should now show: RGB({red_color['r']}, {red_color['g']}, {red_color['b']})")
await asyncio.sleep(2)
# Step 4: Change to BLUE (slot 2)
print("\n4⃣ Changing selected color to BLUE (slot 2)...")
async with session.post(
'http://localhost:8765/api/color-palette',
json={"selected_indices": [2, 1]}
) as response:
if response.status == 200:
print(" ✅ Color changed to slot 2")
blue_color = data['palette'][2]
print(f" 🎨 LED bar should now show: RGB({blue_color['r']}, {blue_color['g']}, {blue_color['b']})")
await asyncio.sleep(2)
# Step 5: Test alternating pattern
print("\n5⃣ Testing alternating pattern...")
await ws.send_json({
"type": "pattern_change",
"data": {"pattern": "alternating"}
})
print(" 📤 Sent pattern: 'alternating'")
print(" 🎨 Pattern should alternate with blue color")
await asyncio.sleep(3)
# Step 6: Restore original selection
print(f"\n6⃣ Restoring original selection (slot {current_index})...")
async with session.post(
'http://localhost:8765/api/color-palette',
json={"selected_indices": data['selected_indices']}
) as response:
if response.status == 200:
print(f" ✅ Restored to slot {current_index}")
except Exception as e:
print(f" ❌ Error: {e}")
finally:
await session.close()
print("\n" + "=" * 60)
print("✅ Test Complete!")
print("=" * 60)
print("\n💡 What to verify:")
print(" - LED bar changed color when palette selection changed")
print(" - Colors matched: Red → Blue → back to original")
print(" - Pattern continued running with new colors")
if __name__ == "__main__":
asyncio.run(test_color_pattern_integration())