diff --git a/homeassistant/components/logbook/websocket_api.py b/homeassistant/components/logbook/websocket_api.py index 8d0dd49bff8..04b288d523b 100644 --- a/homeassistant/components/logbook/websocket_api.py +++ b/homeassistant/components/logbook/websocket_api.py @@ -83,6 +83,7 @@ async def _async_send_historical_events( formatter: Callable[[int, Any], dict[str, Any]], event_processor: EventProcessor, partial: bool, + force_send: bool = False, ) -> dt | None: """Select historical data from the database and deliver it to the websocket. @@ -116,7 +117,7 @@ async def _async_send_historical_events( # if its the last one (not partial) so # consumers of the api know their request was # answered but there were no results - if last_event_time or not partial: + if last_event_time or not partial or force_send: connection.send_message(message) return last_event_time @@ -150,7 +151,7 @@ async def _async_send_historical_events( # if its the last one (not partial) so # consumers of the api know their request was # answered but there were no results - if older_query_last_event_time or not partial: + if older_query_last_event_time or not partial or force_send: connection.send_message(older_message) # Returns the time of the newest event @@ -384,6 +385,11 @@ async def ws_event_stream( messages.event_message, event_processor, partial=True, + # Force a send since the wait for the sync task + # can take a a while if the recorder is busy and + # we want to make sure the client is not still spinning + # because it is waiting for the first message + force_send=True, ) live_stream.task = asyncio.create_task( diff --git a/tests/components/logbook/test_websocket_api.py b/tests/components/logbook/test_websocket_api.py index 5b16c98998c..91d1a95f75b 100644 --- a/tests/components/logbook/test_websocket_api.py +++ b/tests/components/logbook/test_websocket_api.py @@ -1817,6 +1817,7 @@ async def test_subscribe_unsubscribe_logbook_stream_device( assert msg["id"] == 7 assert msg["type"] == TYPE_RESULT assert msg["success"] + await async_wait_recording_done(hass) # There are no answers to our initial query # so we get an empty reply. This is to ensure @@ -1828,6 +1829,15 @@ async def test_subscribe_unsubscribe_logbook_stream_device( assert msg["id"] == 7 assert msg["type"] == "event" assert msg["event"]["events"] == [] + assert "partial" in msg["event"] + await async_wait_recording_done(hass) + + msg = await asyncio.wait_for(websocket_client.receive_json(), 2) + assert msg["id"] == 7 + assert msg["type"] == "event" + assert msg["event"]["events"] == [] + assert "partial" not in msg["event"] + await async_wait_recording_done(hass) hass.states.async_set("binary_sensor.should_not_appear", STATE_ON) hass.states.async_set("binary_sensor.should_not_appear", STATE_OFF) @@ -1942,6 +1952,14 @@ async def test_logbook_stream_match_multiple_entities( assert msg["id"] == 7 assert msg["type"] == "event" assert msg["event"]["events"] == [] + assert "partial" in msg["event"] + await async_wait_recording_done(hass) + + msg = await asyncio.wait_for(websocket_client.receive_json(), 2) + assert msg["id"] == 7 + assert msg["type"] == "event" + assert msg["event"]["events"] == [] + assert "partial" not in msg["event"] await async_wait_recording_done(hass) hass.states.async_set("binary_sensor.should_not_appear", STATE_ON)