1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
"""Define SimpliSafe cameras (SimpliCams)."""
from __future__ import annotations
from enum import Enum
from typing import TYPE_CHECKING, Any, cast
from urllib.parse import urlencode
from simplipy.const import LOGGER
from simplipy.device import DeviceV3
if TYPE_CHECKING:
from simplipy.system.v3 import SystemV3
DEFAULT_AUDIO_ENCODING = "AAC"
DEFAULT_MEDIA_URL_BASE = "https://media.simplisafe.com/v1"
DEFAULT_VIDEO_WIDTH = 1280
class CameraTypes(Enum):
"""Define camera types based on internal SimpliSafe ID number."""
CAMERA = 0
DOORBELL = 1
OUTDOOR_CAMERA = 2
UNKNOWN = 99
MODEL_TO_TYPE = {
"SS001": CameraTypes.CAMERA,
"SS002": CameraTypes.DOORBELL,
"SS003": CameraTypes.CAMERA,
"SSOBCM4": CameraTypes.OUTDOOR_CAMERA,
}
class Camera(DeviceV3):
"""Define a SimpliCam."""
_system: SystemV3
@property
def camera_settings(self) -> dict[str, Any]:
"""Return the camera settings.
Returns:
A dictionary of camera settings.
"""
return cast(
dict[str, Any], self._system.camera_data[self._serial]["cameraSettings"]
)
@property
def camera_type(self) -> CameraTypes:
"""Return the type of camera.
Returns:
The camera type.
"""
try:
return MODEL_TO_TYPE[self._system.camera_data[self._serial]["model"]]
except KeyError:
LOGGER.error(
"Unknown camera type: %s",
self._system.camera_data[self._serial]["model"],
)
return CameraTypes.UNKNOWN
@property
def name(self) -> str:
"""Return the camera name.
Returns:
The camera name.
"""
return cast(
str, self._system.camera_data[self._serial]["cameraSettings"]["cameraName"]
)
@property
def serial(self) -> str:
"""Return the camera's serial number.
Returns:
The camera serial number.
"""
return self._serial
@property
def shutter_open_when_away(self) -> bool:
"""Return whether the privacy shutter is open in away mode.
Returns:
The camera's "shutter open when away" status.
"""
val = self._system.camera_data[self._serial]["cameraSettings"]["shutterAway"]
return cast(bool, val == "open")
@property
def shutter_open_when_home(self) -> bool:
"""Return whether the privacy shutter is open in home mode.
Returns:
The camera's "shutter open when home" status.
"""
val = self._system.camera_data[self._serial]["cameraSettings"]["shutterHome"]
return cast(bool, val == "open")
@property
def shutter_open_when_off(self) -> bool:
"""Return whether the privacy shutter is open when the alarm is disarmed.
Returns:
The camera's "shutter open when off" status.
"""
val = self._system.camera_data[self._serial]["cameraSettings"]["shutterOff"]
return cast(bool, val == "open")
@property
def status(self) -> str:
"""Return the camera status.
Returns:
The camera status.
"""
return cast(str, self._system.camera_data[self._serial]["status"])
@property
def subscription_enabled(self) -> bool:
"""Return the camera subscription status.
Returns:
The camera subscription status.
"""
return cast(
bool, self._system.camera_data[self._serial]["subscription"]["enabled"]
)
def as_dict(self) -> dict[str, Any]:
"""Return dictionary version of this device.
Returns:
A dict representation of this device.
"""
return {
"camera_settings": self.camera_settings,
"camera_type": self.camera_type.value,
"name": self.name,
"serial": self.serial,
"shutter_open_when_away": self.shutter_open_when_away,
"shutter_open_when_home": self.shutter_open_when_home,
"shutter_open_when_off": self.shutter_open_when_off,
"status": self.status,
"subscription_enabled": self.subscription_enabled,
}
def video_url(
self,
width: int = DEFAULT_VIDEO_WIDTH,
audio_encoding: str = DEFAULT_AUDIO_ENCODING,
**kwargs: Any,
) -> str:
"""Return the camera video URL.
Args:
width: The video width.
audio_encoding: The audio encoding.
kwargs: Additional parameters.
Returns:
The camera video URL.
"""
url_params = {"x": width, "audioEncoding": audio_encoding, **kwargs}
return f"{DEFAULT_MEDIA_URL_BASE}/{self.serial}/flv?{urlencode(url_params)}"
|