feat: HA light target live color preview — per-entity swatches via WebSocket
Lint & Test / test (push) Successful in 1m24s
Lint & Test / test (push) Successful in 1m24s
- Cache per-entity colors in HALightTargetProcessor._update_lights()
- Broadcast colors_update to WS clients at target's update_rate
- WS endpoint: /api/v1/output-targets/{target_id}/ha-light/ws
- Frontend: connect WS when target runs, update swatch colors live
- Card shows colored boxes per mapped entity with entity name labels
This commit is contained in:
@@ -18,7 +18,7 @@ import { showToast, showConfirm, formatUptime, formatCompact, setTabRefreshing,
|
||||
import { Modal } from '../core/modal.ts';
|
||||
import { createDeviceCard, attachDeviceListeners, fetchDeviceBrightness, enrichOpenrgbZoneBadges, _computeMaxFps, getZoneCountCache, formatRelativeTime } from './devices.ts';
|
||||
import { _splitOpenrgbZone } from './device-discovery.ts';
|
||||
import { createHALightTargetCard, initHALightTargetDelegation, patchHALightTargetMetrics } from './ha-light-targets.ts';
|
||||
import { createHALightTargetCard, initHALightTargetDelegation, patchHALightTargetMetrics, connectHALightWS, disconnectHALightWS } from './ha-light-targets.ts';
|
||||
import {
|
||||
getValueSourceIcon, getTargetTypeIcon, getDeviceTypeIcon, getColorStripIcon,
|
||||
ICON_CLONE, ICON_EDIT, ICON_START, ICON_STOP,
|
||||
@@ -616,21 +616,12 @@ export async function loadTargetsTab() {
|
||||
|
||||
const devicesWithState = devices.map(d => ({ ...d, state: allDeviceStates[d.id] || {} }));
|
||||
|
||||
// Enrich targets with state/metrics; fetch colors only for running KC targets
|
||||
const targetsWithState = await Promise.all(
|
||||
targets.map(async (target) => {
|
||||
const state = allTargetStates[target.id] || {};
|
||||
const metrics = allTargetMetrics[target.id] || {};
|
||||
let latestColors = null;
|
||||
if (target.target_type === 'key_colors' && state.processing) {
|
||||
try {
|
||||
const colorsResp = await fetch(`${API_BASE}/output-targets/${target.id}/colors`, { headers: getHeaders() });
|
||||
if (colorsResp.ok) latestColors = await colorsResp.json();
|
||||
} catch {}
|
||||
}
|
||||
return { ...target, state, metrics, latestColors };
|
||||
})
|
||||
);
|
||||
// Enrich targets with state/metrics
|
||||
const targetsWithState = targets.map((target) => {
|
||||
const state = allTargetStates[target.id] || {};
|
||||
const metrics = allTargetMetrics[target.id] || {};
|
||||
return { ...target, state, metrics };
|
||||
});
|
||||
|
||||
// Build device map for target name resolution
|
||||
const deviceMap = {};
|
||||
@@ -769,6 +760,15 @@ export async function loadTargetsTab() {
|
||||
if (!processingLedIds.has(id)) disconnectLedPreviewWS(id);
|
||||
});
|
||||
|
||||
// Manage HA light color preview WebSockets
|
||||
haLightTargets.forEach(target => {
|
||||
if (target.state && target.state.processing) {
|
||||
connectHALightWS(target.id);
|
||||
} else {
|
||||
disconnectHALightWS(target.id);
|
||||
}
|
||||
});
|
||||
|
||||
// FPS charts: only destroy charts for replaced/removed cards (or all on first render)
|
||||
if (changedTargetIds) {
|
||||
// Incremental: destroy only charts whose cards were replaced or removed
|
||||
|
||||
Reference in New Issue
Block a user