Add adaptive FPS and honest device reachability during streaming
DDP uses fire-and-forget UDP, so when a WiFi device becomes overwhelmed by sustained traffic, sends appear successful while the device is actually unreachable. This adds: - HTTP liveness probe (GET /json/info, 2s timeout) every 10s during streaming, exposed as device_streaming_reachable in target state - Adaptive FPS (opt-in): exponential backoff when device is unreachable, gradual recovery when it stabilizes — finds sustainable send rate - Honest health checks: removed the lie that forced device_online=true during streaming; now runs actual health checks regardless - Target editor toggle, FPS display shows effective rate when throttled, health dot reflects streaming reachability, red highlight when unreachable - Auto-backup scheduling support in settings modal Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,8 +13,10 @@ 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.core.profiles.profile_engine import ProfileEngine
|
||||
from wled_controller.core.backup.auto_backup import AutoBackupEngine
|
||||
|
||||
# Global instances (initialized in main.py)
|
||||
_auto_backup_engine: AutoBackupEngine | None = None
|
||||
_device_store: DeviceStore | None = None
|
||||
_template_store: TemplateStore | None = None
|
||||
_pp_template_store: PostprocessingTemplateStore | None = None
|
||||
@@ -121,6 +123,13 @@ def get_profile_engine() -> ProfileEngine:
|
||||
return _profile_engine
|
||||
|
||||
|
||||
def get_auto_backup_engine() -> AutoBackupEngine:
|
||||
"""Get auto-backup engine dependency."""
|
||||
if _auto_backup_engine is None:
|
||||
raise RuntimeError("Auto-backup engine not initialized")
|
||||
return _auto_backup_engine
|
||||
|
||||
|
||||
def init_dependencies(
|
||||
device_store: DeviceStore,
|
||||
template_store: TemplateStore,
|
||||
@@ -135,12 +144,13 @@ def init_dependencies(
|
||||
value_source_store: ValueSourceStore | None = None,
|
||||
profile_store: ProfileStore | None = None,
|
||||
profile_engine: ProfileEngine | None = None,
|
||||
auto_backup_engine: AutoBackupEngine | None = None,
|
||||
):
|
||||
"""Initialize global 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
|
||||
global _value_source_store, _profile_store, _profile_engine, _auto_backup_engine
|
||||
_device_store = device_store
|
||||
_template_store = template_store
|
||||
_processor_manager = processor_manager
|
||||
@@ -154,3 +164,4 @@ def init_dependencies(
|
||||
_value_source_store = value_source_store
|
||||
_profile_store = profile_store
|
||||
_profile_engine = profile_engine
|
||||
_auto_backup_engine = auto_backup_engine
|
||||
|
||||
Reference in New Issue
Block a user