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:
2026-02-23 01:48:23 +03:00
parent a4083764fb
commit 9e555cef2e
12 changed files with 178 additions and 51 deletions

View File

@@ -297,6 +297,7 @@
"filters.auto_crop": "Auto Crop",
"filters.flip": "Flip",
"filters.color_correction": "Color Correction",
"filters.filter_template": "Filter Template",
"postprocessing.description_label": "Description (optional):",
"postprocessing.description_placeholder": "Describe this template...",
"postprocessing.created": "Template created successfully",
@@ -372,8 +373,8 @@
"targets.interpolation.dominant": "Dominant",
"targets.smoothing": "Smoothing:",
"targets.smoothing.hint": "Temporal blending between frames (0=none, 1=full). Reduces flicker.",
"targets.standby_interval": "Standby Interval:",
"targets.standby_interval.hint": "How often to resend the last frame when the screen is static, keeping the device in live mode (0.5-5.0s)",
"targets.keepalive_interval": "Keep Alive Interval:",
"targets.keepalive_interval.hint": "How often to resend the last frame when the source is static, keeping the device in live mode (0.5-5.0s)",
"targets.created": "Target created successfully",
"targets.updated": "Target updated successfully",
"targets.deleted": "Target deleted successfully",

View File

@@ -297,6 +297,7 @@
"filters.auto_crop": "Авто Обрезка",
"filters.flip": "Отражение",
"filters.color_correction": "Цветокоррекция",
"filters.filter_template": "Шаблон фильтров",
"postprocessing.description_label": "Описание (необязательно):",
"postprocessing.description_placeholder": "Опишите этот шаблон...",
"postprocessing.created": "Шаблон успешно создан",
@@ -372,8 +373,8 @@
"targets.interpolation.dominant": "Доминантный",
"targets.smoothing": "Сглаживание:",
"targets.smoothing.hint": "Временное смешивание между кадрами (0=нет, 1=полное). Уменьшает мерцание.",
"targets.standby_interval": "Интервал ожидания:",
"targets.standby_interval.hint": "Как часто повторно отправлять последний кадр при статичном экране для удержания устройства в режиме live (0.5-5.0с)",
"targets.keepalive_interval": "Интервал поддержания связи:",
"targets.keepalive_interval.hint": "Как часто повторно отправлять последний кадр при статичном источнике для удержания устройства в режиме live (0.5-5.0с)",
"targets.created": "Цель успешно создана",
"targets.updated": "Цель успешно обновлена",
"targets.deleted": "Цель успешно удалена",