diff --git a/custom_components/remote_media_player/api_client.py b/custom_components/remote_media_player/api_client.py index 01cb88d..6734acd 100644 --- a/custom_components/remote_media_player/api_client.py +++ b/custom_components/remote_media_player/api_client.py @@ -307,6 +307,7 @@ class MediaServerWebSocket: token: str, on_status_update: Callable[[dict[str, Any]], None], on_disconnect: Callable[[], None] | None = None, + on_scripts_changed: Callable[[], None] | None = None, ) -> None: """Initialize the WebSocket client. @@ -316,12 +317,14 @@ class MediaServerWebSocket: token: API authentication token on_status_update: Callback when status update received on_disconnect: Callback when connection lost + on_scripts_changed: Callback when scripts have changed """ self._host = host self._port = int(port) self._token = token self._on_status_update = on_status_update self._on_disconnect = on_disconnect + self._on_scripts_changed = on_scripts_changed self._ws_url = f"ws://{host}:{self._port}/api/media/ws?token={token}" self._session: aiohttp.ClientSession | None = None self._ws: aiohttp.ClientWebSocketResponse | None = None @@ -401,6 +404,10 @@ class MediaServerWebSocket: f"{status_data['album_art_url']}?token={self._token}&t={track_hash}" ) self._on_status_update(status_data) + elif msg_type == "scripts_changed": + _LOGGER.info("Scripts changed notification received") + if self._on_scripts_changed: + self._on_scripts_changed() elif msg_type == "pong": _LOGGER.debug("Received pong") diff --git a/custom_components/remote_media_player/media_player.py b/custom_components/remote_media_player/media_player.py index 350f15b..28a0f0b 100644 --- a/custom_components/remote_media_player/media_player.py +++ b/custom_components/remote_media_player/media_player.py @@ -82,6 +82,7 @@ async def async_setup_entry( port=entry.data[CONF_PORT], token=entry.data[CONF_TOKEN], use_websocket=use_websocket, + entry=entry, ) # Set up WebSocket connection if enabled @@ -118,6 +119,7 @@ class MediaPlayerCoordinator(DataUpdateCoordinator[dict[str, Any]]): port: int, token: str, use_websocket: bool = True, + entry: ConfigEntry | None = None, ) -> None: """Initialize the coordinator. @@ -129,6 +131,7 @@ class MediaPlayerCoordinator(DataUpdateCoordinator[dict[str, Any]]): port: Server port token: API token use_websocket: Whether to use WebSocket for updates + entry: Config entry (for integration reload on scripts change) """ super().__init__( hass, @@ -141,6 +144,7 @@ class MediaPlayerCoordinator(DataUpdateCoordinator[dict[str, Any]]): self._port = port self._token = token self._use_websocket = use_websocket + self._entry = entry self._ws_client: MediaServerWebSocket | None = None self._ws_connected = False self._reconnect_task: asyncio.Task | None = None @@ -162,6 +166,7 @@ class MediaPlayerCoordinator(DataUpdateCoordinator[dict[str, Any]]): token=self._token, on_status_update=self._handle_ws_status_update, on_disconnect=self._handle_ws_disconnect, + on_scripts_changed=self._handle_ws_scripts_changed, ) if await self._ws_client.connect(): @@ -192,6 +197,17 @@ class MediaPlayerCoordinator(DataUpdateCoordinator[dict[str, Any]]): # Schedule reconnect attempt self._schedule_reconnect() + @callback + def _handle_ws_scripts_changed(self) -> None: + """Handle scripts changed notification from WebSocket.""" + if self._entry: + _LOGGER.info("Scripts changed, reloading integration") + self.hass.async_create_task( + self.hass.config_entries.async_reload(self._entry.entry_id) + ) + else: + _LOGGER.warning("Cannot reload integration: entry not available") + def _schedule_reconnect(self) -> None: """Schedule a WebSocket reconnection attempt.""" if self._reconnect_task and not self._reconnect_task.done():