Skip to content

Commit

Permalink
Merge pull request #89 from CodeChief/master
Browse files Browse the repository at this point in the history
Support footage leftover by un-managed/moved cameras.
  • Loading branch information
danielfernau authored Jul 3, 2022
2 parents ee40b1f + cc0c253 commit a1e383f
Show file tree
Hide file tree
Showing 5 changed files with 321 additions and 29 deletions.
306 changes: 306 additions & 0 deletions fixtures/bootstrap.json
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,312 @@
"hasWifi": false,
"audioBitrate": 64000,
"modelKey": "camera"
},
{
"isDeleting": false,
"mac": "AAAAAAAAAAAA",
"host": "192.168.1.16",
"connectionHost": "192.168.1.7",
"type": "UVC G3 Micro",
"name": "Offline",
"upSince": 1580864933288,
"lastSeen": 1581122207843,
"connectedSince": 1581059728298,
"state": "DISCONNECTED",
"hardwareRevision": "23",
"firmwareVersion": "4.18.37",
"firmwareBuild": "3fcdcec.191223.633",
"isUpdating": false,
"isAdopting": false,
"isManaged": true,
"isProvisioned": true,
"isRebooting": false,
"isSshEnabled": false,
"canManage": false,
"isHidden": false,
"lastMotion": 1581108893184,
"micVolume": 100,
"isMicEnabled": true,
"isRecording": true,
"isMotionDetected": false,
"isAttemptingToConnect": false,
"phyRate": 81,
"hdrMode": false,
"isProbingForWifi": null,
"apMac": null,
"apRssi": null,
"elementInfo": null,
"chimeDuration": 300,
"isDark": true,
"motionStartCalls": 0,
"lastRing": null,
"wiredConnectionState": {
"phyRate": null
},
"channels": [
{
"id": 0,
"name": "High",
"enabled": true,
"isRtspEnabled": true,
"rtspAlias": "CgzDPxc1O7YnJmIt",
"width": 1920,
"height": 1080,
"fps": 15,
"bitrate": 3000000,
"minBitrate": 750000,
"maxBitrate": 6000000,
"fpsValues": [
1,
2,
3,
4,
5,
6,
8,
9,
10,
12,
15,
16,
18,
20,
24,
25,
30
],
"idrInterval": 5
},
{
"id": 1,
"name": "Medium",
"enabled": true,
"isRtspEnabled": false,
"rtspAlias": null,
"width": 1024,
"height": 576,
"fps": 15,
"bitrate": 1200000,
"minBitrate": 750000,
"maxBitrate": 2000000,
"fpsValues": [
1,
2,
3,
4,
5,
6,
8,
9,
10,
12,
15,
16,
18,
20,
24,
25,
30
],
"idrInterval": 5
},
{
"id": 2,
"name": "Low",
"enabled": true,
"isRtspEnabled": false,
"rtspAlias": null,
"width": 640,
"height": 360,
"fps": 15,
"bitrate": 200000,
"minBitrate": 32000,
"maxBitrate": 1000000,
"fpsValues": [
1,
2,
3,
4,
5,
6,
8,
9,
10,
12,
15
],
"idrInterval": 5
}
],
"ispSettings": {
"aeMode": "auto",
"irLedMode": "auto",
"irLedLevel": 255,
"wdr": 1,
"icrSensitivity": 0,
"brightness": 50,
"contrast": 50,
"hue": 50,
"saturation": 50,
"sharpness": 50,
"denoise": 50,
"isFlippedVertical": false,
"isFlippedHorizontal": false,
"isAutoRotateEnabled": false,
"isLdcEnabled": true,
"is3dnrEnabled": true,
"isExternalIrEnabled": false,
"isAggressiveAntiFlickerEnabled": false,
"isPauseMotionEnabled": false,
"dZoomCenterX": 50,
"dZoomCenterY": 50,
"dZoomScale": 0,
"dZoomStreamId": 4,
"focusMode": "ztrig",
"focusPosition": 0,
"touchFocusX": 0,
"touchFocusY": 0,
"zoomPosition": 0
},
"talkbackSettings": {
"typeFmt": "aac",
"typeIn": "serverudp",
"bindAddr": "0.0.0.0",
"bindPort": 7004,
"filterAddr": "",
"filterPort": 0,
"channels": 1,
"samplingRate": 22050,
"bitsPerSample": 16,
"quality": 100
},
"osdSettings": {
"isNameEnabled": true,
"isDateEnabled": true,
"isLogoEnabled": false,
"isDebugEnabled": false
},
"ledSettings": {
"isEnabled": true,
"blinkRate": 0
},
"speakerSettings": {
"isEnabled": true,
"areSystemSoundsEnabled": false,
"volume": 80
},
"recordingSettings": {
"prePaddingSecs": 2,
"postPaddingSecs": 2,
"minMotionEventTrigger": 1000,
"endMotionEventDelay": 3000,
"suppressIlluminationSurge": false,
"mode": "always",
"geofencing": "off",
"useNewMotionAlgorithm": false,
"enablePirTimelapse": false
},
"recordingSchedule": null,
"motionZones": [
{
"name": "Default",
"color": "#AB46BC",
"points": [
[
0,
0
],
[
1,
0
],
[
1,
1
],
[
0,
1
]
],
"sensitivity": 50
}
],
"privacyZones": [],
"stats": {
"rxBytes": 3358170514,
"txBytes": 51307864867,
"wifi": {
"channel": 36,
"frequency": 5180,
"linkSpeedMbps": 81,
"signalQuality": 97,
"signalStrength": -66
},
"battery": {
"percentage": null,
"isCharging": false,
"sleepState": "awake"
},
"video": {
"recordingStart": null,
"recordingEnd": null,
"recordingStartLQ": null,
"recordingEndLQ": null,
"timelapseStart": null,
"timelapseEnd": null,
"timelapseStartLQ": null,
"timelapseEndLQ": null
},
"wifiQuality": 97,
"wifiStrength": -66
},
"featureFlags": {
"canAdjustIrLedLevel": false,
"canMagicZoom": true,
"canOpticalZoom": false,
"canTouchFocus": false,
"hasAccelerometer": false,
"hasAec": false,
"hasBattery": false,
"hasBluetooth": true,
"hasChime": false,
"hasExternalIr": false,
"hasIcrSensitivity": true,
"hasLdc": true,
"hasLedIr": true,
"hasLedStatus": true,
"hasLineIn": false,
"hasMic": true,
"hasPrivacyMask": true,
"hasRtc": false,
"hasSdCard": false,
"hasSpeaker": true,
"hasWifi": true,
"hasHdr": false,
"hasAutoICROnly": true,
"hasMotionZones": true
},
"pirSettings": {
"pirSensitivity": 100,
"pirMotionClipLength": 15,
"timelapseFrameInterval": 15,
"timelapseTransferInterval": 600
},
"wifiConnectionState": {
"channel": 36,
"frequency": 5180,
"phyRate": 81,
"signalQuality": 97,
"signalStrength": -66
},
"id": "offlineCameraId",
"isConnected": false,
"platform": "s2lm",
"hasSpeaker": true,
"hasWifi": true,
"audioBitrate": 64000,
"modelKey": "camera"
}
],
"users": [
Expand Down
4 changes: 2 additions & 2 deletions protect_archiver/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ def __init__(
self.verify_ssl,
)

def get_camera_list(self, connected: bool = True) -> List[Any]:
return Downloader.get_camera_list(self.session, connected)
def get_camera_list(self) -> List[Any]:
return Downloader.get_camera_list(self.session)

def get_motion_event_list(
self, start: datetime, end: datetime, camera_list: List[Any]
Expand Down
4 changes: 2 additions & 2 deletions protect_archiver/downloader/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ def __init__(
self.download_wait = download_wait

@staticmethod
def get_camera_list(session: Any, connected: bool) -> List[Any]:
return get_camera_list(session, connected)
def get_camera_list(session: Any) -> List[Any]:
return get_camera_list(session)

@staticmethod
def get_motion_event_list(
Expand Down
21 changes: 6 additions & 15 deletions protect_archiver/downloader/get_camera_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from protect_archiver.dataclasses import Camera


def get_camera_list(session: Any, connected: bool = True) -> List[Camera]:
def get_camera_list(session: Any) -> List[Camera]:
cameras_uri = f"{session.authority}{session.base_path}/cameras"

response = (
Expand All @@ -36,21 +36,12 @@ def get_camera_list(session: Any, connected: bool = True) -> List[Camera]:

camera_list = []
for camera in cameras:
if connected and camera["state"] != "CONNECTED": # ignore disconnected cameras
continue

if camera["stats"]["video"]["recordingStart"] is None: # ignore cameras without recordings
continue

camera_list.append(
Camera(
id=camera["id"],
name=camera["name"],
recording_start=datetime.utcfromtimestamp(
camera["stats"]["video"]["recordingStart"] / 1000
),
camera_data = Camera(id=camera["id"], name=camera["name"], recording_start=datetime.min)
if camera["stats"]["video"]["recordingStart"]:
camera_data.recording_start = datetime.utcfromtimestamp(
camera["stats"]["video"]["recordingStart"] / 1000
)
)
camera_list.append(camera_data)

logging.info(
"Cameras found:\n{}".format(
Expand Down
15 changes: 5 additions & 10 deletions protect_archiver/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,7 @@ def mock_api(
def test_get_camera_list(client: Any) -> None:
results = client.get_camera_list()

assert len(results) == 1
assert results[0].id == "exteriorCameraId"
assert results[0].name == "Exterior"
assert results[0].recording_start == datetime(2020, 1, 8, 23, 26, 9, 586000)


def test_get_camera_list_with_disconnected(client: Any) -> None:
results = client.get_camera_list(connected=False)

assert len(results) == 2
assert len(results) == 3
assert results[0].id == "exteriorCameraId"
assert results[0].name == "Exterior"
assert results[0].recording_start == datetime(2020, 1, 8, 23, 26, 9, 586000)
Expand All @@ -53,6 +44,10 @@ def test_get_camera_list_with_disconnected(client: Any) -> None:
assert results[1].name == "Test"
assert results[1].recording_start == datetime(2019, 10, 20, 18, 0, 0, 134000)

assert results[2].id == "offlineCameraId"
assert results[2].name == "Offline"
assert results[2].recording_start == datetime.min


def test_download_footage(
responses: Any, client: Any, sample_camera: Any, test_output_dest: Any
Expand Down

0 comments on commit a1e383f

Please sign in to comment.