feat: add weather source entity and weather-reactive CSS source type
Some checks failed
Lint & Test / test (push) Failing after 34s
Some checks failed
Lint & Test / test (push) Failing after 34s
New standalone WeatherSource entity with pluggable provider architecture (Open-Meteo v1, free, no API key). Full CRUD, test endpoint, browser geolocation, IconSelect provider picker, CardSection with test/clone/edit. WeatherColorStripStream maps WMO weather codes to ambient color palettes with temperature hue shifting and thunderstorm flash effects. Ref-counted WeatherManager polls API and caches data per source. CSS editor integration: weather type with EntitySelect source picker, speed and temperature influence sliders. Backup/restore support. i18n for en/ru/zh.
This commit is contained in:
@@ -33,7 +33,9 @@ from wled_controller.storage.scene_preset_store import ScenePresetStore
|
||||
from wled_controller.storage.sync_clock_store import SyncClockStore
|
||||
from wled_controller.storage.color_strip_processing_template_store import ColorStripProcessingTemplateStore
|
||||
from wled_controller.storage.gradient_store import GradientStore
|
||||
from wled_controller.storage.weather_source_store import WeatherSourceStore
|
||||
from wled_controller.core.processing.sync_clock_manager import SyncClockManager
|
||||
from wled_controller.core.weather.weather_manager import WeatherManager
|
||||
from wled_controller.core.automations.automation_engine import AutomationEngine
|
||||
from wled_controller.core.mqtt.mqtt_service import MQTTService
|
||||
from wled_controller.core.devices.mqtt_client import set_mqtt_service
|
||||
@@ -72,7 +74,9 @@ sync_clock_store = SyncClockStore(config.storage.sync_clocks_file)
|
||||
cspt_store = ColorStripProcessingTemplateStore(config.storage.color_strip_processing_templates_file)
|
||||
gradient_store = GradientStore(config.storage.gradients_file)
|
||||
gradient_store.migrate_palette_references(color_strip_store)
|
||||
weather_source_store = WeatherSourceStore(config.storage.weather_sources_file)
|
||||
sync_clock_manager = SyncClockManager(sync_clock_store)
|
||||
weather_manager = WeatherManager(weather_source_store)
|
||||
|
||||
processor_manager = ProcessorManager(
|
||||
ProcessorDependencies(
|
||||
@@ -88,6 +92,7 @@ processor_manager = ProcessorManager(
|
||||
sync_clock_manager=sync_clock_manager,
|
||||
cspt_store=cspt_store,
|
||||
gradient_store=gradient_store,
|
||||
weather_manager=weather_manager,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -103,7 +108,7 @@ def _save_all_stores() -> None:
|
||||
picture_source_store, output_target_store, pattern_template_store,
|
||||
color_strip_store, audio_source_store, audio_template_store,
|
||||
value_source_store, automation_store, scene_preset_store,
|
||||
sync_clock_store, cspt_store, gradient_store,
|
||||
sync_clock_store, cspt_store, gradient_store, weather_source_store,
|
||||
]
|
||||
saved = 0
|
||||
for store in all_stores:
|
||||
@@ -195,6 +200,8 @@ async def lifespan(app: FastAPI):
|
||||
sync_clock_manager=sync_clock_manager,
|
||||
cspt_store=cspt_store,
|
||||
gradient_store=gradient_store,
|
||||
weather_source_store=weather_source_store,
|
||||
weather_manager=weather_manager,
|
||||
)
|
||||
|
||||
# Register devices in processor manager for health monitoring
|
||||
@@ -258,6 +265,12 @@ async def lifespan(app: FastAPI):
|
||||
# where no CRUD happened during the session.
|
||||
_save_all_stores()
|
||||
|
||||
# Stop weather manager
|
||||
try:
|
||||
weather_manager.shutdown()
|
||||
except Exception as e:
|
||||
logger.error(f"Error stopping weather manager: {e}")
|
||||
|
||||
# Stop auto-backup engine
|
||||
try:
|
||||
await auto_backup_engine.stop()
|
||||
|
||||
Reference in New Issue
Block a user