mirror of
https://github.com/home-assistant/core.git
synced 2025-12-24 12:59:34 +00:00
Mark camera unavailable when keepalive stream fails (#62294)
* Mark camera unavailable when keepalive stream fails Add a listener in stream that notifies camera when the stream state has changed, and use that to inform the camera `available` property. Update the property to be set only from the main loop where it is read to reduce thread safety races. Issue #54659 * Fix pylint import related errors * Address lint naming errors * Apply suggestions from code review Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io> Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
@@ -16,7 +16,11 @@ from homeassistant.components.camera.const import (
|
||||
from homeassistant.components.camera.prefs import CameraEntityPreferences
|
||||
from homeassistant.components.websocket_api.const import TYPE_RESULT
|
||||
from homeassistant.config import async_process_ha_core_config
|
||||
from homeassistant.const import ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_START
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
EVENT_HOMEASSISTANT_START,
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
@@ -633,3 +637,56 @@ async def test_websocket_web_rtc_offer_invalid_stream_type(
|
||||
assert response["type"] == TYPE_RESULT
|
||||
assert not response["success"]
|
||||
assert response["error"]["code"] == "web_rtc_offer_failed"
|
||||
|
||||
|
||||
async def test_state_streaming(hass, hass_ws_client, mock_camera):
|
||||
"""Camera state."""
|
||||
demo_camera = hass.states.get("camera.demo_camera")
|
||||
assert demo_camera is not None
|
||||
assert demo_camera.state == camera.STATE_STREAMING
|
||||
|
||||
|
||||
async def test_stream_unavailable(hass, hass_ws_client, mock_camera, mock_stream):
|
||||
"""Camera state."""
|
||||
await async_setup_component(hass, "camera", {})
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.camera.Stream.endpoint_url",
|
||||
return_value="http://home.assistant/playlist.m3u8",
|
||||
), patch(
|
||||
"homeassistant.components.demo.camera.DemoCamera.stream_source",
|
||||
return_value="http://example.com",
|
||||
), patch(
|
||||
"homeassistant.components.camera.Stream.set_update_callback",
|
||||
) as mock_update_callback:
|
||||
# Request playlist through WebSocket. We just want to create the stream
|
||||
# but don't care about the result.
|
||||
client = await hass_ws_client(hass)
|
||||
await client.send_json(
|
||||
{"id": 10, "type": "camera/stream", "entity_id": "camera.demo_camera"}
|
||||
)
|
||||
await client.receive_json()
|
||||
assert mock_update_callback.called
|
||||
|
||||
# Simluate the stream going unavailable
|
||||
callback = mock_update_callback.call_args.args[0]
|
||||
with patch(
|
||||
"homeassistant.components.camera.Stream.available", new_callable=lambda: False
|
||||
):
|
||||
callback()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
demo_camera = hass.states.get("camera.demo_camera")
|
||||
assert demo_camera is not None
|
||||
assert demo_camera.state == STATE_UNAVAILABLE
|
||||
|
||||
# Simulate stream becomes available
|
||||
with patch(
|
||||
"homeassistant.components.camera.Stream.available", new_callable=lambda: True
|
||||
):
|
||||
callback()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
demo_camera = hass.states.get("camera.demo_camera")
|
||||
assert demo_camera is not None
|
||||
assert demo_camera.state == camera.STATE_STREAMING
|
||||
|
||||
Reference in New Issue
Block a user