1 """Component providing support for Reolink IP cameras."""
3 from __future__
import annotations
5 from dataclasses
import dataclass
8 from reolink_aio.api
import DUAL_LENS_MODELS
9 from reolink_aio.exceptions
import ReolinkError
13 CameraEntityDescription,
20 from .entity
import ReolinkChannelCoordinatorEntity, ReolinkChannelEntityDescription
21 from .util
import ReolinkConfigEntry, ReolinkData
23 _LOGGER = logging.getLogger(__name__)
27 @dataclass(frozen=True, kw_only=True)
29 CameraEntityDescription,
30 ReolinkChannelEntityDescription,
32 """A class that describes camera entities for a camera channel."""
41 translation_key=
"sub",
46 translation_key=
"main",
47 entity_registry_enabled_default=
False,
51 stream=
"snapshots_sub",
52 translation_key=
"snapshots_sub",
53 entity_registry_enabled_default=
False,
57 stream=
"snapshots_main",
58 translation_key=
"snapshots_main",
59 entity_registry_enabled_default=
False,
64 translation_key=
"ext",
65 supported=
lambda api, ch: api.protocol
in [
"rtmp",
"flv"],
66 entity_registry_enabled_default=
False,
70 stream=
"autotrack_sub",
71 translation_key=
"autotrack_sub",
72 supported=
lambda api, ch: api.supported(ch,
"autotrack_stream"),
75 key=
"autotrack_snapshots_sub",
76 stream=
"autotrack_snapshots_sub",
77 translation_key=
"autotrack_snapshots_sub",
78 supported=
lambda api, ch: api.supported(ch,
"autotrack_stream"),
79 entity_registry_enabled_default=
False,
82 key=
"autotrack_snapshots_main",
83 stream=
"autotrack_snapshots_main",
84 translation_key=
"autotrack_snapshots_main",
85 supported=
lambda api, ch: api.supported(ch,
"autotrack_stream"),
86 entity_registry_enabled_default=
False,
93 config_entry: ReolinkConfigEntry,
94 async_add_entities: AddEntitiesCallback,
96 """Set up a Reolink IP Camera."""
97 reolink_data: ReolinkData = config_entry.runtime_data
99 entities: list[ReolinkCamera] = []
100 for entity_description
in CAMERA_ENTITIES:
101 for channel
in reolink_data.host.api.stream_channels:
102 if not entity_description.supported(reolink_data.host.api, channel):
104 stream_url = await reolink_data.host.api.get_stream_source(
105 channel, entity_description.stream
107 if stream_url
is None and "snapshots" not in entity_description.stream:
110 entities.append(
ReolinkCamera(reolink_data, channel, entity_description))
116 """An implementation of a Reolink IP camera."""
118 entity_description: ReolinkCameraEntityDescription
122 reolink_data: ReolinkData,
124 entity_description: ReolinkCameraEntityDescription,
126 """Initialize Reolink camera stream."""
128 ReolinkChannelCoordinatorEntity.__init__(self, reolink_data, channel)
129 Camera.__init__(self)
131 if "snapshots" not in entity_description.stream:
134 if self.
_host_host.api.model
in DUAL_LENS_MODELS:
136 f
"{entity_description.translation_key}_lens_{self._channel}"
140 """Return the source of the stream."""
141 return await self.
_host_host.api.get_stream_source(
146 self, width: int |
None =
None, height: int |
None =
None
148 """Return a still image response from the camera."""
150 return await self.
_host_host.api.get_snapshot(
153 except ReolinkError
as err:
None __init__(self, ReolinkData reolink_data, int channel, ReolinkCameraEntityDescription entity_description)
str|None stream_source(self)
bytes|None async_camera_image(self, int|None width=None, int|None height=None)
None async_setup_entry(HomeAssistant hass, ReolinkConfigEntry config_entry, AddEntitiesCallback async_add_entities)