From 79482501ec0e2359b4471552aad4324e208b789c Mon Sep 17 00:00:00 2001 From: Moe A Date: Wed, 26 Apr 2023 22:38:33 -0700 Subject: [PATCH] Save Frame to Timelapse for Motion Detection --- definitions/base.js | 18 +++++++++++++++ languages/en_CA.json | 2 ++ libs/events/utils.js | 33 ++++++++++++++++++++++++---- web/assets/js/bs5.monitorSettings.js | 1 + 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/definitions/base.js b/definitions/base.js index 104bda38..a7956330 100644 --- a/definitions/base.js +++ b/definitions/base.js @@ -2931,6 +2931,24 @@ module.exports = function(s,config,lang){ } ] }, + { + isAdvanced: true, + "name": "detail=detector_motion_save_frame", + "field": lang["Save Frames"], + "description": lang["fieldTextSaveFrames"], + "default": "0", + "fieldType": "select", + "possible": [ + { + "name": lang.No, + "value": "0" + }, + { + "name": lang.Yes, + "value": "1" + } + ] + }, // { // "name": "detail=detector_show_matrix", // "field": lang["Show Matrices"], diff --git a/languages/en_CA.json b/languages/en_CA.json index 92b89cf4..b5382d9b 100644 --- a/languages/en_CA.json +++ b/languages/en_CA.json @@ -27,6 +27,8 @@ "tagsCannotAddText": "Cannot add Tag", "tagsTriggerCannotAddText": "Trigger tags must match an existing tag that was added to a Monitor previously or is pending to be added to this monitor that is currently being edited.", "tagsFieldText": "Automatically group Monitors based on a common identifier.", + "Save Frames": "Save Frames", + "fieldTextSaveFrames": "Save a video frame when Motion Detection occurs.", "Refresh": "Refresh", "Compress": "Compress", "Tile Size": "Tile Size", diff --git a/libs/events/utils.js b/libs/events/utils.js index d02db6d6..4d69308a 100644 --- a/libs/events/utils.js +++ b/libs/events/utils.js @@ -11,6 +11,7 @@ const P = SAT.Polygon; const B = SAT.Box; // Matrix In Region Libs /> module.exports = (s,config,lang) => { + const motionFrameSaveTimeouts = {} // Event Filters > const acceptableOperators = ['indexOf','!indexOf','===','!==','>=','>','<','<='] // Event Filters /> @@ -375,8 +376,11 @@ module.exports = (s,config,lang) => { } const runEventExecutions = async (eventTime,monitorConfig,eventDetails,forceSave,filter,d, triggerEvent) => { const groupKey = monitorConfig.ke + const monitorId = d.id || d.mid const monitorDetails = monitorConfig.details const detailString = JSON.stringify(eventDetails) + const reason = eventDetails.reason + const timeoutId = `${groupKey}${monitorId}` if(monitorDetails.detector_ptz_follow === '1'){ moveCameraPtzToMatrix(d,monitorDetails.detector_ptz_follow_target) } @@ -389,10 +393,31 @@ module.exports = (s,config,lang) => { if(d.frame){ saveImageFromEvent({ ke: d.ke, - mid: d.id, + mid: monitorId, time: eventTime, matrices: eventDetails.matrices || [], },d.frame) + }else if( + !motionFrameSaveTimeouts[timeoutId] && + reason === 'motion' && + monitorDetails.detector_motion_save_frame === '1' && + ( + monitorDetails.detector_use_detect_object !== '1' || + (monitorDetails.detector_use_detect_object === '1' && monitorDetails.detector_use_motion !== '1') + ) + ){ + motionFrameSaveTimeouts[timeoutId] = setTimeout(() => { + delete(motionFrameSaveTimeouts[timeoutId]) + },10000) + const { screenShot, isStaticFile } = await s.getRawSnapshotFromMonitor(monitorConfig,{ + secondsInward: parseInt(monitorConfig.details.detector_buffer_seconds_before) || 5 + }) + saveImageFromEvent({ + ke: d.ke, + mid: monitorId, + time: eventTime, + matrices: eventDetails.matrices || [], + }, screenShot) } if(forceSave || (filter.save || monitorDetails.detector_save === '1')){ s.knexQuery({ @@ -400,7 +425,7 @@ module.exports = (s,config,lang) => { table: "Events", insert: { ke: d.ke, - mid: d.id, + mid: monitorId, details: detailString, time: s.formattedTime(eventTime), } @@ -439,9 +464,9 @@ module.exports = (s,config,lang) => { if( filter.command || - (monitorDetails.detector_command_enable === '1' && !s.group[d.ke].activeMonitors[d.id].detector_command) + (monitorDetails.detector_command_enable === '1' && !s.group[d.ke].activeMonitors[monitorId].detector_command) ){ - s.group[d.ke].activeMonitors[d.id].detector_command = s.createTimeout('detector_command',s.group[d.ke].activeMonitors[d.id],monitorDetails.detector_command_timeout,10) + s.group[d.ke].activeMonitors[monitorId].detector_command = s.createTimeout('detector_command',s.group[d.ke].activeMonitors[monitorId],monitorDetails.detector_command_timeout,10) var detector_command = addEventDetailsToString(d,monitorDetails.detector_command) if(detector_command === '')return exec(detector_command,{detached: true},function(err){ diff --git a/web/assets/js/bs5.monitorSettings.js b/web/assets/js/bs5.monitorSettings.js index 855a6d9a..3460b46f 100644 --- a/web/assets/js/bs5.monitorSettings.js +++ b/web/assets/js/bs5.monitorSettings.js @@ -137,6 +137,7 @@ function generateDefaultMonitorSettings(){ "detector_scale_y": "480", "detector_record_method": "sip", "detector_trigger": "1", + "detector_motion_save_frame": "1", "detector_timeout": "0.5", "detector_send_video_length": "", "watchdog_reset": "1",