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

148
AIOHTTP_MIGRATION.md Normal file
View File

@@ -0,0 +1,148 @@
# Migration to aiohttp for WebSocket and HTTP
## Summary
The control server has been refactored to use **aiohttp** for both WebSocket and HTTP endpoints, replacing the previous `websockets` library for the WebSocket server.
## What Changed
### 1. Server Architecture
**Before:**
- Separate `websockets` server on port 8765
- Separate `aiohttp` HTTP API server on port 8766
**After:**
- Single `aiohttp` application serving both:
- WebSocket endpoint: `ws://host:8765/ws`
- HTTP API endpoints: `http://host:8765/api/*`
- HTTP API also available on port 8766 for backward compatibility
### 2. Code Changes
#### `/home/pi/lighting-controller/src/control_server.py`
**Removed:**
- `import websockets`
- `handle_ui_client()` method (used websockets library)
- `start_websocket_server()` method
- `_websocket_server_task()` method
**Added:**
- `handle_websocket()` method using aiohttp's WebSocket support
- Updated `start_http_server()` to include WebSocket endpoint
- Combined server startup (HTTP and WebSocket on same port)
**Key Differences:**
```python
# OLD (websockets library)
async def handle_ui_client(self, websocket):
async for message in websocket:
data = json.loads(message)
await websocket.send(json.dumps(response))
# NEW (aiohttp)
async def handle_websocket(self, request):
ws = web.WebSocketResponse()
await ws.prepare(request)
async for msg in ws:
if msg.type == web.WSMsgType.TEXT:
data = json.loads(msg.data)
await ws.send_json(response)
return ws
```
#### `/home/pi/lighting-controller/Pipfile`
Both `aiohttp` and `websockets` are now in the dependencies:
- `aiohttp` - for server WebSocket and HTTP
- `websockets` - for client connections to LED bars (in `networking.py`)
### 3. Client Changes Required
**WebSocket URL Update:**
Clients must update their connection URL to include the `/ws` path:
```javascript
// OLD
const ws = new WebSocket('ws://10.42.0.1:8765');
// NEW
const ws = new WebSocket('ws://10.42.0.1:8765/ws');
```
**Python Client:**
```python
# OLD
uri = "ws://10.42.0.1:8765"
# NEW
uri = "ws://10.42.0.1:8765/ws"
```
### 4. HTTP API
The HTTP API endpoints remain the same, but are now available on both ports:
- **Primary:** `http://10.42.0.1:8765/api/color-palette`
- **Backward Compatibility:** `http://10.42.0.1:8766/api/color-palette`
### 5. Configuration
Environment variables remain the same:
```bash
CONTROL_SERVER_HOST=0.0.0.0
CONTROL_SERVER_PORT=8765
HTTP_API_PORT=8766
```
## Benefits
1. **Unified Server:** Single aiohttp application handles all HTTP and WebSocket traffic
2. **Easier CORS:** Can add CORS middleware once for both REST and WebSocket
3. **Simpler Deployment:** One port for UI clients (WebSocket + API)
4. **Standard REST Patterns:** aiohttp's routing and middleware ecosystem
5. **Less Dependencies:** One web framework instead of two
## Testing
### Test WebSocket Connection
```bash
# Python test client
pipenv run python test/test_control_server.py --pattern rainbow
```
### Test HTTP API
```bash
# Get color palette
curl http://localhost:8765/api/color-palette
# Update selected colors
curl -X POST http://localhost:8765/api/color-palette \
-H "Content-Type: application/json" \
-d '{"selected_indices": [3, 6]}'
```
## Backward Compatibility
- HTTP API still available on port 8766
- WebSocket protocol unchanged (JSON message format)
- Only the WebSocket URL path changed (added `/ws`)
## Files Modified
1. `/home/pi/lighting-controller/src/control_server.py` - Main refactor
2. `/home/pi/lighting-controller/Pipfile` - Dependencies (kept both aiohttp and websockets)
3. `/home/pi/lighting-controller/COLOR_PALETTE_API.md` - Updated documentation
## Files NOT Modified
- `/home/pi/lighting-controller/src/networking.py` - Still uses `websockets` for client connections
- `/home/pi/lighting-controller/src/ui_client.py` - UI being worked on elsewhere (needs URL update)
- `/home/pi/led-bar/*` - No changes needed