Merge branch 'dev-region-testing' into 'dev'
Add support for Region Name testing into detection filters See merge request Shinobi-Systems/Shinobi!203merge-requests/210/head
commit
98bc29e8eb
197
libs/events.js
197
libs/events.js
|
|
@ -53,6 +53,31 @@ module.exports = function(s,config,lang){
|
|||
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 nonEmpty = (element) => element.length !== 0;
|
||||
const moveLock = {}
|
||||
const getLargestMatrix = (matrices) => {
|
||||
var largestMatrix = {width: 0, height: 0}
|
||||
|
|
@ -161,13 +186,14 @@ module.exports = function(s,config,lang){
|
|||
s.onEventTriggerBeforeFilterExtensions.forEach(function(extender){
|
||||
extender(d,filter)
|
||||
})
|
||||
var detailString = JSON.stringify(d.details);
|
||||
if(!s.group[d.ke]||!s.group[d.ke].activeMonitors[d.id]){
|
||||
return s.systemLog(lang['No Monitor Found, Ignoring Request'])
|
||||
}
|
||||
d.mon=s.group[d.ke].rawMonitorConfigurations[d.id];
|
||||
var currentConfig = s.group[d.ke].rawMonitorConfigurations[d.id].details
|
||||
var hasMatrices = (d.details.matrices && d.details.matrices.length > 0)
|
||||
var allMatrices = d.details.matrices
|
||||
var matchedMatrices = []
|
||||
//read filters
|
||||
if(
|
||||
currentConfig.use_detector_filters === '1' &&
|
||||
|
|
@ -192,74 +218,126 @@ module.exports = function(s,config,lang){
|
|||
}
|
||||
return newVal
|
||||
}
|
||||
var defaultDrop = true; // forces unmatched events to be dropped
|
||||
var testMatrices = [...allMatrices] // default
|
||||
var filters = currentConfig.detector_filters
|
||||
var hasFilters = (filters.length > 0)
|
||||
Object.keys(filters).forEach(function(key){
|
||||
var conditionChain = {}
|
||||
testMatrices = [...allMatrices] // for new filter reset the matrices to be tested against
|
||||
var dFilter = filters[key]
|
||||
dFilter.where.forEach(function(condition,place){
|
||||
conditionChain[place] = {ok:false,next:condition.p4,matrixCount:0}
|
||||
if(d.details.matrices)conditionChain[place].matrixCount = d.details.matrices.length
|
||||
if(testMatrices)conditionChain[place].matrixCount = testMatrices.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
|
||||
}
|
||||
conditionChain[place].ok = true
|
||||
}
|
||||
var fail = function(){
|
||||
if (matrixPosition !== undefined) delete(testMatrices[matrixPosition])
|
||||
}
|
||||
switch(condition.p2){
|
||||
case'indexOf':
|
||||
if(param.indexOf(condition.p3) > -1){
|
||||
pass()
|
||||
} else {
|
||||
fail()
|
||||
}
|
||||
break;
|
||||
case'!indexOf':
|
||||
if(param.indexOf(condition.p3) === -1){
|
||||
pass()
|
||||
} else {
|
||||
fail()
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(eval('param '+condition.p2+' "'+condition.p3.replace(/"/g,'\\"')+'"')){
|
||||
pass()
|
||||
} else {
|
||||
fail()
|
||||
}
|
||||
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
|
||||
if(eval('nowAddedInSeconds '+condition.p2+' conditionAddedInSeconds')){
|
||||
conditionChain[place].ok = true
|
||||
if (testMatrices.some(nonEmpty)){
|
||||
switch(condition.p1){
|
||||
case'tag':
|
||||
case'x':
|
||||
case'y':
|
||||
case'height':
|
||||
case'width':
|
||||
case'confidence':
|
||||
if(testMatrices){
|
||||
testMatrices.forEach(function(matrix,position){
|
||||
if (matrix) modifyFilters(matrix,position)
|
||||
})
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
modifyFilters(d.details)
|
||||
break;
|
||||
break;
|
||||
case'name':
|
||||
if (testMatrices){
|
||||
var regions = s.group[d.ke].activeMonitors[d.id].parsedObjects.cords
|
||||
regions.forEach(function(region,position){
|
||||
switch(condition.p2){
|
||||
case'indexOf':
|
||||
if(region.name.indexOf(condition.p3) > -1){
|
||||
testMatrices = testMatrices.concat(scanMatricesforCollisions(region,testMatrices));
|
||||
if(testMatrices.some(nonEmpty)) conditionChain[place].ok = true; // default is false
|
||||
}
|
||||
break;
|
||||
case'!indexOf':
|
||||
if(region.name.indexOf(condition.p3) === -1){
|
||||
testMatrices = testMatrices.concat(scanMatricesforCollisions(region,testMatrices));
|
||||
if(testMatrices.some(nonEmpty)) conditionChain[place].ok = true; // default is false
|
||||
}
|
||||
break;
|
||||
case'===':
|
||||
if(region.name === condition.p3){
|
||||
testMatrices = scanMatricesforCollisions(region,testMatrices);
|
||||
if(testMatrices.some(nonEmpty)) conditionChain[place].ok = true; // default is false
|
||||
}
|
||||
break;
|
||||
case'!==':
|
||||
if(region.name !== condition.p3){
|
||||
testMatrices = testMatrices.concat(scanMatricesforCollisions(region,testMatrices));
|
||||
if(testMatrices.some(nonEmpty)) conditionChain[place].ok = true; // default is false
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//s.systemLog(lang['Numeric criteria unsupported for Region tests, Ignoring Conditional'])
|
||||
s.systemLog('Numeric criteria unsupported for Region tests, Ignoring Conditional')
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
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
|
||||
if(eval('nowAddedInSeconds '+condition.p2+' conditionAddedInSeconds')){
|
||||
conditionChain[place].ok = true
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
modifyFilters(d.details)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (condition.p4 === '||' || dFilter.where.length-1 === place){
|
||||
if (testMatrices.length > 0) matchedMatrices = matchedMatrices.concat(testMatrices)
|
||||
testMatrices = [...allMatrices] // reset matrices for next group of conditions
|
||||
}
|
||||
})
|
||||
var conditionArray = Object.values(conditionChain)
|
||||
|
|
@ -277,19 +355,28 @@ module.exports = function(s,config,lang){
|
|||
var value = dFilter.actions[key]
|
||||
filter[key] = parseValue(key,value)
|
||||
})
|
||||
defaultDrop = false;
|
||||
}else{
|
||||
filter.halt = true
|
||||
}
|
||||
}
|
||||
})
|
||||
if(d.details.matrices && d.details.matrices.length === 0 || filter.halt === true){
|
||||
if(filter.halt === true){
|
||||
return
|
||||
}else if(hasMatrices){
|
||||
var reviewedMatrix = []
|
||||
d.details.matrices.forEach(function(matrix){
|
||||
if(matrix)reviewedMatrix.push(matrix)
|
||||
})
|
||||
d.details.matrices = reviewedMatrix
|
||||
// remove empty elements
|
||||
matchedMatrices = matchedMatrices.filter(value => Object.keys(value).length !== 0)
|
||||
// remove duplicate matches
|
||||
matchedMatrices = matchedMatrices.filter((matrix, index, self) =>
|
||||
index === self.findIndex((t) => (
|
||||
t.x === matrix.x && t.y === matrix.y && t.tag === matrix.tag && t.confidence === matrix.confidence
|
||||
))
|
||||
)
|
||||
d.details.matrices = matchedMatrices
|
||||
}
|
||||
// -- delayed decision here --
|
||||
if (defaultDrop && hasFilters) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
var eventTime = new Date()
|
||||
|
|
@ -325,8 +412,21 @@ module.exports = function(s,config,lang){
|
|||
// check if object should be in region
|
||||
if(hasMatrices && currentConfig.detector_obj_region === '1'){
|
||||
var regions = s.group[d.ke].activeMonitors[d.id].parsedObjects.cords
|
||||
var isMatrixInRegions = isAtleastOneMatrixInRegion(regions,d.details.matrices)
|
||||
if(isMatrixInRegions){
|
||||
testMatrices = d.details.matrices // matrices that made it passed filters
|
||||
matchedMatrices = []
|
||||
regions.forEach(function(region,position){
|
||||
matchedMatrices = matchedMatrices.concat(scanMatricesforCollisions(region,testMatrices));
|
||||
})
|
||||
if (matchedMatrices.length > 2){
|
||||
// remove duplicate matches
|
||||
matchedMatrices = matchedMatrices.filter((matrix, index, self) =>
|
||||
index === self.findIndex((t) => (
|
||||
t.x === matrix.x && t.y === matrix.y && t.tag === matrix.tag && t.confidence === matrix.confidence
|
||||
))
|
||||
)
|
||||
}
|
||||
d.details.matrices = matchedMatrices // pass matrices that are within a region
|
||||
if(d.details.matrices && d.details.matrices.length > 0){
|
||||
s.debugLog('Matrix in region!')
|
||||
if(filter.countObjects && currentConfig.detector_obj_count === '1' && currentConfig.detector_obj_count_in_region === '1' && !didCountingAlready){
|
||||
countObjects(d)
|
||||
|
|
@ -369,6 +469,7 @@ module.exports = function(s,config,lang){
|
|||
}
|
||||
//save this detection result in SQL, only coords. not image.
|
||||
if(forceSave || (filter.save && currentConfig.detector_save === '1')){
|
||||
var detailString = JSON.stringify(d.details);
|
||||
s.sqlQuery('INSERT INTO Events (ke,mid,details,time) VALUES (?,?,?,?)',[d.ke,d.id,detailString,eventTime])
|
||||
}
|
||||
if(currentConfig.detector === '1' && currentConfig.detector_notrigger === '1'){
|
||||
|
|
|
|||
Loading…
Reference in New Issue