From 94cdede3b93f136220eef2a9c429dd7803594ad6 Mon Sep 17 00:00:00 2001 From: thekiwismarthome Date: Tue, 17 Feb 2026 18:57:40 +1300 Subject: [PATCH] non-admin event handler --- .../shopping_list_manager/__init__.py | 4 ++ .../shopping_list_manager/const.py | 1 + .../websocket/handlers.py | 39 +++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/custom_components/shopping_list_manager/__init__.py b/custom_components/shopping_list_manager/__init__.py index 0372c3c..50c45c0 100644 --- a/custom_components/shopping_list_manager/__init__.py +++ b/custom_components/shopping_list_manager/__init__.py @@ -103,6 +103,10 @@ async def _async_register_websocket_handlers( from .websocket import handlers # Lists handlers + websocket_api.async_register_command( + hass, + handlers.websocket_subscribe, + ) websocket_api.async_register_command( hass, handlers.websocket_get_lists, diff --git a/custom_components/shopping_list_manager/const.py b/custom_components/shopping_list_manager/const.py index 8b1dbac..29b4d3f 100644 --- a/custom_components/shopping_list_manager/const.py +++ b/custom_components/shopping_list_manager/const.py @@ -57,6 +57,7 @@ EVENT_ITEM_UPDATED = f"{DOMAIN}_item_updated" EVENT_ITEM_CHECKED = f"{DOMAIN}_item_checked" EVENT_ITEM_DELETED = f"{DOMAIN}_item_deleted" EVENT_LIST_UPDATED = f"{DOMAIN}_list_updated" +EVENT_LIST_DELETED = f"{DOMAIN}_list_deleted" # Image Configuration IMAGE_FORMAT = "webp" diff --git a/custom_components/shopping_list_manager/websocket/handlers.py b/custom_components/shopping_list_manager/websocket/handlers.py index b36a4a1..37ff8e7 100644 --- a/custom_components/shopping_list_manager/websocket/handlers.py +++ b/custom_components/shopping_list_manager/websocket/handlers.py @@ -28,6 +28,7 @@ from ..const import ( WS_TYPE_PRODUCTS_ADD, WS_TYPE_PRODUCTS_UPDATE, WS_TYPE_CATEGORIES_GET_ALL, + WS_TYPE_SUBSCRIBE, EVENT_ITEM_ADDED, EVENT_ITEM_UPDATED, EVENT_ITEM_CHECKED, @@ -44,6 +45,44 @@ _LOGGER = logging.getLogger(__name__) # LIST HANDLERS # ============================================================================= +@websocket_api.websocket_command({ + vol.Required("type"): WS_TYPE_SUBSCRIBE, +}) +@websocket_api.async_response +async def websocket_subscribe( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: dict, +) -> None: + """Subscribe to shopping list manager events via WebSocket.""" + + @callback + def forward_event(event): + """Forward HA bus event to WebSocket connection.""" + connection.send_message( + websocket_api.event_message( + msg["id"], + { + "event_type": event.event_type, + "data": event.data, + } + ) + ) + + # Subscribe to all SLM events on the HA bus (backend has permission) + unsubs = [] + unsubs.append(hass.bus.async_listen(EVENT_ITEM_ADDED, forward_event)) + unsubs.append(hass.bus.async_listen(EVENT_ITEM_UPDATED, forward_event)) + unsubs.append(hass.bus.async_listen(EVENT_ITEM_CHECKED, forward_event)) + unsubs.append(hass.bus.async_listen(EVENT_ITEM_DELETED, forward_event)) + unsubs.append(hass.bus.async_listen(EVENT_LIST_UPDATED, forward_event)) + unsubs.append(hass.bus.async_listen(EVENT_LIST_DELETED, forward_event)) + + # Clean up when connection closes + connection.subscriptions[msg["id"]] = lambda: [unsub() for unsub in unsubs] + + connection.send_message(websocket_api.result_message(msg["id"])) + @websocket_api.websocket_command({ vol.Required("type"): "shopping_list_manager/items/increment", vol.Required("item_id"): str,