Fix serial send bloat when sharing CSS stream with higher-LED device
When two targets share the same color strip source, configure() resizes the stream to the last caller's LED count. If a WLED device (934 LEDs) starts after a serial device (fewer LEDs), the serial target sends the full 934-LED frame over serial, massively inflating send time. Add _fit_to_device() to truncate/tile colors to the target's actual device LED count before sending, so each consumer only transmits what its device needs regardless of the shared stream's current size. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -362,6 +362,22 @@ class WledTargetProcessor(TargetProcessor):
|
|||||||
return (colors.astype(np.uint16) * device_info.software_brightness >> 8).astype(np.uint8)
|
return (colors.astype(np.uint16) * device_info.software_brightness >> 8).astype(np.uint8)
|
||||||
return colors
|
return colors
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _fit_to_device(colors: np.ndarray, device_led_count: int) -> np.ndarray:
|
||||||
|
"""Truncate or repeat colors to match the target device LED count.
|
||||||
|
|
||||||
|
Shared streams may be sized to a different consumer's LED count.
|
||||||
|
This ensures each target only sends what its device actually needs.
|
||||||
|
"""
|
||||||
|
n = len(colors)
|
||||||
|
if n == device_led_count or device_led_count <= 0:
|
||||||
|
return colors
|
||||||
|
if n > device_led_count:
|
||||||
|
return colors[:device_led_count]
|
||||||
|
# Tile to fill (rare — usually streams are >= device count)
|
||||||
|
reps = (device_led_count + n - 1) // n
|
||||||
|
return np.tile(colors, (reps, 1))[:device_led_count]
|
||||||
|
|
||||||
async def _processing_loop(self) -> None:
|
async def _processing_loop(self) -> None:
|
||||||
"""Main processing loop — poll ColorStripStream → apply brightness → send."""
|
"""Main processing loop — poll ColorStripStream → apply brightness → send."""
|
||||||
stream = self._color_strip_stream
|
stream = self._color_strip_stream
|
||||||
@@ -430,7 +446,10 @@ class WledTargetProcessor(TargetProcessor):
|
|||||||
if prev_colors is not None and (loop_start - last_send_time) >= standby_interval:
|
if prev_colors is not None and (loop_start - last_send_time) >= standby_interval:
|
||||||
if not self._is_running or self._led_client is None:
|
if not self._is_running or self._led_client is None:
|
||||||
break
|
break
|
||||||
send_colors = self._apply_brightness(prev_colors, device_info)
|
kc = prev_colors
|
||||||
|
if device_info and device_info.led_count > 0:
|
||||||
|
kc = self._fit_to_device(kc, device_info.led_count)
|
||||||
|
send_colors = self._apply_brightness(kc, device_info)
|
||||||
if self._led_client.supports_fast_send:
|
if self._led_client.supports_fast_send:
|
||||||
self._led_client.send_pixels_fast(send_colors)
|
self._led_client.send_pixels_fast(send_colors)
|
||||||
else:
|
else:
|
||||||
@@ -448,6 +467,10 @@ class WledTargetProcessor(TargetProcessor):
|
|||||||
|
|
||||||
prev_colors = colors
|
prev_colors = colors
|
||||||
|
|
||||||
|
# Fit to this device's LED count (stream may be shared)
|
||||||
|
if device_info and device_info.led_count > 0:
|
||||||
|
colors = self._fit_to_device(colors, device_info.led_count)
|
||||||
|
|
||||||
# Apply device software brightness
|
# Apply device software brightness
|
||||||
send_colors = self._apply_brightness(colors, device_info)
|
send_colors = self._apply_brightness(colors, device_info)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user