mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Call async_refresh_providers when camera entity feature changes (#129941)
This commit is contained in:
parent
9f427893b1
commit
fe0a822721
@ -472,6 +472,8 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
_attr_state: None = None # State is determined by is_on
|
_attr_state: None = None # State is determined by is_on
|
||||||
_attr_supported_features: CameraEntityFeature = CameraEntityFeature(0)
|
_attr_supported_features: CameraEntityFeature = CameraEntityFeature(0)
|
||||||
|
|
||||||
|
__supports_stream: CameraEntityFeature | None = None
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""Initialize a camera."""
|
"""Initialize a camera."""
|
||||||
self._cache: dict[str, Any] = {}
|
self._cache: dict[str, Any] = {}
|
||||||
@ -783,6 +785,9 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
async def async_internal_added_to_hass(self) -> None:
|
async def async_internal_added_to_hass(self) -> None:
|
||||||
"""Run when entity about to be added to hass."""
|
"""Run when entity about to be added to hass."""
|
||||||
await super().async_internal_added_to_hass()
|
await super().async_internal_added_to_hass()
|
||||||
|
self.__supports_stream = (
|
||||||
|
self.supported_features_compat & CameraEntityFeature.STREAM
|
||||||
|
)
|
||||||
await self.async_refresh_providers(write_state=False)
|
await self.async_refresh_providers(write_state=False)
|
||||||
|
|
||||||
async def async_refresh_providers(self, *, write_state: bool = True) -> None:
|
async def async_refresh_providers(self, *, write_state: bool = True) -> None:
|
||||||
@ -892,6 +897,21 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
|
|
||||||
return CameraCapabilities(frontend_stream_types)
|
return CameraCapabilities(frontend_stream_types)
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def async_write_ha_state(self) -> None:
|
||||||
|
"""Write the state to the state machine.
|
||||||
|
|
||||||
|
Schedules async_refresh_providers if support of streams have changed.
|
||||||
|
"""
|
||||||
|
super().async_write_ha_state()
|
||||||
|
if self.__supports_stream != (
|
||||||
|
supports_stream := self.supported_features_compat
|
||||||
|
& CameraEntityFeature.STREAM
|
||||||
|
):
|
||||||
|
self.__supports_stream = supports_stream
|
||||||
|
self._invalidate_camera_capabilities_cache()
|
||||||
|
self.hass.async_create_task(self.async_refresh_providers())
|
||||||
|
|
||||||
|
|
||||||
class CameraView(HomeAssistantView):
|
class CameraView(HomeAssistantView):
|
||||||
"""Base CameraView."""
|
"""Base CameraView."""
|
||||||
|
@ -157,7 +157,7 @@ def mock_stream_source_fixture() -> Generator[AsyncMock]:
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def mock_test_webrtc_cameras(hass: HomeAssistant) -> None:
|
async def mock_test_webrtc_cameras(hass: HomeAssistant) -> None:
|
||||||
"""Initialize a test WebRTC cameras."""
|
"""Initialize test WebRTC cameras with native RTC support."""
|
||||||
|
|
||||||
# Cannot use the fixture mock_camera_web_rtc as it's mocking Camera.async_handle_web_rtc_offer
|
# Cannot use the fixture mock_camera_web_rtc as it's mocking Camera.async_handle_web_rtc_offer
|
||||||
# and native support is checked by verify the function "async_handle_web_rtc_offer" was
|
# and native support is checked by verify the function "async_handle_web_rtc_offer" was
|
||||||
|
@ -1005,3 +1005,52 @@ async def test_webrtc_provider_not_added_for_native_webrtc(
|
|||||||
assert camera_obj._webrtc_provider is None
|
assert camera_obj._webrtc_provider is None
|
||||||
assert camera_obj._supports_native_sync_webrtc is not expect_native_async_webrtc
|
assert camera_obj._supports_native_sync_webrtc is not expect_native_async_webrtc
|
||||||
assert camera_obj._supports_native_async_webrtc is expect_native_async_webrtc
|
assert camera_obj._supports_native_async_webrtc is expect_native_async_webrtc
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("mock_camera", "mock_stream_source")
|
||||||
|
async def test_camera_capabilities_changing_non_native_support(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
hass_ws_client: WebSocketGenerator,
|
||||||
|
) -> None:
|
||||||
|
"""Test WebRTC camera capabilities."""
|
||||||
|
cam = get_camera_from_entity_id(hass, "camera.demo_camera")
|
||||||
|
assert (
|
||||||
|
cam.supported_features
|
||||||
|
== camera.CameraEntityFeature.ON_OFF | camera.CameraEntityFeature.STREAM
|
||||||
|
)
|
||||||
|
|
||||||
|
await _test_capabilities(
|
||||||
|
hass,
|
||||||
|
hass_ws_client,
|
||||||
|
cam.entity_id,
|
||||||
|
{StreamType.HLS},
|
||||||
|
{StreamType.HLS, StreamType.WEB_RTC},
|
||||||
|
)
|
||||||
|
|
||||||
|
cam._attr_supported_features = camera.CameraEntityFeature(0)
|
||||||
|
cam.async_write_ha_state()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
await _test_capabilities(hass, hass_ws_client, cam.entity_id, set(), set())
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("mock_test_webrtc_cameras")
|
||||||
|
@pytest.mark.parametrize(("entity_id"), ["camera.sync", "camera.async"])
|
||||||
|
async def test_camera_capabilities_changing_native_support(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
hass_ws_client: WebSocketGenerator,
|
||||||
|
entity_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test WebRTC camera capabilities."""
|
||||||
|
cam = get_camera_from_entity_id(hass, entity_id)
|
||||||
|
assert cam.supported_features == camera.CameraEntityFeature.STREAM
|
||||||
|
|
||||||
|
await _test_capabilities(
|
||||||
|
hass, hass_ws_client, cam.entity_id, {StreamType.WEB_RTC}, {StreamType.WEB_RTC}
|
||||||
|
)
|
||||||
|
|
||||||
|
cam._attr_supported_features = camera.CameraEntityFeature(0)
|
||||||
|
cam.async_write_ha_state()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
await _test_capabilities(hass, hass_ws_client, cam.entity_id, set(), set())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user