Allow camera stream to fail safely (#50728)
This commit is contained in:
parent
1f80defe3a
commit
2e1037005c
2 changed files with 28 additions and 4 deletions
|
@ -160,7 +160,7 @@ async def async_get_stream_source(hass: HomeAssistant, entity_id: str) -> str |
|
||||||
@bind_hass
|
@bind_hass
|
||||||
async def async_get_mjpeg_stream(
|
async def async_get_mjpeg_stream(
|
||||||
hass: HomeAssistant, request: web.Request, entity_id: str
|
hass: HomeAssistant, request: web.Request, entity_id: str
|
||||||
) -> web.StreamResponse:
|
) -> web.StreamResponse | None:
|
||||||
"""Fetch an mjpeg stream from a camera entity."""
|
"""Fetch an mjpeg stream from a camera entity."""
|
||||||
camera = _get_camera_from_entity_id(hass, entity_id)
|
camera = _get_camera_from_entity_id(hass, entity_id)
|
||||||
|
|
||||||
|
@ -399,7 +399,7 @@ class Camera(Entity):
|
||||||
|
|
||||||
async def handle_async_mjpeg_stream(
|
async def handle_async_mjpeg_stream(
|
||||||
self, request: web.Request
|
self, request: web.Request
|
||||||
) -> web.StreamResponse:
|
) -> web.StreamResponse | None:
|
||||||
"""Serve an HTTP MJPEG stream from the camera.
|
"""Serve an HTTP MJPEG stream from the camera.
|
||||||
|
|
||||||
This method can be overridden by camera platforms to proxy
|
This method can be overridden by camera platforms to proxy
|
||||||
|
@ -543,7 +543,10 @@ class CameraMjpegStream(CameraView):
|
||||||
"""Serve camera stream, possibly with interval."""
|
"""Serve camera stream, possibly with interval."""
|
||||||
interval_str = request.query.get("interval")
|
interval_str = request.query.get("interval")
|
||||||
if interval_str is None:
|
if interval_str is None:
|
||||||
return await camera.handle_async_mjpeg_stream(request)
|
stream = await camera.handle_async_mjpeg_stream(request)
|
||||||
|
if stream is None:
|
||||||
|
raise web.HTTPBadGateway()
|
||||||
|
return stream
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Compose camera stream from stills
|
# Compose camera stream from stills
|
||||||
|
|
|
@ -11,7 +11,12 @@ from homeassistant.components.camera.const import DOMAIN, PREF_PRELOAD_STREAM
|
||||||
from homeassistant.components.camera.prefs import CameraEntityPreferences
|
from homeassistant.components.camera.prefs import CameraEntityPreferences
|
||||||
from homeassistant.components.websocket_api.const import TYPE_RESULT
|
from homeassistant.components.websocket_api.const import TYPE_RESULT
|
||||||
from homeassistant.config import async_process_ha_core_config
|
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,
|
||||||
|
HTTP_BAD_GATEWAY,
|
||||||
|
HTTP_OK,
|
||||||
|
)
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
@ -354,3 +359,19 @@ async def test_record_service(hass, mock_camera, mock_stream):
|
||||||
# So long as we call stream.record, the rest should be covered
|
# So long as we call stream.record, the rest should be covered
|
||||||
# by those tests.
|
# by those tests.
|
||||||
assert mock_record.called
|
assert mock_record.called
|
||||||
|
|
||||||
|
|
||||||
|
async def test_camera_proxy_stream(hass, mock_camera, hass_client):
|
||||||
|
"""Test record service."""
|
||||||
|
|
||||||
|
client = await hass_client()
|
||||||
|
|
||||||
|
response = await client.get("/api/camera_proxy_stream/camera.demo_camera")
|
||||||
|
assert response.status == HTTP_OK
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.demo.camera.DemoCamera.handle_async_mjpeg_stream",
|
||||||
|
return_value=None,
|
||||||
|
):
|
||||||
|
response = await client.get("/api/camera_proxy_stream/camera.demo_camera")
|
||||||
|
assert response.status == HTTP_BAD_GATEWAY
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue