Add static color support, HAOS light entity, and real-time profile updates

- Add static_color capability to WLED and serial providers with native
  set_color() dispatch (WLED uses JSON API, serial uses idle client)
- Encapsulate device-specific logic in providers instead of device_type
  checks in ProcessorManager and API routes
- Add HAOS light entity for devices with brightness_control + static_color
  (Adalight/AmbiLED get light entity, WLED keeps number entity)
- Fix serial device brightness and turn-off: pass software_brightness
  through provider chain, clear device on color=null, re-send static
  color after brightness change
- Add global events WebSocket (events-ws.js) replacing per-tab WS,
  enabling real-time profile state updates on both dashboard and profiles tabs
- Fix profile activation: mark active when all targets already running,
  add asyncio.Lock to prevent concurrent evaluation races, skip process
  enumeration when no profile has conditions, trigger immediate evaluation
  on enable/create/update for instant target startup
- Add reliable server restart script (restart.ps1)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 14:23:47 +03:00
parent 6388e0defa
commit bef28ece5c
21 changed files with 410 additions and 78 deletions

View File

@@ -35,10 +35,11 @@ import {
updateSettingsBaudFpsHint,
} from './features/devices.js';
import {
loadDashboard, startDashboardWS, stopDashboardWS, stopUptimeTimer,
loadDashboard, stopUptimeTimer,
dashboardToggleProfile, dashboardStartTarget, dashboardStopTarget, dashboardStopAll,
toggleDashboardSection, changeDashboardPollInterval,
} from './features/dashboard.js';
import { startEventsWS, stopEventsWS } from './core/events-ws.js';
import {
startPerfPolling, stopPerfPolling,
} from './features/perf-charts.js';
@@ -150,8 +151,6 @@ Object.assign(window, {
// dashboard
loadDashboard,
startDashboardWS,
stopDashboardWS,
dashboardToggleProfile,
dashboardStartTarget,
dashboardStopTarget,
@@ -301,6 +300,7 @@ window.addEventListener('beforeunload', () => {
if (refreshInterval) {
clearInterval(refreshInterval);
}
stopEventsWS();
disconnectAllKCWebSockets();
});
@@ -337,6 +337,7 @@ document.addEventListener('DOMContentLoaded', async () => {
loadDisplays();
loadTargetsTab();
// Start auto-refresh
// Start global events WebSocket and auto-refresh
startEventsWS();
startAutoRefresh();
});