Add profile conditions, scene presets, MQTT integration, and Scenes tab

Feature 1 — Profile Conditions: time-of-day, system idle (Win32
GetLastInputInfo), and display state (GUID_CONSOLE_DISPLAY_STATE)
condition types for automatic profile activation.

Feature 2 — Scene Presets: snapshot/restore system that captures target
running states, device brightness, and profile enables. Server-side
capture with 5-step activation order. Dedicated Scenes tab with
CardSection-based card grid, command palette integration, and dashboard
quick-activate section.

Feature 3 — MQTT Integration: MQTTService singleton with aiomqtt,
MQTTLEDClient device provider for pixel output, MQTT profile condition
type with topic/payload matching, and frontend support for MQTT device
type and condition editor.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-28 16:57:42 +03:00
parent bd8d7a019f
commit 2e747b5ece
38 changed files with 2269 additions and 32 deletions

View File

@@ -12,6 +12,7 @@ from wled_controller.storage.audio_source_store import AudioSourceStore
from wled_controller.storage.audio_template_store import AudioTemplateStore
from wled_controller.storage.value_source_store import ValueSourceStore
from wled_controller.storage.profile_store import ProfileStore
from wled_controller.storage.scene_preset_store import ScenePresetStore
from wled_controller.core.profiles.profile_engine import ProfileEngine
from wled_controller.core.backup.auto_backup import AutoBackupEngine
@@ -29,6 +30,7 @@ _audio_template_store: AudioTemplateStore | None = None
_value_source_store: ValueSourceStore | None = None
_processor_manager: ProcessorManager | None = None
_profile_store: ProfileStore | None = None
_scene_preset_store: ScenePresetStore | None = None
_profile_engine: ProfileEngine | None = None
@@ -116,6 +118,13 @@ def get_profile_store() -> ProfileStore:
return _profile_store
def get_scene_preset_store() -> ScenePresetStore:
"""Get scene preset store dependency."""
if _scene_preset_store is None:
raise RuntimeError("Scene preset store not initialized")
return _scene_preset_store
def get_profile_engine() -> ProfileEngine:
"""Get profile engine dependency."""
if _profile_engine is None:
@@ -143,6 +152,7 @@ def init_dependencies(
audio_template_store: AudioTemplateStore | None = None,
value_source_store: ValueSourceStore | None = None,
profile_store: ProfileStore | None = None,
scene_preset_store: ScenePresetStore | None = None,
profile_engine: ProfileEngine | None = None,
auto_backup_engine: AutoBackupEngine | None = None,
):
@@ -150,7 +160,7 @@ def init_dependencies(
global _device_store, _template_store, _processor_manager
global _pp_template_store, _pattern_template_store, _picture_source_store, _picture_target_store
global _color_strip_store, _audio_source_store, _audio_template_store
global _value_source_store, _profile_store, _profile_engine, _auto_backup_engine
global _value_source_store, _profile_store, _scene_preset_store, _profile_engine, _auto_backup_engine
_device_store = device_store
_template_store = template_store
_processor_manager = processor_manager
@@ -163,5 +173,6 @@ def init_dependencies(
_audio_template_store = audio_template_store
_value_source_store = value_source_store
_profile_store = profile_store
_scene_preset_store = scene_preset_store
_profile_engine = profile_engine
_auto_backup_engine = auto_backup_engine