python
This commit is contained in:
107
custom_components/yandex_smart_home/capability_video.py
Normal file
107
custom_components/yandex_smart_home/capability_video.py
Normal 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)
|
||||
Reference in New Issue
Block a user