Add composable filter templates, skip keepalive for serial devices
Filter Template meta-filter: reference existing PP templates inside others for composable, DRY filter chains. Filters are recursively expanded at pipeline build time with cycle detection. New `select` option type with dynamic choices populated by the API. Keepalive optimization: serial devices (Adalight, AmbiLED) don't need keepalive — they hold last frame indefinitely. Check `standby_required` capability at processor start, skip keepalive sends for serial targets, and hide keepalive metrics in the UI. Rename "Standby Interval" to "Keep Alive Interval" throughout the frontend. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ from wled_controller.api.auth import AuthRequired
|
||||
from wled_controller.api.dependencies import (
|
||||
get_device_store,
|
||||
get_picture_source_store,
|
||||
get_pp_template_store,
|
||||
get_processor_manager,
|
||||
get_template_store,
|
||||
)
|
||||
@@ -385,26 +386,44 @@ async def test_template(
|
||||
# ===== FILTER TYPE ENDPOINTS =====
|
||||
|
||||
@router.get("/api/v1/filters", response_model=FilterTypeListResponse, tags=["Filters"])
|
||||
async def list_filter_types(_auth: AuthRequired):
|
||||
async def list_filter_types(
|
||||
_auth: AuthRequired,
|
||||
pp_store=Depends(get_pp_template_store),
|
||||
):
|
||||
"""List all available postprocessing filter types and their options schemas."""
|
||||
all_filters = FilterRegistry.get_all()
|
||||
|
||||
# Pre-build template choices for the filter_template filter
|
||||
template_choices = None
|
||||
if pp_store:
|
||||
try:
|
||||
templates = pp_store.get_all_templates()
|
||||
template_choices = [{"value": t.id, "label": t.name} for t in templates]
|
||||
except Exception:
|
||||
template_choices = []
|
||||
|
||||
responses = []
|
||||
for filter_id, filter_cls in all_filters.items():
|
||||
schema = filter_cls.get_options_schema()
|
||||
opt_schemas = []
|
||||
for opt in schema:
|
||||
choices = opt.choices
|
||||
# Enrich filter_template choices with current template list
|
||||
if filter_id == "filter_template" and opt.key == "template_id" and template_choices is not None:
|
||||
choices = template_choices
|
||||
opt_schemas.append(FilterOptionDefSchema(
|
||||
key=opt.key,
|
||||
label=opt.label,
|
||||
type=opt.option_type,
|
||||
default=opt.default,
|
||||
min_value=opt.min_value,
|
||||
max_value=opt.max_value,
|
||||
step=opt.step,
|
||||
choices=choices,
|
||||
))
|
||||
responses.append(FilterTypeResponse(
|
||||
filter_id=filter_cls.filter_id,
|
||||
filter_name=filter_cls.filter_name,
|
||||
options_schema=[
|
||||
FilterOptionDefSchema(
|
||||
key=opt.key,
|
||||
label=opt.label,
|
||||
type=opt.option_type,
|
||||
default=opt.default,
|
||||
min_value=opt.min_value,
|
||||
max_value=opt.max_value,
|
||||
step=opt.step,
|
||||
)
|
||||
for opt in schema
|
||||
],
|
||||
options_schema=opt_schemas,
|
||||
))
|
||||
return FilterTypeListResponse(filters=responses, count=len(responses))
|
||||
|
||||
Reference in New Issue
Block a user