- 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
149 lines
3.9 KiB
Markdown
149 lines
3.9 KiB
Markdown
# 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
|
|
|