diff --git a/firmware/README-API.md b/firmware/README-API.md index 359ca4b..c77cdd1 100644 --- a/firmware/README-API.md +++ b/firmware/README-API.md @@ -7,6 +7,7 @@ This document describes all REST API endpoints and WebSocket messages required f - [REST API Endpoints](#rest-api-endpoints) - [WiFi](#wifi) - [Light Control](#light-control) + - [WLED Configuration](#wled-configuration) - [Schema](#schema) - [Devices](#devices) - [Scenes](#scenes) @@ -201,6 +202,89 @@ Returns current light status (alternative to WebSocket). --- +### WLED Configuration + +#### Get WLED Configuration + +Returns the current WLED configuration including host and all segments. + +- **URL:** `/api/wled/config` +- **Method:** `GET` +- **Response:** + +```json +{ + "host": "192.168.1.100", + "segments": [ + { + "name": "Main Light", + "start": 0, + "leds": 60 + }, + { + "name": "Accent Light", + "start": 60, + "leds": 30 + } + ] +} +``` + +| Field | Type | Description | +|--------------------|--------|------------------------------------------| +| host | string | WLED host address (IP or hostname) | +| segments | array | List of LED segments | +| segments[].name | string | Optional segment name | +| segments[].start | number | Start LED index (0-based) | +| segments[].leds | number | Number of LEDs in this segment | + +--- + +#### Save WLED Configuration + +Saves the WLED configuration. + +- **URL:** `/api/wled/config` +- **Method:** `POST` +- **Content-Type:** `application/json` +- **Request Body:** + +```json +{ + "host": "192.168.1.100", + "segments": [ + { + "name": "Main Light", + "start": 0, + "leds": 60 + }, + { + "name": "Accent Light", + "start": 60, + "leds": 30 + } + ] +} +``` + +| Field | Type | Required | Description | +|--------------------|--------|----------|------------------------------------------| +| host | string | Yes | WLED host address (IP or hostname) | +| segments | array | Yes | List of LED segments (can be empty) | +| segments[].name | string | No | Optional segment name | +| segments[].start | number | Yes | Start LED index (0-based) | +| segments[].leds | number | Yes | Number of LEDs in this segment | + +- **Response:** `200 OK` on success, `400 Bad Request` on validation error + +**Notes:** +- The firmware uses this configuration to communicate with a WLED controller +- Segments are mapped to the WLED JSON API segment control +- Changes are persisted to NVS (non-volatile storage) +- The host can be an IP address (e.g., `192.168.1.100`) or hostname (e.g., `wled.local`) + +--- + ### Schema #### Load Schema diff --git a/firmware/storage/www/css/index.css b/firmware/storage/www/css/index.css index 7b38b94..2cc17cd 100644 --- a/firmware/storage/www/css/index.css +++ b/firmware/storage/www/css/index.css @@ -1198,4 +1198,136 @@ body { .scene-action-row select { width: 100%; } +} + +/* WLED Configuration */ +.segment-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12px; +} + +.segment-header h3 { + margin: 0; + font-size: 1rem; + color: var(--text); +} + +.btn-small { + padding: 6px 12px; + font-size: 0.85rem; +} + +.wled-segments-list { + display: flex; + flex-direction: column; + gap: 12px; + margin-bottom: 20px; +} + +.wled-segment-item { + display: grid; + grid-template-columns: 1fr auto auto auto; + gap: 12px; + align-items: flex-end; + padding: 16px; + background: var(--bg-color); + border-radius: 10px; + border: 1px solid var(--border); +} + +.segment-name-field { + display: flex; + flex-direction: column; + gap: 4px; +} + +.segment-number { + font-weight: 600; + font-size: 0.75rem; + color: var(--primary); +} + +.segment-name-input { + padding: 8px 12px; + border: 1px solid var(--border); + border-radius: 6px; + background: var(--card-bg); + color: var(--text); + font-size: 0.9rem; + height: 38px; + box-sizing: border-box; +} + +.segment-field { + display: flex; + flex-direction: column; + gap: 4px; +} + +.segment-field label { + font-size: 0.75rem; + color: var(--text-secondary); + white-space: nowrap; +} + +.segment-field input { + padding: 8px 10px; + border: 1px solid var(--border); + border-radius: 6px; + background: var(--card-bg); + color: var(--text); + font-size: 0.9rem; + text-align: center; + width: 70px; + height: 38px; + box-sizing: border-box; +} + +.segment-remove-btn { + padding: 8px; + background: transparent; + border: 1px solid var(--border); + border-radius: 6px; + cursor: pointer; + color: var(--text-secondary); + transition: all 0.2s; + height: 38px; + width: 38px; + box-sizing: border-box; + align-self: flex-end; +} + +.segment-remove-btn:hover { + background: #ff4444; + border-color: #ff4444; + color: white; +} + +/* Responsive for WLED */ +@media (max-width: 600px) { + .segment-header { + flex-direction: column; + align-items: flex-start; + gap: 10px; + } + + .wled-segment-item { + grid-template-columns: 1fr 1fr; + grid-template-rows: auto auto auto; + } + + .segment-number { + grid-column: 1 / -1; + } + + .segment-name-input { + grid-column: 1 / -1; + } + + .segment-remove-btn { + grid-column: 1 / -1; + justify-self: end; + } } \ No newline at end of file diff --git a/firmware/storage/www/index.html b/firmware/storage/www/index.html index 53f2a96..0383a43 100644 --- a/firmware/storage/www/index.html +++ b/firmware/storage/www/index.html @@ -135,7 +135,8 @@
Konfiguriere die WLED-Segmente und LEDs pro + Segment
+ +Keine Segmente konfiguriert
+Klicke auf "Segment hinzufügen" + um ein Segment zu erstellen
+