Frame interpolation, FPS hot-update, timing metrics, KC brightness fixes
- CSS: add frame interpolation option — blends between consecutive captured frames on idle ticks so LED output runs at full target FPS even when capture rate is lower (e.g. capture 30fps, output 60fps) - WledTargetProcessor: re-read stream.target_fps each loop tick so FPS changes to the CSS source take effect without restarting the target - WledTargetProcessor: restore per-stage timing metrics on target card by pulling extract/map/smooth/total from CSS stream get_last_timing() - TargetProcessingState schema: add missing timing_extract_ms, timing_map_leds_ms, timing_smooth_ms, timing_total_ms fields - KC targets: add extraction FPS badge to target card props row - KC targets: fix 500 error when changing brightness — update_fields now accepts (and ignores) WLED-specific kwargs - KC targets: fix partial key_colors_settings update wiping pattern_template_id — update route merges only explicitly-set fields using model_dump(exclude_unset=True) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -121,6 +121,7 @@ class ColorStripSource:
|
||||
interpolation_mode=data.get("interpolation_mode") or "average",
|
||||
calibration=calibration,
|
||||
led_count=data.get("led_count") or 0,
|
||||
frame_interpolation=bool(data.get("frame_interpolation", False)),
|
||||
)
|
||||
|
||||
|
||||
@@ -143,6 +144,7 @@ class PictureColorStripSource(ColorStripSource):
|
||||
default_factory=lambda: CalibrationConfig(layout="clockwise", start_position="bottom_left")
|
||||
)
|
||||
led_count: int = 0 # explicit LED count; 0 = auto (derived from calibration)
|
||||
frame_interpolation: bool = False # blend between consecutive captured frames
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
d = super().to_dict()
|
||||
@@ -155,6 +157,7 @@ class PictureColorStripSource(ColorStripSource):
|
||||
d["interpolation_mode"] = self.interpolation_mode
|
||||
d["calibration"] = calibration_to_dict(self.calibration)
|
||||
d["led_count"] = self.led_count
|
||||
d["frame_interpolation"] = self.frame_interpolation
|
||||
return d
|
||||
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ class ColorStripStore:
|
||||
color: Optional[list] = None,
|
||||
stops: Optional[list] = None,
|
||||
description: Optional[str] = None,
|
||||
frame_interpolation: bool = False,
|
||||
) -> ColorStripSource:
|
||||
"""Create a new color strip source.
|
||||
|
||||
@@ -165,6 +166,7 @@ class ColorStripStore:
|
||||
interpolation_mode=interpolation_mode,
|
||||
calibration=calibration,
|
||||
led_count=led_count,
|
||||
frame_interpolation=frame_interpolation,
|
||||
)
|
||||
|
||||
self._sources[source_id] = source
|
||||
@@ -189,6 +191,7 @@ class ColorStripStore:
|
||||
color: Optional[list] = None,
|
||||
stops: Optional[list] = None,
|
||||
description: Optional[str] = None,
|
||||
frame_interpolation: Optional[bool] = None,
|
||||
) -> ColorStripSource:
|
||||
"""Update an existing color strip source.
|
||||
|
||||
@@ -228,6 +231,8 @@ class ColorStripStore:
|
||||
source.calibration = calibration
|
||||
if led_count is not None:
|
||||
source.led_count = led_count
|
||||
if frame_interpolation is not None:
|
||||
source.frame_interpolation = frame_interpolation
|
||||
elif isinstance(source, StaticColorStripSource):
|
||||
if color is not None:
|
||||
if isinstance(color, list) and len(color) == 3:
|
||||
|
||||
@@ -90,7 +90,10 @@ class KeyColorsPictureTarget(PictureTarget):
|
||||
manager.update_target_source(self.id, self.picture_source_id)
|
||||
|
||||
def update_fields(self, *, name=None, device_id=None, picture_source_id=None,
|
||||
settings=None, key_colors_settings=None, description=None) -> None:
|
||||
settings=None, key_colors_settings=None, description=None,
|
||||
# WledPictureTarget-specific params — accepted but ignored:
|
||||
color_strip_source_id=None, standby_interval=None,
|
||||
state_check_interval=None) -> None:
|
||||
"""Apply mutable field updates for KC targets."""
|
||||
super().update_fields(name=name, description=description)
|
||||
if picture_source_id is not None:
|
||||
|
||||
Reference in New Issue
Block a user