diff --git a/server/src/wled_controller/core/processing/processor_manager.py b/server/src/wled_controller/core/processing/processor_manager.py
index 53885f1..6772597 100644
--- a/server/src/wled_controller/core/processing/processor_manager.py
+++ b/server/src/wled_controller/core/processing/processor_manager.py
@@ -272,6 +272,13 @@ class ProcessorManager:
ds = self._devices[device_id]
h = ds.health
+ # Fall back to stored device rgbw when health check doesn't report it
+ # (e.g. mock devices have no real hardware to query)
+ rgbw = h.device_rgbw
+ if rgbw is None and self._device_store:
+ dev = self._device_store.get_device(device_id)
+ if dev:
+ rgbw = getattr(dev, "rgbw", False)
return {
"device_id": device_id,
"device_online": h.online,
@@ -279,7 +286,7 @@ class ProcessorManager:
"device_name": h.device_name,
"device_version": h.device_version,
"device_led_count": h.device_led_count,
- "device_rgbw": h.device_rgbw,
+ "device_rgbw": rgbw,
"device_led_type": h.device_led_type,
"device_fps": h.device_fps,
"device_last_checked": h.last_checked,
diff --git a/server/src/wled_controller/static/js/features/streams.js b/server/src/wled_controller/static/js/features/streams.js
index c48cbe4..43e2bf2 100644
--- a/server/src/wled_controller/static/js/features/streams.js
+++ b/server/src/wled_controller/static/js/features/streams.js
@@ -729,8 +729,8 @@ function renderPictureSourcesList(streams) {
const parentName = parent ? parent.name : src.audio_source_id;
const chLabel = src.channel === 'left' ? 'L' : src.channel === 'right' ? 'R' : 'M';
propsHtml = `
- ${escapeHtml(parentName)}
- ${chLabel}
+ 🔊 ${escapeHtml(parentName)}
+ 📻 ${chLabel}
`;
} else {
const devIdx = src.device_index ?? -1;
diff --git a/server/src/wled_controller/static/js/features/value-sources.js b/server/src/wled_controller/static/js/features/value-sources.js
index 907671a..97f95ba 100644
--- a/server/src/wled_controller/static/js/features/value-sources.js
+++ b/server/src/wled_controller/static/js/features/value-sources.js
@@ -267,35 +267,35 @@ export function createValueSourceCard(src) {
let propsHtml = '';
if (src.source_type === 'static') {
- propsHtml = `${t('value_source.type.static')}: ${src.value ?? 1.0}`;
+ propsHtml = `📊 ${t('value_source.type.static')}: ${src.value ?? 1.0}`;
} else if (src.source_type === 'animated') {
const waveLabel = src.waveform || 'sine';
propsHtml = `
- ${escapeHtml(waveLabel)}
- ${src.speed ?? 10} cpm
- ${src.min_value ?? 0}–${src.max_value ?? 1}
+ 〰️ ${escapeHtml(waveLabel)}
+ ⏱️ ${src.speed ?? 10} cpm
+ ↕️ ${src.min_value ?? 0}–${src.max_value ?? 1}
`;
} else if (src.source_type === 'audio') {
const audioSrc = _cachedAudioSources.find(a => a.id === src.audio_source_id);
const audioName = audioSrc ? audioSrc.name : (src.audio_source_id || '-');
const modeLabel = src.mode || 'rms';
propsHtml = `
- ${escapeHtml(audioName)}
- ${modeLabel.toUpperCase()}
- ${src.min_value ?? 0}–${src.max_value ?? 1}
+ 🎵 ${escapeHtml(audioName)}
+ 📈 ${modeLabel.toUpperCase()}
+ ↕️ ${src.min_value ?? 0}–${src.max_value ?? 1}
`;
} else if (src.source_type === 'adaptive_time') {
const pts = (src.schedule || []).length;
propsHtml = `
- ${pts} ${t('value_source.schedule.points')}
- ${src.min_value ?? 0}–${src.max_value ?? 1}
+ 📍 ${pts} ${t('value_source.schedule.points')}
+ ↕️ ${src.min_value ?? 0}–${src.max_value ?? 1}
`;
} else if (src.source_type === 'adaptive_scene') {
const ps = _cachedStreams.find(s => s.id === src.picture_source_id);
const psName = ps ? ps.name : (src.picture_source_id || '-');
propsHtml = `
- ${escapeHtml(psName)}
- ${src.scene_behavior || 'complement'}
+ 🖥️ ${escapeHtml(psName)}
+ 🔄 ${src.scene_behavior || 'complement'}
`;
}