mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 16:27:08 +00:00
Remove deprecated legacy WebRTC provider (#144547)
This commit is contained in:
parent
a93bf3c150
commit
1f84c5e1f1
@ -85,7 +85,6 @@ from .img_util import scale_jpeg_camera_image
|
||||
from .prefs import CameraPreferences, DynamicStreamSettings # noqa: F401
|
||||
from .webrtc import (
|
||||
DATA_ICE_SERVERS,
|
||||
CameraWebRTCLegacyProvider,
|
||||
CameraWebRTCProvider,
|
||||
WebRTCAnswer,
|
||||
WebRTCCandidate, # noqa: F401
|
||||
@ -93,10 +92,8 @@ from .webrtc import (
|
||||
WebRTCError,
|
||||
WebRTCMessage, # noqa: F401
|
||||
WebRTCSendMessage,
|
||||
async_get_supported_legacy_provider,
|
||||
async_get_supported_provider,
|
||||
async_register_ice_servers,
|
||||
async_register_rtsp_to_web_rtc_provider, # noqa: F401
|
||||
async_register_webrtc_provider, # noqa: F401
|
||||
async_register_ws,
|
||||
)
|
||||
@ -476,7 +473,6 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
self.async_update_token()
|
||||
self._create_stream_lock: asyncio.Lock | None = None
|
||||
self._webrtc_provider: CameraWebRTCProvider | None = None
|
||||
self._legacy_webrtc_provider: CameraWebRTCLegacyProvider | None = None
|
||||
self._supports_native_sync_webrtc = (
|
||||
type(self).async_handle_web_rtc_offer != Camera.async_handle_web_rtc_offer
|
||||
)
|
||||
@ -646,14 +642,7 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
)
|
||||
return
|
||||
|
||||
if self._legacy_webrtc_provider and (
|
||||
answer := await self._legacy_webrtc_provider.async_handle_web_rtc_offer(
|
||||
self, offer_sdp
|
||||
)
|
||||
):
|
||||
send_message(WebRTCAnswer(answer))
|
||||
else:
|
||||
raise HomeAssistantError("Camera does not support WebRTC")
|
||||
raise HomeAssistantError("Camera does not support WebRTC")
|
||||
|
||||
def camera_image(
|
||||
self, width: int | None = None, height: int | None = None
|
||||
@ -772,9 +761,7 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
providers or inputs to the state attributes change.
|
||||
"""
|
||||
old_provider = self._webrtc_provider
|
||||
old_legacy_provider = self._legacy_webrtc_provider
|
||||
new_provider = None
|
||||
new_legacy_provider = None
|
||||
|
||||
# Skip all providers if the camera has a native WebRTC implementation
|
||||
if not (
|
||||
@ -785,15 +772,8 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
async_get_supported_provider
|
||||
)
|
||||
|
||||
if new_provider is None:
|
||||
# Only add the legacy provider if the new provider is not available
|
||||
new_legacy_provider = await self._async_get_supported_webrtc_provider(
|
||||
async_get_supported_legacy_provider
|
||||
)
|
||||
|
||||
if old_provider != new_provider or old_legacy_provider != new_legacy_provider:
|
||||
if old_provider != new_provider:
|
||||
self._webrtc_provider = new_provider
|
||||
self._legacy_webrtc_provider = new_legacy_provider
|
||||
self._invalidate_camera_capabilities_cache()
|
||||
if write_state:
|
||||
self.async_write_ha_state()
|
||||
@ -828,10 +808,7 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
]
|
||||
config.configuration.ice_servers.extend(ice_servers)
|
||||
|
||||
config.get_candidates_upfront = (
|
||||
self._supports_native_sync_webrtc
|
||||
or self._legacy_webrtc_provider is not None
|
||||
)
|
||||
config.get_candidates_upfront = self._supports_native_sync_webrtc
|
||||
|
||||
return config
|
||||
|
||||
@ -867,7 +844,7 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||
else:
|
||||
frontend_stream_types.add(StreamType.HLS)
|
||||
|
||||
if self._webrtc_provider or self._legacy_webrtc_provider:
|
||||
if self._webrtc_provider:
|
||||
frontend_stream_types.add(StreamType.WEB_RTC)
|
||||
|
||||
return CameraCapabilities(frontend_stream_types)
|
||||
|
@ -46,10 +46,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"legacy_webrtc_provider": {
|
||||
"title": "Detected use of legacy WebRTC provider registered by {legacy_integration}",
|
||||
"description": "The {legacy_integration} integration has registered a legacy WebRTC provider. Home Assistant prefers using the built-in modern WebRTC provider registered by the {builtin_integration} integration.\n\nBenefits of the built-in integration are:\n\n- The camera stream is started faster.\n- More camera devices are supported.\n\nTo fix this issue, you can either keep using the built-in modern WebRTC provider and remove the {legacy_integration} integration or remove the {builtin_integration} integration to use the legacy provider, and then restart Home Assistant."
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
|
@ -8,7 +8,7 @@ from collections.abc import Awaitable, Callable, Iterable
|
||||
from dataclasses import asdict, dataclass, field
|
||||
from functools import cache, partial, wraps
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Any, Protocol
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from mashumaro import MissingField
|
||||
import voluptuous as vol
|
||||
@ -22,8 +22,7 @@ from webrtc_models import (
|
||||
from homeassistant.components import websocket_api
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import config_validation as cv, issue_registry as ir
|
||||
from homeassistant.helpers.deprecation import deprecated_function
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.util.hass_dict import HassKey
|
||||
from homeassistant.util.ulid import ulid
|
||||
|
||||
@ -39,9 +38,6 @@ _LOGGER = logging.getLogger(__name__)
|
||||
DATA_WEBRTC_PROVIDERS: HassKey[set[CameraWebRTCProvider]] = HassKey(
|
||||
"camera_webrtc_providers"
|
||||
)
|
||||
DATA_WEBRTC_LEGACY_PROVIDERS: HassKey[dict[str, CameraWebRTCLegacyProvider]] = HassKey(
|
||||
"camera_webrtc_legacy_providers"
|
||||
)
|
||||
DATA_ICE_SERVERS: HassKey[list[Callable[[], Iterable[RTCIceServer]]]] = HassKey(
|
||||
"camera_webrtc_ice_servers"
|
||||
)
|
||||
@ -163,18 +159,6 @@ class CameraWebRTCProvider(ABC):
|
||||
return ## This is an optional method so we need a default here.
|
||||
|
||||
|
||||
class CameraWebRTCLegacyProvider(Protocol):
|
||||
"""WebRTC provider."""
|
||||
|
||||
async def async_is_supported(self, stream_source: str) -> bool:
|
||||
"""Determine if the provider supports the stream source."""
|
||||
|
||||
async def async_handle_web_rtc_offer(
|
||||
self, camera: Camera, offer_sdp: str
|
||||
) -> str | None:
|
||||
"""Handle the WebRTC offer and return an answer."""
|
||||
|
||||
|
||||
@callback
|
||||
def async_register_webrtc_provider(
|
||||
hass: HomeAssistant,
|
||||
@ -204,8 +188,6 @@ def async_register_webrtc_provider(
|
||||
|
||||
async def _async_refresh_providers(hass: HomeAssistant) -> None:
|
||||
"""Check all cameras for any state changes for registered providers."""
|
||||
_async_check_conflicting_legacy_provider(hass)
|
||||
|
||||
component = hass.data[DATA_COMPONENT]
|
||||
await asyncio.gather(
|
||||
*(camera.async_refresh_providers() for camera in component.entities)
|
||||
@ -380,21 +362,6 @@ async def async_get_supported_provider(
|
||||
return None
|
||||
|
||||
|
||||
async def async_get_supported_legacy_provider(
|
||||
hass: HomeAssistant, camera: Camera
|
||||
) -> CameraWebRTCLegacyProvider | None:
|
||||
"""Return the first supported provider for the camera."""
|
||||
providers = hass.data.get(DATA_WEBRTC_LEGACY_PROVIDERS)
|
||||
if not providers or not (stream_source := await camera.stream_source()):
|
||||
return None
|
||||
|
||||
for provider in providers.values():
|
||||
if await provider.async_is_supported(stream_source):
|
||||
return provider
|
||||
|
||||
return None
|
||||
|
||||
|
||||
@callback
|
||||
def async_register_ice_servers(
|
||||
hass: HomeAssistant,
|
||||
@ -411,94 +378,3 @@ def async_register_ice_servers(
|
||||
|
||||
servers.append(get_ice_server_fn)
|
||||
return remove
|
||||
|
||||
|
||||
# The following code is legacy code that was introduced with rtsp_to_webrtc and will be deprecated/removed in the future.
|
||||
# Left it so custom integrations can still use it.
|
||||
|
||||
_RTSP_PREFIXES = {"rtsp://", "rtsps://", "rtmp://"}
|
||||
|
||||
# An RtspToWebRtcProvider accepts these inputs:
|
||||
# stream_source: The RTSP url
|
||||
# offer_sdp: The WebRTC SDP offer
|
||||
# stream_id: A unique id for the stream, used to update an existing source
|
||||
# The output is the SDP answer, or None if the source or offer is not eligible.
|
||||
# The Callable may throw HomeAssistantError on failure.
|
||||
type RtspToWebRtcProviderType = Callable[[str, str, str], Awaitable[str | None]]
|
||||
|
||||
|
||||
class _CameraRtspToWebRTCProvider(CameraWebRTCLegacyProvider):
|
||||
def __init__(self, fn: RtspToWebRtcProviderType) -> None:
|
||||
"""Initialize the RTSP to WebRTC provider."""
|
||||
self._fn = fn
|
||||
|
||||
async def async_is_supported(self, stream_source: str) -> bool:
|
||||
"""Return if this provider is supports the Camera as source."""
|
||||
return any(stream_source.startswith(prefix) for prefix in _RTSP_PREFIXES)
|
||||
|
||||
async def async_handle_web_rtc_offer(
|
||||
self, camera: Camera, offer_sdp: str
|
||||
) -> str | None:
|
||||
"""Handle the WebRTC offer and return an answer."""
|
||||
if not (stream_source := await camera.stream_source()):
|
||||
return None
|
||||
|
||||
return await self._fn(stream_source, offer_sdp, camera.entity_id)
|
||||
|
||||
|
||||
@deprecated_function("async_register_webrtc_provider", breaks_in_ha_version="2025.6")
|
||||
def async_register_rtsp_to_web_rtc_provider(
|
||||
hass: HomeAssistant,
|
||||
domain: str,
|
||||
provider: RtspToWebRtcProviderType,
|
||||
) -> Callable[[], None]:
|
||||
"""Register an RTSP to WebRTC provider.
|
||||
|
||||
The first provider to satisfy the offer will be used.
|
||||
"""
|
||||
if DOMAIN not in hass.data:
|
||||
raise ValueError("Unexpected state, camera not loaded")
|
||||
|
||||
legacy_providers = hass.data.setdefault(DATA_WEBRTC_LEGACY_PROVIDERS, {})
|
||||
|
||||
if domain in legacy_providers:
|
||||
raise ValueError("Provider already registered")
|
||||
|
||||
provider_instance = _CameraRtspToWebRTCProvider(provider)
|
||||
|
||||
@callback
|
||||
def remove_provider() -> None:
|
||||
legacy_providers.pop(domain)
|
||||
hass.async_create_task(_async_refresh_providers(hass))
|
||||
|
||||
legacy_providers[domain] = provider_instance
|
||||
hass.async_create_task(_async_refresh_providers(hass))
|
||||
|
||||
return remove_provider
|
||||
|
||||
|
||||
@callback
|
||||
def _async_check_conflicting_legacy_provider(hass: HomeAssistant) -> None:
|
||||
"""Check if a legacy provider is registered together with the builtin provider."""
|
||||
builtin_provider_domain = "go2rtc"
|
||||
if (
|
||||
(legacy_providers := hass.data.get(DATA_WEBRTC_LEGACY_PROVIDERS))
|
||||
and (providers := hass.data.get(DATA_WEBRTC_PROVIDERS))
|
||||
and any(provider.domain == builtin_provider_domain for provider in providers)
|
||||
):
|
||||
for domain in legacy_providers:
|
||||
ir.async_create_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
f"legacy_webrtc_provider_{domain}",
|
||||
is_fixable=False,
|
||||
is_persistent=False,
|
||||
issue_domain=domain,
|
||||
learn_more_url="https://www.home-assistant.io/integrations/go2rtc/",
|
||||
severity=ir.IssueSeverity.WARNING,
|
||||
translation_key="legacy_webrtc_provider",
|
||||
translation_placeholders={
|
||||
"legacy_integration": domain,
|
||||
"builtin_integration": builtin_provider_domain,
|
||||
},
|
||||
)
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""Test camera WebRTC."""
|
||||
|
||||
from collections.abc import AsyncGenerator, Generator
|
||||
from collections.abc import AsyncGenerator
|
||||
import logging
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
@ -20,9 +20,7 @@ from homeassistant.components.camera import (
|
||||
WebRTCError,
|
||||
WebRTCMessage,
|
||||
WebRTCSendMessage,
|
||||
async_get_supported_legacy_provider,
|
||||
async_register_ice_servers,
|
||||
async_register_rtsp_to_web_rtc_provider,
|
||||
async_register_webrtc_provider,
|
||||
get_camera_from_entity_id,
|
||||
)
|
||||
@ -31,7 +29,6 @@ from homeassistant.config_entries import ConfigEntry, ConfigFlow
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.core_config import async_process_ha_core_config
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import issue_registry as ir
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from .common import STREAM_SOURCE, WEBRTC_ANSWER, SomeTestProvider
|
||||
@ -427,21 +424,6 @@ async def provide_webrtc_answer(stream_source: str, offer: str, stream_id: str)
|
||||
return WEBRTC_ANSWER
|
||||
|
||||
|
||||
@pytest.fixture(name="mock_rtsp_to_webrtc")
|
||||
def mock_rtsp_to_webrtc_fixture(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||
) -> Generator[Mock]:
|
||||
"""Fixture that registers a mock rtsp to webrtc provider."""
|
||||
mock_provider = Mock(side_effect=provide_webrtc_answer)
|
||||
unsub = async_register_rtsp_to_web_rtc_provider(hass, "mock_domain", mock_provider)
|
||||
assert (
|
||||
"async_register_rtsp_to_web_rtc_provider is a deprecated function which will"
|
||||
" be removed in HA Core 2025.6. Use async_register_webrtc_provider instead"
|
||||
) in caplog.text
|
||||
yield mock_provider
|
||||
unsub()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_test_webrtc_cameras")
|
||||
async def test_websocket_webrtc_offer(
|
||||
hass: HomeAssistant, hass_ws_client: WebSocketGenerator
|
||||
@ -804,45 +786,6 @@ async def test_websocket_webrtc_offer_invalid_stream_type(
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_camera", "mock_stream_source")
|
||||
async def test_rtsp_to_webrtc_offer(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
mock_rtsp_to_webrtc: Mock,
|
||||
) -> None:
|
||||
"""Test creating a webrtc offer from an rstp provider."""
|
||||
client = await hass_ws_client(hass)
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "camera/webrtc/offer",
|
||||
"entity_id": "camera.demo_camera",
|
||||
"offer": WEBRTC_OFFER,
|
||||
}
|
||||
)
|
||||
response = await client.receive_json()
|
||||
|
||||
assert response["type"] == TYPE_RESULT
|
||||
assert response["success"]
|
||||
subscription_id = response["id"]
|
||||
|
||||
# Session id
|
||||
response = await client.receive_json()
|
||||
assert response["id"] == subscription_id
|
||||
assert response["type"] == "event"
|
||||
assert response["event"]["type"] == "session"
|
||||
|
||||
# Answer
|
||||
response = await client.receive_json()
|
||||
assert response["id"] == subscription_id
|
||||
assert response["type"] == "event"
|
||||
assert response["event"] == {
|
||||
"type": "answer",
|
||||
"answer": WEBRTC_ANSWER,
|
||||
}
|
||||
|
||||
assert mock_rtsp_to_webrtc.called
|
||||
|
||||
|
||||
@pytest.fixture(name="mock_hls_stream_source")
|
||||
async def mock_hls_stream_source_fixture() -> AsyncGenerator[AsyncMock]:
|
||||
"""Fixture to create an HLS stream source."""
|
||||
@ -853,117 +796,6 @@ async def mock_hls_stream_source_fixture() -> AsyncGenerator[AsyncMock]:
|
||||
yield mock_hls_stream_source
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_camera", "mock_stream_source")
|
||||
async def test_rtsp_to_webrtc_provider_unregistered(
|
||||
hass: HomeAssistant, hass_ws_client: WebSocketGenerator
|
||||
) -> None:
|
||||
"""Test creating a webrtc offer from an rstp provider."""
|
||||
mock_provider = Mock(side_effect=provide_webrtc_answer)
|
||||
unsub = async_register_rtsp_to_web_rtc_provider(hass, "mock_domain", mock_provider)
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
# Registered provider can handle the WebRTC offer
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "camera/webrtc/offer",
|
||||
"entity_id": "camera.demo_camera",
|
||||
"offer": WEBRTC_OFFER,
|
||||
}
|
||||
)
|
||||
response = await client.receive_json()
|
||||
assert response["type"] == TYPE_RESULT
|
||||
assert response["success"]
|
||||
subscription_id = response["id"]
|
||||
|
||||
# Session id
|
||||
response = await client.receive_json()
|
||||
assert response["id"] == subscription_id
|
||||
assert response["type"] == "event"
|
||||
assert response["event"]["type"] == "session"
|
||||
|
||||
# Answer
|
||||
response = await client.receive_json()
|
||||
assert response["id"] == subscription_id
|
||||
assert response["type"] == "event"
|
||||
assert response["event"] == {
|
||||
"type": "answer",
|
||||
"answer": WEBRTC_ANSWER,
|
||||
}
|
||||
|
||||
assert mock_provider.called
|
||||
mock_provider.reset_mock()
|
||||
|
||||
# Unregister provider, then verify the WebRTC offer cannot be handled
|
||||
unsub()
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "camera/webrtc/offer",
|
||||
"entity_id": "camera.demo_camera",
|
||||
"offer": WEBRTC_OFFER,
|
||||
}
|
||||
)
|
||||
response = await client.receive_json()
|
||||
assert response.get("type") == TYPE_RESULT
|
||||
assert not response["success"]
|
||||
assert response["error"] == {
|
||||
"code": "webrtc_offer_failed",
|
||||
"message": "Camera does not support WebRTC, frontend_stream_types={<StreamType.HLS: 'hls'>}",
|
||||
}
|
||||
|
||||
assert not mock_provider.called
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_camera", "mock_stream_source")
|
||||
async def test_rtsp_to_webrtc_offer_not_accepted(
|
||||
hass: HomeAssistant, hass_ws_client: WebSocketGenerator
|
||||
) -> None:
|
||||
"""Test a provider that can't satisfy the rtsp to webrtc offer."""
|
||||
|
||||
async def provide_none(
|
||||
stream_source: str, offer: str, stream_id: str
|
||||
) -> str | None:
|
||||
"""Simulate a provider that can't accept the offer."""
|
||||
return None
|
||||
|
||||
mock_provider = Mock(side_effect=provide_none)
|
||||
unsub = async_register_rtsp_to_web_rtc_provider(hass, "mock_domain", mock_provider)
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
# Registered provider can handle the WebRTC offer
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "camera/webrtc/offer",
|
||||
"entity_id": "camera.demo_camera",
|
||||
"offer": WEBRTC_OFFER,
|
||||
}
|
||||
)
|
||||
response = await client.receive_json()
|
||||
assert response["type"] == TYPE_RESULT
|
||||
assert response["success"]
|
||||
subscription_id = response["id"]
|
||||
|
||||
# Session id
|
||||
response = await client.receive_json()
|
||||
assert response["id"] == subscription_id
|
||||
assert response["type"] == "event"
|
||||
assert response["event"]["type"] == "session"
|
||||
|
||||
# Answer
|
||||
response = await client.receive_json()
|
||||
assert response["id"] == subscription_id
|
||||
assert response["type"] == "event"
|
||||
assert response["event"] == {
|
||||
"type": "error",
|
||||
"code": "webrtc_offer_failed",
|
||||
"message": "Camera does not support WebRTC",
|
||||
}
|
||||
|
||||
assert mock_provider.called
|
||||
|
||||
unsub()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("frontend_candidate", "expected_candidate"),
|
||||
[
|
||||
@ -1224,79 +1056,3 @@ async def test_webrtc_provider_optional_interface(hass: HomeAssistant) -> None:
|
||||
"session_id", RTCIceCandidateInit("candidate")
|
||||
)
|
||||
provider.async_close_session("session_id")
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_camera")
|
||||
async def test_repair_issue_legacy_provider(
|
||||
hass: HomeAssistant,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
) -> None:
|
||||
"""Test repair issue created for legacy provider."""
|
||||
# Ensure no issue if no provider is registered
|
||||
assert not issue_registry.async_get_issue(
|
||||
"camera", "legacy_webrtc_provider_mock_domain"
|
||||
)
|
||||
|
||||
# Register a legacy provider
|
||||
legacy_provider = Mock(side_effect=provide_webrtc_answer)
|
||||
unsub_legacy_provider = async_register_rtsp_to_web_rtc_provider(
|
||||
hass, "mock_domain", legacy_provider
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Ensure no issue if only legacy provider is registered
|
||||
assert not issue_registry.async_get_issue(
|
||||
"camera", "legacy_webrtc_provider_mock_domain"
|
||||
)
|
||||
|
||||
provider = Go2RTCProvider()
|
||||
unsub_go2rtc_provider = async_register_webrtc_provider(hass, provider)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Ensure issue when legacy and builtin provider are registered
|
||||
issue = issue_registry.async_get_issue(
|
||||
"camera", "legacy_webrtc_provider_mock_domain"
|
||||
)
|
||||
assert issue
|
||||
assert issue.is_fixable is False
|
||||
assert issue.is_persistent is False
|
||||
assert issue.issue_domain == "mock_domain"
|
||||
assert issue.learn_more_url == "https://www.home-assistant.io/integrations/go2rtc/"
|
||||
assert issue.severity == ir.IssueSeverity.WARNING
|
||||
assert issue.issue_id == "legacy_webrtc_provider_mock_domain"
|
||||
assert issue.translation_key == "legacy_webrtc_provider"
|
||||
assert issue.translation_placeholders == {
|
||||
"legacy_integration": "mock_domain",
|
||||
"builtin_integration": "go2rtc",
|
||||
}
|
||||
|
||||
unsub_legacy_provider()
|
||||
unsub_go2rtc_provider()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_camera", "register_test_provider", "mock_rtsp_to_webrtc")
|
||||
async def test_no_repair_issue_without_new_provider(
|
||||
hass: HomeAssistant,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
) -> None:
|
||||
"""Test repair issue not created if no go2rtc provider exists."""
|
||||
assert not issue_registry.async_get_issue(
|
||||
"camera", "legacy_webrtc_provider_mock_domain"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_camera", "mock_rtsp_to_webrtc")
|
||||
async def test_registering_same_legacy_provider(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test registering the same legacy provider twice."""
|
||||
legacy_provider = Mock(side_effect=provide_webrtc_answer)
|
||||
with pytest.raises(ValueError, match="Provider already registered"):
|
||||
async_register_rtsp_to_web_rtc_provider(hass, "mock_domain", legacy_provider)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_hls_stream_source", "mock_camera", "mock_rtsp_to_webrtc")
|
||||
async def test_get_not_supported_legacy_provider(hass: HomeAssistant) -> None:
|
||||
"""Test getting a not supported legacy provider."""
|
||||
camera = get_camera_from_entity_id(hass, "camera.demo_camera")
|
||||
assert await async_get_supported_legacy_provider(hass, camera) is None
|
||||
|
Loading…
x
Reference in New Issue
Block a user