Files
scrypted/plugins/arlo/src/arlo_plugin/camera.py
Brett Jia fb7462b4c2 arlo: various fixes and use correct api url for snapshots (#256)
* remove Refresh, extend internal timeout, add new action to snapshots

* lower timeout, properly listen for last image url

* tweak arlo endpoint

* promote to official release
2022-05-21 20:32:14 -07:00

88 lines
3.2 KiB
Python

import asyncio
import scrypted_sdk
from scrypted_sdk import ScryptedDeviceBase
from scrypted_sdk.types import Camera, VideoCamera, MotionSensor, Battery, ScryptedMimeTypes
from .logging import ScryptedDeviceLoggerMixin
class ArloCamera(ScryptedDeviceBase, Camera, VideoCamera, MotionSensor, Battery, ScryptedDeviceLoggerMixin):
timeout = 30
nativeId = None
arlo_device = None
arlo_basestation = None
provider = None
def __init__(self, nativeId, arlo_device, arlo_basestation, provider):
super().__init__(nativeId=nativeId)
self.logger_name = f"ArloCamera[{nativeId}]"
self.nativeId = nativeId
self.arlo_device = arlo_device
self.arlo_basestation = arlo_basestation
self.provider = provider
self.logger.setLevel(self.provider.get_current_log_level())
self._update_device_details(arlo_device)
self.stop_motion_subscription = False
self.start_motion_subscription()
def __del__(self):
self.stop_motion_subscription = True
def start_motion_subscription(self):
def callback(motionDetected):
self.motionDetected = motionDetected
return self.stop_motion_subscription
self.provider.arlo.SubscribeToMotionEvents(self.arlo_basestation, self.arlo_device, callback)
async def getPictureOptions(self):
return []
async def takePicture(self, options=None):
self.logger.info("Taking picture")
real_device = await scrypted_sdk.systemManager.api.getDeviceById(self.deviceState._id)
msos = await real_device.getVideoStreamOptions()
if any(["prebuffer" in m for m in msos]):
self.logger.info("Getting snapshot from prebuffer")
return await real_device.getVideoStream({"refresh": False})
pic_url = await asyncio.wait_for(self.provider.arlo.TriggerFullFrameSnapshot(self.arlo_basestation, self.arlo_device), timeout=self.timeout)
self.logger.debug(f"Got snapshot URL for at {pic_url}")
if pic_url is None:
raise Exception("Error taking snapshot")
return await scrypted_sdk.mediaManager.createMediaObject(str.encode(pic_url), ScryptedMimeTypes.Url.value)
async def getVideoStreamOptions(self):
return [
{
"id": 'default',
"name": 'Cloud RTSP',
"container": 'rtsp',
"video": {
"codec": 'h264',
},
"audio": None if self.arlo_device.get("modelId") == "VMC3030" else {
"codec": 'aac',
},
"source": 'cloud',
"tool": 'scrypted',
"userConfigurable": False,
}
]
async def getVideoStream(self, options=None):
self.logger.info("Requesting stream")
rtsp_url = await asyncio.wait_for(self.provider.arlo.StartStream(self.arlo_basestation, self.arlo_device), timeout=self.timeout)
self.logger.debug(f"Got stream URL at {rtsp_url}")
return await scrypted_sdk.mediaManager.createMediaObject(str.encode(rtsp_url), ScryptedMimeTypes.Url.value)
def _update_device_details(self, arlo_device):
self.batteryLevel = arlo_device["properties"].get("batteryLevel")