This commit is contained in:
Victor Alexandrovich Tsyrenschikov
2026-03-30 20:25:42 +05:00
parent 139f9f1bd2
commit 373ed28445
2449 changed files with 53602 additions and 0 deletions

View File

@@ -0,0 +1,107 @@
"""Implement the Yandex Smart Home video_stream capabilities."""
# pyright: reportAttributeAccessIssue=information
from __future__ import annotations
from typing import TYPE_CHECKING
from homeassistant.components import camera
from homeassistant.components.camera import CameraEntityFeature, StreamType
from homeassistant.components.stream import Stream
from homeassistant.core import Context
from homeassistant.helpers import network
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from . import DOMAIN
from .capability import STATE_CAPABILITIES_REGISTRY, ActionOnlyCapabilityMixin, StateCapability
from .cloud_stream import CloudStreamManager
from .helpers import APIError
from .schema import (
CapabilityType,
GetStreamInstanceActionResultValue,
GetStreamInstanceActionState,
ResponseCode,
VideoStreamCapabilityInstance,
VideoStreamCapabilityParameters,
)
try:
from homeassistant.components.camera import get_camera_from_entity_id
except ImportError: # pragma: no cover
from homeassistant.components.camera import ( # type: ignore[no-redef]
_get_camera_from_entity_id as get_camera_from_entity_id,
)
if TYPE_CHECKING:
from . import YandexSmartHome
class VideoStreamCapability(ActionOnlyCapabilityMixin, StateCapability[GetStreamInstanceActionState]):
"""Capability to stream from cameras."""
type = CapabilityType.VIDEO_STREAM
instance = VideoStreamCapabilityInstance.GET_STREAM
@property
def supported(self) -> bool:
"""Test if the capability is supported."""
return self.state.domain == camera.DOMAIN and bool(self._state_features & CameraEntityFeature.STREAM)
@property
def parameters(self) -> VideoStreamCapabilityParameters:
"""Return parameters for a devices request."""
return VideoStreamCapabilityParameters(protocols=["hls"])
async def set_instance_state(
self, context: Context, state: GetStreamInstanceActionState
) -> GetStreamInstanceActionResultValue:
"""Change capability instance state."""
component: YandexSmartHome = self._hass.data[DOMAIN]
entity_id = self.state.entity_id
stream = await self._async_request_stream(entity_id)
if self._entry_data.use_cloud_stream:
cloud_stream = component.cloud_streams.get(entity_id)
if not cloud_stream:
cloud_stream = CloudStreamManager(self._hass, stream, async_get_clientsession(self._hass))
component.cloud_streams[entity_id] = cloud_stream
await cloud_stream.async_start()
stream_url = cloud_stream.stream_url
if not stream_url:
raise APIError(ResponseCode.NOT_SUPPORTED_IN_CURRENT_MODE, "Failed to start stream")
else:
try:
external_url = network.get_url(self._hass, allow_internal=False)
except network.NoURLAvailableError:
raise APIError(
ResponseCode.NOT_SUPPORTED_IN_CURRENT_MODE,
"Missing Home Assistant external URL. Have you set external URLs in Configuration -> General?",
)
endpoint_url = stream.endpoint_url(StreamType.HLS)
stream_url = f"{external_url}{endpoint_url}"
return GetStreamInstanceActionResultValue(stream_url=stream_url, protocol="hls")
async def _async_request_stream(self, entity_id: str) -> Stream:
camera_entity = get_camera_from_entity_id(self._hass, self.state.entity_id)
stream = await camera_entity.async_create_stream()
if not stream:
raise APIError(
ResponseCode.NOT_SUPPORTED_IN_CURRENT_MODE, f"{entity_id} does not support play stream service"
)
stream.add_provider(StreamType.HLS)
await stream.start()
stream.endpoint_url(StreamType.HLS)
return stream
STATE_CAPABILITIES_REGISTRY.register(VideoStreamCapability)