Shinobi/libs/events/utils.js

749 lines
33 KiB
JavaScript
Raw Normal View History

const fs = require('fs').promises;
const moment = require('moment');
const execSync = require('child_process').execSync;
const exec = require('child_process').exec;
const spawn = require('child_process').spawn;
const imageSaveEventLock = {};
// Matrix In Region Libs >
const SAT = require('sat')
const V = SAT.Vector;
const P = SAT.Polygon;
const B = SAT.Box;
// Matrix In Region Libs />
module.exports = (s,config,lang,app,io) => {
2021-11-02 01:07:42 +00:00
// Event Filters >
const acceptableOperators = ['indexOf','!indexOf','===','!==','>=','>','<','<=']
// Event Filters />
const {
splitForFFPMEG
} = require('../ffmpeg/utils.js')(s,config,lang)
const {
moveCameraPtzToMatrix
} = require('../control/ptz.js')(s,config,lang)
const {
cutVideoLength
} = require('../video/utils.js')(s,config,lang)
const {
isEven,
fetchTimeout,
} = require('../basic/utils.js')(process.cwd(),config)
async function saveImageFromEvent(options,frameBuffer){
const monitorId = options.mid || options.id
const groupKey = options.ke
if(imageSaveEventLock[groupKey + monitorId])return;
const eventTime = options.time
const objectsFound = options.matrices
const monitorConfig = Object.assign({id: monitorId},s.group[groupKey].rawMonitorConfigurations[monitorId])
const timelapseRecordingDirectory = s.getTimelapseFrameDirectory({mid: monitorId, ke: groupKey})
const currentDate = s.formattedTime(eventTime,'YYYY-MM-DD')
const filename = s.formattedTime(eventTime) + '.jpg'
const location = timelapseRecordingDirectory + currentDate + '/'
try{
await fs.stat(location)
}catch(err){
await fs.mkdir(location)
}
await fs.writeFile(location + filename,frameBuffer)
s.createTimelapseFrameAndInsert(monitorConfig,location,filename,eventTime,{
objects: objectsFound
})
imageSaveEventLock[groupKey + monitorId] = setTimeout(function(){
delete(imageSaveEventLock[groupKey + monitorId])
},1000)
}
const countObjects = async (event) => {
const matrices = event.details.matrices
const eventsCounted = s.group[event.ke].activeMonitors[event.id].eventsCounted || {}
if(matrices){
matrices.forEach((matrix)=>{
const id = matrix.tag
if(!eventsCounted[id])eventsCounted[id] = {times: [], count: {}, tag: matrix.tag}
if(!isNaN(matrix.id))eventsCounted[id].count[matrix.id] = 1
eventsCounted[id].times.push(new Date().getTime())
})
}
return eventsCounted
}
2021-01-02 18:30:20 +00:00
const addEventDetailsToString = (eventData,string,addOps) => {
//d = event data
if(!addOps)addOps = {}
var newString = string + ''
var d = Object.assign(eventData,addOps)
var detailString = s.stringJSON(d.details)
newString = newString
.replace(/{{TIME}}/g,d.currentTimestamp)
.replace(/{{REGION_NAME}}/g,d.details.name)
.replace(/{{SNAP_PATH}}/g,s.dir.streams+d.ke+'/'+d.id+'/s.jpg')
.replace(/{{MONITOR_ID}}/g,d.id)
.replace(/{{MONITOR_NAME}}/g,s.group[d.ke].rawMonitorConfigurations[d.id].name)
.replace(/{{GROUP_KEY}}/g,d.ke)
.replace(/{{DETAILS}}/g,detailString)
if(d.details.confidence){
newString = newString
.replace(/{{CONFIDENCE}}/g,d.details.confidence)
}
if(newString.includes("REASON")) {
if(d.details.reason) {
newString = newString
.replace(/{{REASON}}/g, d.details.reason)
}
}
return newString
}
const isAtleastOneMatrixInRegion = function(regions,matrices,callback){
var regionPolys = []
var matrixPoints = []
regions.forEach(function(region,n){
var polyPoints = []
region.points.forEach(function(point){
polyPoints.push(new V(parseInt(point[0]),parseInt(point[1])))
})
regionPolys[n] = new P(new V(0,0), polyPoints)
})
var collisions = []
var foundInRegion = false
matrices.forEach(function(matrix){
var matrixPoly = new B(new V(matrix.x, matrix.y), matrix.width, matrix.height).toPolygon()
regionPolys.forEach(function(region,n){
var response = new SAT.Response()
var collided = SAT.testPolygonPolygon(matrixPoly, region, response)
if(collided === true){
collisions.push({
matrix: matrix,
region: regions[n]
})
foundInRegion = true
}
})
})
if(callback)callback(foundInRegion,collisions)
return foundInRegion
}
const scanMatricesforCollisions = function(region,matrices){
var matrixPoints = []
var collisions = []
if (!region || !matrices){
if(callback)callback(collisions)
return collisions
}
var polyPoints = []
region.points.forEach(function(point){
polyPoints.push(new V(parseInt(point[0]),parseInt(point[1])))
})
var regionPoly = new P(new V(0,0), polyPoints)
matrices.forEach(function(matrix){
if (matrix){
var matrixPoly = new B(new V(matrix.x, matrix.y), matrix.width, matrix.height).toPolygon()
var response = new SAT.Response()
var collided = SAT.testPolygonPolygon(matrixPoly, regionPoly, response)
if(collided === true){
collisions.push(matrix)
}
}
})
return collisions
}
const getLargestMatrix = (matrices) => {
var largestMatrix = {width: 0, height: 0}
matrices.forEach((matrix) => {
if(matrix.width > largestMatrix.width && matrix.height > largestMatrix.height)largestMatrix = matrix
})
return largestMatrix.x ? largestMatrix : null
}
const addToEventCounter = (eventData) => {
const eventsCounted = s.group[eventData.ke].activeMonitors[eventData.id].detector_motion_count
eventsCounted.push(eventData)
}
const clearEventCounter = (groupKey,monitorId) => {
s.group[eventData.ke].activeMonitors[eventData.id].detector_motion_count = []
}
const getEventsCounted = (groupKey,monitorId) => {
return s.group[eventData.ke].activeMonitors[eventData.id].detector_motion_count.length
}
2021-02-27 16:39:17 +00:00
const hasMatrices = (eventDetails) => {
return (eventDetails.matrices && eventDetails.matrices.length > 0) && eventDetails.reason !== 'motion'
}
const checkEventFilters = (d,monitorDetails,filter) => {
2021-01-17 14:38:08 +00:00
const eventDetails = d.details
if(
monitorDetails.use_detector_filters === '1' &&
((monitorDetails.use_detector_filters_object === '1' && d.details.matrices && d.details.reason !== 'motion') ||
monitorDetails.use_detector_filters_object !== '1')
){
const parseValue = function(key,val){
var newVal
switch(val){
case'':
newVal = filter[key]
break;
case'0':
newVal = false
break;
case'1':
newVal = true
break;
default:
newVal = val
break;
}
return newVal
}
const filters = monitorDetails.detector_filters
Object.keys(filters).forEach(function(key){
var conditionChain = {}
var dFilter = filters[key]
if(dFilter.enabled === '0')return;
var numberOfOpenAndCloseBrackets = 0
dFilter.where.forEach(function(condition,place){
const hasOpenBracket = condition.openBracket === '1';
const hasCloseBracket = condition.closeBracket === '1';
conditionChain[place] = {
ok: false,
next: condition.p4,
matrixCount: 0,
openBracket: hasOpenBracket,
closeBracket: hasCloseBracket,
}
if(hasOpenBracket)++numberOfOpenAndCloseBrackets;
if(hasCloseBracket)++numberOfOpenAndCloseBrackets;
if(d.details.matrices)conditionChain[place].matrixCount = d.details.matrices.length
var modifyFilters = function(toCheck,matrixPosition){
var param = toCheck[condition.p1]
var pass = function(){
if(matrixPosition && dFilter.actions.halt === '1'){
delete(d.details.matrices[matrixPosition])
}else{
conditionChain[place].ok = true
}
}
switch(condition.p2){
case'indexOf':
if(param.indexOf(condition.p3) > -1){
pass()
}
break;
case'!indexOf':
if(param.indexOf(condition.p3) === -1){
pass()
}
break;
2021-11-02 01:07:42 +00:00
case'===':
case'!==':
case'>=':
case'>':
case'<':
case'<=':
if(eval('param '+condition.p2+' "'+condition.p3.replace(/"/g,'\\"')+'"')){
pass()
}
break;
}
}
switch(condition.p1){
case'tag':
case'x':
case'y':
case'height':
case'width':
case'confidence':
if(d.details.matrices){
d.details.matrices.forEach(function(matrix,position){
modifyFilters(matrix,position)
})
}
break;
case'time':
var timeNow = new Date()
var timeCondition = new Date()
var doAtTime = condition.p3.split(':')
var atHour = parseInt(doAtTime[0]) - 1
var atHourNow = timeNow.getHours()
var atMinuteNow = timeNow.getMinutes()
var atSecondNow = timeNow.getSeconds()
if(atHour){
var atMinute = parseInt(doAtTime[1]) - 1 || timeNow.getMinutes()
var atSecond = parseInt(doAtTime[2]) - 1 || timeNow.getSeconds()
var nowAddedInSeconds = atHourNow * 60 * 60 + atMinuteNow * 60 + atSecondNow
var conditionAddedInSeconds = atHour * 60 * 60 + atMinute * 60 + atSecond
2021-11-02 01:07:42 +00:00
if(acceptableOperators.indexOf(condition.p2) > -1 && eval('nowAddedInSeconds '+condition.p2+' conditionAddedInSeconds')){
conditionChain[place].ok = true
}
}
break;
default:
modifyFilters(d.details)
break;
}
})
var conditionArray = Object.values(conditionChain)
var validationString = []
var allowBrackets = false;
if (numberOfOpenAndCloseBrackets === 0 || isEven(numberOfOpenAndCloseBrackets)){
allowBrackets = true;
}else{
s.userLog(d,{type:lang["Event Filter Error"],msg:lang.eventFilterErrorBrackets})
}
conditionArray.forEach(function(condition,number){
validationString.push(`${allowBrackets && condition.openBracket ? '(' : ''}${condition.ok}${allowBrackets && condition.closeBracket ? ')' : ''}`);
if(conditionArray.length-1 !== number){
validationString.push(condition.next)
}
})
if(eval(validationString.join(' '))){
if(dFilter.actions.halt !== '1'){
delete(dFilter.actions.halt)
Object.keys(dFilter.actions).forEach(function(key){
var value = dFilter.actions[key]
filter[key] = parseValue(key,value)
})
if(dFilter.actions.record === '1'){
filter.forceRecord = true
}
}else{
filter.halt = true
}
}
})
if(d.details.matrices && d.details.matrices.length === 0 && d.details.reason !== 'motion' || filter.halt === true){
return false
2021-02-27 16:39:17 +00:00
}else if(hasMatrices(d.details)){
var reviewedMatrix = []
d.details.matrices.forEach(function(matrix){
if(matrix)reviewedMatrix.push(matrix)
})
d.details.matrices = reviewedMatrix
}
}
// check modified indifference
if(
2021-05-19 06:09:04 +00:00
filter.indifference &&
eventDetails.confidence < parseFloat(filter.indifference)
){
// fails indifference check for modified indifference
return
}
return true
}
const checkMotionLock = (eventData,monitorDetails) => {
if(s.group[eventData.ke].activeMonitors[eventData.id].motion_lock){
return false
}
var detector_lock_timeout
if(!monitorDetails.detector_lock_timeout||monitorDetails.detector_lock_timeout===''){
detector_lock_timeout = 2000
}
detector_lock_timeout = parseFloat(monitorDetails.detector_lock_timeout);
if(!s.group[eventData.ke].activeMonitors[eventData.id].detector_lock_timeout){
s.group[eventData.ke].activeMonitors[eventData.id].detector_lock_timeout=setTimeout(function(){
clearTimeout(s.group[eventData.ke].activeMonitors[eventData.id].detector_lock_timeout)
delete(s.group[eventData.ke].activeMonitors[eventData.id].detector_lock_timeout)
},detector_lock_timeout)
}else{
return false
}
return true
}
const runMultiTrigger = (monitorConfig,eventDetails, d, triggerEvent) => {
s.getCamerasForMultiTrigger(monitorConfig).forEach(function(monitor){
if(monitor.mid !== d.id){
triggerEvent({
id: monitor.mid,
ke: monitor.ke,
details: {
confidence: 100,
name: "multiTrigger",
plug: eventDetails.plug,
reason: eventDetails.reason
}
})
}
})
}
2021-02-27 16:39:17 +00:00
const checkForObjectsInRegions = (monitorConfig,eventDetails,filter,d,didCountingAlready) => {
2021-01-02 18:30:20 +00:00
const monitorDetails = monitorConfig.details
2021-02-27 16:39:17 +00:00
if(hasMatrices(eventDetails) && monitorDetails.detector_obj_region === '1'){
2021-01-02 18:30:20 +00:00
var regions = s.group[monitorConfig.ke].activeMonitors[monitorConfig.mid].parsedObjects.cords
var isMatrixInRegions = isAtleastOneMatrixInRegion(regions,eventDetails.matrices)
if(isMatrixInRegions){
s.debugLog('Matrix in region!')
if(filter.countObjects && monitorDetails.detector_obj_count === '1' && monitorDetails.detector_obj_count_in_region === '1' && !didCountingAlready){
countObjects(d)
}
}else{
return false
}
}
return true
}
const runEventExecutions = async (eventTime,monitorConfig,eventDetails,forceSave,filter,d, triggerEvent) => {
const monitorDetails = monitorConfig.details
2021-01-02 16:47:59 +00:00
const detailString = JSON.stringify(eventDetails)
if(monitorDetails.detector_ptz_follow === '1'){
moveCameraPtzToMatrix(d,monitorDetails.detector_ptz_follow_target)
}
if(monitorDetails.det_multi_trig === '1'){
runMultiTrigger(monitorConfig,eventDetails, d, triggerEvent)
}
//save this detection result in SQL, only coords. not image.
if(d.frame){
saveImageFromEvent({
ke: d.ke,
mid: d.id,
time: eventTime,
matrices: eventDetails.matrices || [],
},d.frame)
}
2021-10-29 04:00:52 +00:00
if(forceSave || (filter.save || monitorDetails.detector_save === '1')){
s.knexQuery({
action: "insert",
table: "Events",
insert: {
ke: d.ke,
mid: d.id,
details: detailString,
time: s.formattedTime(eventTime),
}
})
}
if(monitorDetails.detector === '1' && monitorDetails.detector_notrigger === '1'){
s.setNoEventsDetector(monitorConfig)
}
var detector_timeout
if(!monitorDetails.detector_timeout||monitorDetails.detector_timeout===''){
detector_timeout = 10
}else{
detector_timeout = parseFloat(monitorDetails.detector_timeout)
}
if(
(filter.forceRecord || (filter.record && monitorDetails.detector_trigger === '1')) &&
monitorConfig.mode === 'start' &&
(monitorDetails.detector_record_method === 'sip' || monitorDetails.detector_record_method === 'hot')
){
2021-01-02 18:30:20 +00:00
createEventBasedRecording(d,moment(eventTime).subtract(5,'seconds').format('YYYY-MM-DDTHH-mm-ss'))
}
d.currentTime = eventTime
d.currentTimestamp = s.timeObject(d.currentTime).format()
d.screenshotName = eventDetails.reason + '_'+(monitorConfig.name.replace(/[^\w\s]/gi,''))+'_'+d.id+'_'+d.ke+'_'+s.formattedTime()
d.screenshotBuffer = null
if(filter.webhook && monitorDetails.detector_webhook === '1' && !s.group[d.ke].activeMonitors[d.id].detector_webhook){
s.group[d.ke].activeMonitors[d.id].detector_webhook = s.createTimeout('detector_webhook',s.group[d.ke].activeMonitors[d.id],monitorDetails.detector_webhook_timeout,10)
2021-01-02 18:30:20 +00:00
var detector_webhook_url = addEventDetailsToString(d,monitorDetails.detector_webhook_url)
var webhookMethod = monitorDetails.detector_webhook_method
if(!webhookMethod || webhookMethod === '')webhookMethod = 'GET'
fetchTimeout(detector_webhook_url,10000,{
method: webhookMethod
}).catch((err) => {
s.userLog(d,{type:lang["Event Webhook Error"],msg:{error:err,data:data}})
})
}
if(
filter.command ||
(monitorDetails.detector_command_enable === '1' && !s.group[d.ke].activeMonitors[d.id].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)
2021-01-02 18:30:20 +00:00
var detector_command = addEventDetailsToString(d,monitorDetails.detector_command)
if(detector_command === '')return
exec(detector_command,{detached: true},function(err){
if(err)s.debugLog(err)
})
}
for (var i = 0; i < s.onEventTriggerExtensions.length; i++) {
const extender = s.onEventTriggerExtensions[i]
await extender(d,filter)
}
}
const getEventBasedRecordingUponCompletion = function(options){
const response = {ok: true}
return new Promise((resolve,reject) => {
const groupKey = options.ke
const monitorId = options.mid
const activeMonitor = s.group[groupKey].activeMonitors[monitorId]
if(activeMonitor && activeMonitor.eventBasedRecording && activeMonitor.eventBasedRecording.process){
const eventBasedRecording = activeMonitor.eventBasedRecording
const monitorConfig = s.group[groupKey].rawMonitorConfigurations[monitorId]
const videoLength = parseInt(monitorConfig.details.detector_send_video_length) || 10
const recordingDirectory = s.getVideoDirectory(monitorConfig)
const fileTime = eventBasedRecording.lastFileTime
const filename = `${fileTime}.mp4`
response.filename = `${filename}`
response.filePath = `${recordingDirectory}${filename}`
eventBasedRecording.process.on('exit',function(){
setTimeout(async () => {
if(!isNaN(videoLength)){
const cutResponse = await cutVideoLength({
ke: groupKey,
mid: monitorId,
filePath: response.filePath,
cutLength: videoLength,
})
if(cutResponse.ok){
response.filename = cutResponse.filename
response.filePath = cutResponse.filePath
}else{
s.debugLog('cutResponse',cutResponse)
}
}
resolve(response)
},1000)
})
}else{
resolve(response)
}
})
}
2021-01-02 18:30:20 +00:00
const createEventBasedRecording = function(d,fileTime){
if(!fileTime)fileTime = s.formattedTime()
const logTitleText = lang["Traditional Recording"]
const activeMonitor = s.group[d.ke].activeMonitors[d.id]
const monitorConfig = s.group[d.ke].rawMonitorConfigurations[d.id]
const monitorDetails = monitorConfig.details
2021-01-02 18:30:20 +00:00
if(monitorDetails.detector !== '1'){
return
}
var detector_timeout
if(!monitorDetails.detector_timeout||monitorDetails.detector_timeout===''){
detector_timeout = 10
}else{
detector_timeout = parseFloat(monitorDetails.detector_timeout)
}
if(monitorDetails.watchdog_reset === '1' || !activeMonitor.eventBasedRecording.timeout){
clearTimeout(activeMonitor.eventBasedRecording.timeout)
activeMonitor.eventBasedRecording.timeout = setTimeout(function(){
activeMonitor.eventBasedRecording.allowEnd = true
activeMonitor.eventBasedRecording.process.stdin.setEncoding('utf8')
activeMonitor.eventBasedRecording.process.stdin.write('q')
activeMonitor.eventBasedRecording.process.kill('SIGINT')
delete(activeMonitor.eventBasedRecording.timeout)
},detector_timeout * 1000 * 60)
}
if(!activeMonitor.eventBasedRecording.process){
activeMonitor.eventBasedRecording.allowEnd = false;
activeMonitor.eventBasedRecording.lastFileTime = `${fileTime}`;
2021-01-02 18:30:20 +00:00
const runRecord = function(){
var ffmpegError = ''
var error
var filename = fileTime + '.mp4'
let outputMap = `-map 0:0 `
2021-01-02 18:30:20 +00:00
s.userLog(d,{
type: logTitleText,
msg: lang["Started"]
})
//-t 00:'+s.timeObject(new Date(detector_timeout * 1000 * 60)).format('mm:ss')+'
if(
monitorDetails.detector_buffer_acodec &&
monitorDetails.detector_buffer_acodec !== 'no' &&
monitorDetails.detector_buffer_acodec !== 'auto'
){
outputMap += `-map 0:1 `
}
const ffmpegCommand = `-loglevel warning -live_start_index -99999 -analyzeduration 1000 -probesize 32 -re -i "${s.dir.streams+d.ke+'/'+d.id}/detectorStream.m3u8" ${outputMap}-movflags faststart+frag_keyframe+empty_moov -fflags +igndts -c:v copy -c:a aac -strict -2 -strftime 1 -y "${s.getVideoDirectory(monitorConfig) + filename}"`
s.debugLog(ffmpegCommand)
2021-01-02 18:30:20 +00:00
activeMonitor.eventBasedRecording.process = spawn(
config.ffmpegDir,
splitForFFPMEG(ffmpegCommand)
2021-01-02 18:30:20 +00:00
)
activeMonitor.eventBasedRecording.process.stderr.on('data',function(data){
s.userLog(d,{
type: logTitleText,
msg: data.toString()
})
})
activeMonitor.eventBasedRecording.process.on('close',function(){
if(!activeMonitor.eventBasedRecording.allowEnd){
s.userLog(d,{
type: logTitleText,
msg: lang["Detector Recording Process Exited Prematurely. Restarting."]
})
runRecord()
return
}
s.insertCompletedVideo(monitorConfig,{
file : filename,
})
s.userLog(d,{
type: logTitleText,
msg: lang["Detector Recording Complete"]
})
s.userLog(d,{
type: logTitleText,
msg: lang["Clear Recorder Process"]
})
delete(activeMonitor.eventBasedRecording.process)
clearTimeout(activeMonitor.eventBasedRecording.timeout)
delete(activeMonitor.eventBasedRecording.timeout)
clearTimeout(activeMonitor.recordingChecker)
})
}
2021-01-02 18:30:20 +00:00
runRecord()
}
2021-01-02 18:30:20 +00:00
}
const closeEventBasedRecording = function(e){
const activeMonitor = s.group[e.ke].activeMonitors[e.id]
if(activeMonitor.eventBasedRecording.process){
clearTimeout(activeMonitor.eventBasedRecording.timeout)
activeMonitor.eventBasedRecording.allowEnd = true
activeMonitor.eventBasedRecording.process.kill('SIGTERM')
}
// var stackedProcesses = s.group[e.ke].activeMonitors[e.id].eventBasedRecording.stackable
// Object.keys(stackedProcesses).forEach(function(key){
// var item = stackedProcesses[key]
// clearTimeout(item.timeout)
// item.allowEnd = true;
// item.process.kill('SIGTERM');
// })
}
const legacyFilterEvents = (x,d) => {
switch(x){
case'archive':
d.videos.forEach(function(v,n){
s.video('archive',v)
})
break;
case'delete':
s.deleteListOfVideos(d.videos)
break;
case'execute':
exec(d.execute,{detached: true})
break;
}
s.onEventTriggerBeforeFilterExtensions.forEach(function(extender){
extender(x,d)
})
}
const sendFramesFromSecondaryOutput = (groupKey,monitorId,timeout) => {
const activeMonitor = s.group[groupKey].activeMonitors[monitorId]
const theEmitter = activeMonitor.secondaryDetectorOutput
if(!activeMonitor.sendingFromSecondaryDetectorOuput){
s.debugLog('start sending object frames',groupKey,monitorId)
theEmitter.on('data',activeMonitor.secondaryDetectorOuputContentWriter = (data) => {
s.ocvTx({
f : 'frame',
mon : s.group[groupKey].rawMonitorConfigurations[monitorId].details,
ke : groupKey,
id : monitorId,
time : s.formattedTime(),
frame : data
})
})
}
clearTimeout(activeMonitor.sendingFromSecondaryDetectorOuput)
activeMonitor.sendingFromSecondaryDetectorOuput = setTimeout(() => {
theEmitter.removeListener('data',activeMonitor.secondaryDetectorOuputContentWriter)
delete(activeMonitor.sendingFromSecondaryDetectorOuput)
},timeout || 5000)
}
const triggerEvent = async (d,forceSave) => {
var didCountingAlready = false
const filter = {
halt : false,
addToMotionCounter : true,
useLock : true,
2021-11-17 02:02:27 +00:00
save : false,
webhook : false,
command : false,
2021-12-04 01:52:40 +00:00
record : true,
forceRecord : false,
indifference : false,
2021-11-17 02:02:27 +00:00
countObjects : false
}
if(!s.group[d.ke] || !s.group[d.ke].activeMonitors[d.id]){
return s.systemLog(lang['No Monitor Found, Ignoring Request'])
}
const monitorConfig = s.group[d.ke].rawMonitorConfigurations[d.id]
if(!monitorConfig){
return s.systemLog(lang['No Monitor Found, Ignoring Request'])
}
const monitorDetails = monitorConfig.details
s.onEventTriggerBeforeFilterExtensions.forEach(function(extender){
extender(d,filter)
})
2021-05-19 06:09:04 +00:00
const eventDetails = d.details
const passedEventFilters = checkEventFilters(d,monitorDetails,filter)
2021-12-05 03:49:25 +00:00
if(!passedEventFilters)return;
const eventTime = new Date()
if(
filter.addToMotionCounter &&
filter.record &&
(
monitorConfig.mode === 'record' ||
monitorConfig.mode === 'start' &&
(
(
monitorDetails.detector_record_method === 'sip' &&
monitorDetails.detector_trigger === '1'
) ||
(
monitorDetails.detector_record_method === 'del' &&
monitorDetails.detector_delete_motionless_videos === '1'
)
)
)
){
addToEventCounter(d)
}
if(
2021-11-17 02:02:27 +00:00
(filter.countObjects || monitorDetails.detector_obj_count === '1') &&
monitorDetails.detector_obj_count_in_region !== '1'
){
didCountingAlready = true
countObjects(d)
}
if(filter.useLock){
const passedMotionLock = checkMotionLock(d,monitorDetails)
if(!passedMotionLock)return
}
2021-02-27 16:39:17 +00:00
const passedObjectInRegionCheck = checkForObjectsInRegions(monitorConfig,eventDetails,filter,d,didCountingAlready)
if(!passedObjectInRegionCheck)return
//
d.doObjectDetection = (
eventDetails.reason !== 'object' &&
s.isAtleatOneDetectorPluginConnected &&
monitorDetails.detector_use_detect_object === '1' &&
monitorDetails.detector_use_motion === '1'
);
if(d.doObjectDetection === true){
sendFramesFromSecondaryOutput(d.ke,d.id)
}
//
if(
monitorDetails.detector_use_motion === '0' ||
d.doObjectDetection !== true
){
runEventExecutions(eventTime,monitorConfig,eventDetails,forceSave,filter,d, triggerEvent)
}
//show client machines the event
s.tx({
f: 'detector_trigger',
id: d.id,
ke: d.ke,
details: eventDetails,
doObjectDetection: d.doObjectDetection
},`DETECTOR_${monitorConfig.ke}${monitorConfig.mid}`);
}
return {
countObjects: countObjects,
isAtleastOneMatrixInRegion: isAtleastOneMatrixInRegion,
scanMatricesforCollisions: scanMatricesforCollisions,
getLargestMatrix: getLargestMatrix,
addToEventCounter: addToEventCounter,
clearEventCounter: clearEventCounter,
getEventsCounted: getEventsCounted,
hasMatrices: hasMatrices,
checkEventFilters: checkEventFilters,
checkMotionLock: checkMotionLock,
runMultiTrigger: runMultiTrigger,
checkForObjectsInRegions: checkForObjectsInRegions,
runEventExecutions: runEventExecutions,
2021-01-02 18:30:20 +00:00
createEventBasedRecording: createEventBasedRecording,
closeEventBasedRecording: closeEventBasedRecording,
legacyFilterEvents: legacyFilterEvents,
triggerEvent: triggerEvent,
2021-03-27 20:04:01 +00:00
addEventDetailsToString: addEventDetailsToString,
getEventBasedRecordingUponCompletion: getEventBasedRecordingUponCompletion,
}
}