feat: Home Assistant integration — WebSocket connection, automation conditions, UI
Add full Home Assistant integration via WebSocket API: - HARuntime: persistent WebSocket client with auth, auto-reconnect, entity state cache - HAManager: ref-counted runtime pool (like WeatherManager) - HomeAssistantCondition: new automation trigger type matching entity states - REST API: CRUD for HA sources + /test, /entities, /status endpoints - /api/v1/system/integrations-status: combined MQTT + HA dashboard indicators - Frontend: HA Sources tab in Streams, condition type in automation editor - Modal editor with host, token, SSL, entity filters - websockets>=13.0 dependency added
This commit is contained in:
@@ -21,6 +21,8 @@ from wled_controller.api.dependencies import (
|
||||
get_automation_store,
|
||||
get_color_strip_store,
|
||||
get_device_store,
|
||||
get_ha_manager,
|
||||
get_ha_store,
|
||||
get_output_target_store,
|
||||
get_pattern_template_store,
|
||||
get_picture_source_store,
|
||||
@@ -311,3 +313,52 @@ def list_api_keys(_: AuthRequired):
|
||||
for label, key in config.auth.api_keys.items()
|
||||
]
|
||||
return {"keys": keys, "count": len(keys)}
|
||||
|
||||
|
||||
@router.get("/api/v1/system/integrations-status", tags=["System"])
|
||||
async def get_integrations_status(
|
||||
_: AuthRequired,
|
||||
ha_store=Depends(get_ha_store),
|
||||
ha_manager=Depends(get_ha_manager),
|
||||
):
|
||||
"""Return connection status for external integrations (MQTT, Home Assistant).
|
||||
|
||||
Used by the dashboard to show connectivity indicators.
|
||||
"""
|
||||
from wled_controller.core.devices.mqtt_client import get_mqtt_service
|
||||
|
||||
# MQTT status
|
||||
mqtt_service = get_mqtt_service()
|
||||
mqtt_config = get_config().mqtt
|
||||
mqtt_status = {
|
||||
"enabled": mqtt_config.enabled,
|
||||
"connected": mqtt_service.is_connected if mqtt_service else False,
|
||||
"broker": (
|
||||
f"{mqtt_config.broker_host}:{mqtt_config.broker_port}" if mqtt_config.enabled else None
|
||||
),
|
||||
}
|
||||
|
||||
# Home Assistant status
|
||||
ha_sources = ha_store.get_all_sources()
|
||||
ha_connections = ha_manager.get_connection_status()
|
||||
ha_status_map = {s["source_id"]: s for s in ha_connections}
|
||||
ha_items = []
|
||||
for source in ha_sources:
|
||||
status = ha_status_map.get(source.id)
|
||||
ha_items.append(
|
||||
{
|
||||
"source_id": source.id,
|
||||
"name": source.name,
|
||||
"connected": status["connected"] if status else False,
|
||||
"entity_count": status["entity_count"] if status else 0,
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"mqtt": mqtt_status,
|
||||
"home_assistant": {
|
||||
"sources": ha_items,
|
||||
"total": len(ha_sources),
|
||||
"connected": sum(1 for s in ha_items if s["connected"]),
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user