Add WebSocket device type, capability-driven settings, hide filter on collapse

- New WS device type: broadcaster singleton + LEDClient that sends binary
  frames to connected WebSocket clients during processing
- FastAPI WS endpoint at /api/v1/devices/{device_id}/ws with token auth
- Frontend: add/edit WS devices, connection URL with copy button in settings
- Add health_check and auto_restore capabilities to WLED and Serial providers;
  hide health interval and auto-restore toggle for devices without them
- Skip health check loop for virtual devices (Mock, MQTT, WS) — set always-online
- Copy buttons and labels for API CSS push endpoints (REST POST / WebSocket)
- Hide mock:// and ws:// URLs in target device dropdown
- Hide filter textbox when card section is collapsed (cs-collapsed CSS class)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-28 20:55:09 +03:00
parent 175a2c6c10
commit fa81d6a608
21 changed files with 375 additions and 16 deletions

View File

@@ -31,6 +31,7 @@
<option value="adalight">Adalight</option>
<option value="ambiled">AmbiLED</option>
<option value="mqtt">MQTT</option>
<option value="ws">WebSocket</option>
<option value="mock">Mock</option>
</select>
</div>

View File

@@ -78,7 +78,7 @@
<input type="number" id="settings-send-latency" min="0" max="5000" value="0">
</div>
<div class="form-group">
<div class="form-group" id="settings-health-interval-group">
<div class="label-row">
<label for="settings-health-interval" data-i18n="settings.health_interval">Health Check Interval (s):</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
@@ -87,7 +87,7 @@
<input type="number" id="settings-health-interval" min="5" max="600" value="30">
</div>
<div class="form-group settings-toggle-group">
<div class="form-group settings-toggle-group" id="settings-auto-shutdown-group">
<div class="label-row">
<label data-i18n="settings.auto_shutdown">Auto Restore:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
@@ -99,6 +99,18 @@
</label>
</div>
<div class="form-group" id="settings-ws-url-group" style="display: none;">
<div class="label-row">
<label for="settings-ws-url" data-i18n="device.ws_url">Connection URL:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.ws_url.hint">WebSocket URL for clients to connect and receive LED data</small>
<div class="ws-url-row">
<input type="text" id="settings-ws-url" readonly>
<button type="button" class="btn btn-sm btn-secondary" onclick="copyWsUrl()" title="Copy">&#x1F4CB;</button>
</div>
</div>
<div id="settings-error" class="error-message" style="display: none;"></div>
</form>
</div>