Introduce ColorStripSource as first-class entity
Extracts color processing and calibration out of WledPictureTarget into a new PictureColorStripSource entity, enabling multiple LED targets to share one capture/processing pipeline. New entities & processing: - storage/color_strip_source.py: ColorStripSource + PictureColorStripSource models - storage/color_strip_store.py: JSON-backed CRUD store (prefix css_) - core/processing/color_strip_stream.py: ColorStripStream ABC + PictureColorStripStream (runs border-extract → map → smooth → brightness/sat/gamma in background thread) - core/processing/color_strip_stream_manager.py: ref-counted shared stream manager Modified storage/processing: - WledPictureTarget simplified to device_id + color_strip_source_id + standby_interval + state_check_interval - Device model: calibration field removed - WledTargetProcessor: acquires ColorStripStream from manager instead of running its own pipeline - ProcessorManager: wires ColorStripStreamManager into TargetContext API layer: - New routes: GET/POST/PUT/DELETE /api/v1/color-strip-sources, PUT calibration/test - Removed calibration endpoints from /devices - Updated /picture-targets CRUD for new target structure Frontend: - New color-strips.js module with CSS editor modal and card rendering - Calibration modal extended with CSS mode (css-id hidden field + device picker) - targets.js: Color Strip Sources section added to LED tab; target editor/card updated - app.js: imports and window globals for CSS + showCSSCalibration - en.json / ru.json: color_strip.* and targets.section.color_strips keys added Data migration runs at startup: existing WledPictureTargets are converted to reference a new PictureColorStripSource created from their old settings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -343,10 +343,11 @@
|
||||
"streams.validate_image.valid": "Image accessible",
|
||||
"streams.validate_image.invalid": "Image not accessible",
|
||||
"targets.title": "⚡ Targets",
|
||||
"targets.description": "Targets bridge picture sources to output devices. Each target references a device and a source, with its own processing settings.",
|
||||
"targets.description": "Targets bridge color strip sources to output devices. Each target references a device and a color strip source.",
|
||||
"targets.subtab.wled": "LED",
|
||||
"targets.subtab.led": "LED",
|
||||
"targets.section.devices": "💡 Devices",
|
||||
"targets.section.color_strips": "🎞️ Color Strip Sources",
|
||||
"targets.section.targets": "⚡ Targets",
|
||||
"targets.add": "Add Target",
|
||||
"targets.edit": "Edit Target",
|
||||
@@ -358,6 +359,8 @@
|
||||
"targets.device": "Device:",
|
||||
"targets.device.hint": "Select the LED device to send data to",
|
||||
"targets.device.none": "-- Select a device --",
|
||||
"targets.color_strip_source": "Color Strip Source:",
|
||||
"targets.color_strip_source.hint": "Color strip source that captures and processes screen pixels into LED colors",
|
||||
"targets.source": "Source:",
|
||||
"targets.source.hint": "Which picture source to capture and process",
|
||||
"targets.source.none": "-- No source assigned --",
|
||||
@@ -380,6 +383,7 @@
|
||||
"targets.delete.confirm": "Are you sure you want to delete this target?",
|
||||
"targets.error.load": "Failed to load targets",
|
||||
"targets.error.required": "Please fill in all required fields",
|
||||
"targets.error.name_required": "Please enter a target name",
|
||||
"targets.error.delete": "Failed to delete target",
|
||||
"targets.button.start": "Start",
|
||||
"targets.button.stop": "Stop",
|
||||
@@ -531,5 +535,36 @@
|
||||
"aria.cancel": "Cancel",
|
||||
"aria.previous": "Previous",
|
||||
"aria.next": "Next",
|
||||
"aria.hint": "Show hint"
|
||||
"aria.hint": "Show hint",
|
||||
|
||||
"color_strip.add": "🎞️ Add Color Strip Source",
|
||||
"color_strip.edit": "🎞️ Edit Color Strip Source",
|
||||
"color_strip.name": "Name:",
|
||||
"color_strip.name.placeholder": "Wall Strip",
|
||||
"color_strip.picture_source": "Picture Source:",
|
||||
"color_strip.picture_source.hint": "Which screen capture source to use as input for LED color calculation",
|
||||
"color_strip.fps": "Target FPS:",
|
||||
"color_strip.fps.hint": "Target frames per second for LED color updates (10-90)",
|
||||
"color_strip.interpolation": "Color Mode:",
|
||||
"color_strip.interpolation.hint": "How to calculate LED color from sampled border pixels",
|
||||
"color_strip.interpolation.average": "Average",
|
||||
"color_strip.interpolation.median": "Median",
|
||||
"color_strip.interpolation.dominant": "Dominant",
|
||||
"color_strip.smoothing": "Smoothing:",
|
||||
"color_strip.smoothing.hint": "Temporal blending between frames (0=none, 1=full). Reduces flicker.",
|
||||
"color_strip.brightness": "Brightness:",
|
||||
"color_strip.brightness.hint": "Output brightness multiplier (0=off, 1=unchanged, 2=double). Applied after color extraction.",
|
||||
"color_strip.saturation": "Saturation:",
|
||||
"color_strip.saturation.hint": "Color saturation (0=grayscale, 1=unchanged, 2=double saturation)",
|
||||
"color_strip.gamma": "Gamma:",
|
||||
"color_strip.gamma.hint": "Gamma correction (1=none, <1=brighter midtones, >1=darker midtones)",
|
||||
"color_strip.test_device": "Test on Device:",
|
||||
"color_strip.test_device.hint": "Select a device to send test pixels to when clicking edge toggles",
|
||||
"color_strip.leds": "LED count",
|
||||
"color_strip.created": "Color strip source created",
|
||||
"color_strip.updated": "Color strip source updated",
|
||||
"color_strip.deleted": "Color strip source deleted",
|
||||
"color_strip.delete.confirm": "Are you sure you want to delete this color strip source?",
|
||||
"color_strip.delete.referenced": "Cannot delete: this source is in use by a target",
|
||||
"color_strip.error.name_required": "Please enter a name"
|
||||
}
|
||||
|
||||
@@ -343,10 +343,11 @@
|
||||
"streams.validate_image.valid": "Изображение доступно",
|
||||
"streams.validate_image.invalid": "Изображение недоступно",
|
||||
"targets.title": "⚡ Цели",
|
||||
"targets.description": "Цели связывают источники изображений с устройствами вывода. Каждая цель ссылается на устройство и источник, с собственными настройками обработки.",
|
||||
"targets.description": "Цели связывают источники цветовых полос с устройствами вывода. Каждая цель ссылается на устройство и источник цветовой полосы.",
|
||||
"targets.subtab.wled": "LED",
|
||||
"targets.subtab.led": "LED",
|
||||
"targets.section.devices": "💡 Устройства",
|
||||
"targets.section.color_strips": "🎞️ Источники цветовых полос",
|
||||
"targets.section.targets": "⚡ Цели",
|
||||
"targets.add": "Добавить Цель",
|
||||
"targets.edit": "Редактировать Цель",
|
||||
@@ -358,6 +359,8 @@
|
||||
"targets.device": "Устройство:",
|
||||
"targets.device.hint": "Выберите LED устройство для передачи данных",
|
||||
"targets.device.none": "-- Выберите устройство --",
|
||||
"targets.color_strip_source": "Источник цветовой полосы:",
|
||||
"targets.color_strip_source.hint": "Источник цветовой полосы, который захватывает и обрабатывает пиксели экрана в цвета светодиодов",
|
||||
"targets.source": "Источник:",
|
||||
"targets.source.hint": "Какой источник изображения захватывать и обрабатывать",
|
||||
"targets.source.none": "-- Источник не назначен --",
|
||||
@@ -380,6 +383,7 @@
|
||||
"targets.delete.confirm": "Вы уверены, что хотите удалить эту цель?",
|
||||
"targets.error.load": "Не удалось загрузить цели",
|
||||
"targets.error.required": "Пожалуйста, заполните все обязательные поля",
|
||||
"targets.error.name_required": "Введите название цели",
|
||||
"targets.error.delete": "Не удалось удалить цель",
|
||||
"targets.button.start": "Запустить",
|
||||
"targets.button.stop": "Остановить",
|
||||
@@ -531,5 +535,36 @@
|
||||
"aria.cancel": "Отмена",
|
||||
"aria.previous": "Назад",
|
||||
"aria.next": "Вперёд",
|
||||
"aria.hint": "Показать подсказку"
|
||||
"aria.hint": "Показать подсказку",
|
||||
|
||||
"color_strip.add": "🎞️ Добавить источник цветовой полосы",
|
||||
"color_strip.edit": "🎞️ Редактировать источник цветовой полосы",
|
||||
"color_strip.name": "Название:",
|
||||
"color_strip.name.placeholder": "Настенная полоса",
|
||||
"color_strip.picture_source": "Источник изображения:",
|
||||
"color_strip.picture_source.hint": "Источник захвата экрана для расчёта цветов светодиодов",
|
||||
"color_strip.fps": "Целевой FPS:",
|
||||
"color_strip.fps.hint": "Целевая частота кадров для обновления цветов светодиодов (10-90)",
|
||||
"color_strip.interpolation": "Режим цвета:",
|
||||
"color_strip.interpolation.hint": "Как вычислять цвет светодиода по пикселям рамки",
|
||||
"color_strip.interpolation.average": "Среднее",
|
||||
"color_strip.interpolation.median": "Медиана",
|
||||
"color_strip.interpolation.dominant": "Доминирующий",
|
||||
"color_strip.smoothing": "Сглаживание:",
|
||||
"color_strip.smoothing.hint": "Временное смешивание кадров (0=без смешивания, 1=полное). Уменьшает мерцание.",
|
||||
"color_strip.brightness": "Яркость:",
|
||||
"color_strip.brightness.hint": "Множитель яркости (0=выкл, 1=без изменений, 2=двойная). Применяется после извлечения цвета.",
|
||||
"color_strip.saturation": "Насыщенность:",
|
||||
"color_strip.saturation.hint": "Насыщенность цвета (0=оттенки серого, 1=без изменений, 2=двойная насыщенность)",
|
||||
"color_strip.gamma": "Гамма:",
|
||||
"color_strip.gamma.hint": "Гамма-коррекция (1=без коррекции, <1=ярче средние тона, >1=темнее средние тона)",
|
||||
"color_strip.test_device": "Тестировать на устройстве:",
|
||||
"color_strip.test_device.hint": "Выберите устройство для отправки тестовых пикселей при нажатии на рамку",
|
||||
"color_strip.leds": "Количество светодиодов",
|
||||
"color_strip.created": "Источник цветовой полосы создан",
|
||||
"color_strip.updated": "Источник цветовой полосы обновлён",
|
||||
"color_strip.deleted": "Источник цветовой полосы удалён",
|
||||
"color_strip.delete.confirm": "Удалить этот источник цветовой полосы?",
|
||||
"color_strip.delete.referenced": "Невозможно удалить: источник используется в цели",
|
||||
"color_strip.error.name_required": "Введите название"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user