add Event Counting engine 0.1
parent
f35136b46c
commit
664a30ee32
|
@ -8,33 +8,16 @@ var SAT = require('sat')
|
|||
var V = SAT.Vector;
|
||||
var P = SAT.Polygon;
|
||||
// Matrix In Region Libs />
|
||||
var objectCountTimeouts = {}
|
||||
module.exports = function(s,config,lang){
|
||||
const clearCountedObjectsForMonitor = async (groupKey,monitorId) => {
|
||||
Object.keys(objectCountTimeouts[groupKey][monitorId]).forEach((objectId) => {
|
||||
clearTimeout(objectCountTimeouts[groupKey][monitorId][objectId])
|
||||
})
|
||||
s.group[groupKey].activeMonitors[monitorId].eventsCounted = {}
|
||||
}
|
||||
const countObjectSetTimeout = async (event,matrixId) => {
|
||||
const eventsCounted = s.group[event.ke].activeMonitors[event.id].eventsCounted || {}
|
||||
if(!objectCountTimeouts[event.ke])objectCountTimeouts[event.ke] = {}
|
||||
if(!objectCountTimeouts[event.ke][event.id])objectCountTimeouts[event.ke][event.id] = {}
|
||||
clearTimeout(objectCountTimeouts[event.ke][event.id][matrixId])
|
||||
objectCountTimeouts[event.ke][event.id][matrixId] = setTimeout(() => {
|
||||
delete(eventsCounted[matrixId])
|
||||
},10000)
|
||||
}
|
||||
const countObjects = async (event) => {
|
||||
const matrices = event.details.matrices
|
||||
const eventsCounted = s.group[event.ke].activeMonitors[event.id].eventsCounted || {}
|
||||
if(matrices){
|
||||
const currentTime = new Date()
|
||||
matrices.forEach((matrix)=>{
|
||||
const id = !isNaN(matrix.id) ? matrix.id + '_' + matrix.tag : matrix.tag
|
||||
if(!eventsCounted[id])eventsCounted[id] = 0
|
||||
++eventsCounted[id]
|
||||
// countObjectSetTimeout(event,id)
|
||||
if(!eventsCounted[id])eventsCounted[id] = {times: [], count: 0}
|
||||
++eventsCounted[id].count
|
||||
eventsCounted[id].times.push(new Date().getTime())
|
||||
})
|
||||
}
|
||||
return eventsCounted
|
||||
|
@ -483,5 +466,4 @@ module.exports = function(s,config,lang){
|
|||
// item.process.kill('SIGTERM');
|
||||
// })
|
||||
}
|
||||
s.clearCountedObjectsForMonitor = clearCountedObjectsForMonitor
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ var SoundDetection = require('shinobi-sound-detection')
|
|||
var async = require("async");
|
||||
var URL = require('url')
|
||||
module.exports = function(s,config,lang){
|
||||
var objectCountIntervals = {}
|
||||
const startMonitorInQueue = async.queue(function(action, callback) {
|
||||
setTimeout(function(){
|
||||
action(callback)
|
||||
|
@ -401,6 +402,7 @@ module.exports = function(s,config,lang){
|
|||
delete(activeMonitor.detectorFrameSaveBuffer);
|
||||
clearTimeout(activeMonitor.recordingSnapper);
|
||||
clearInterval(activeMonitor.getMonitorCpuUsage);
|
||||
clearInterval(objectCountIntervals[e.ke][e.id]);
|
||||
if(activeMonitor.onChildNodeExit){
|
||||
activeMonitor.onChildNodeExit()
|
||||
}
|
||||
|
@ -1009,6 +1011,42 @@ module.exports = function(s,config,lang){
|
|||
},1000 * 60)
|
||||
}
|
||||
}
|
||||
const createEventCounter = function(monitor){
|
||||
if(monitor.details.detector_obj_count === '1'){
|
||||
const activeMonitor = s.group[monitor.ke].activeMonitors[monitor.id]
|
||||
activeMonitor.eventsCountStartTime = new Date()
|
||||
const eventsCounted = activeMonitor.eventsCounted || {}
|
||||
if(!objectCountIntervals[monitor.ke])objectCountIntervals[monitor.ke] = {}
|
||||
if(!objectCountIntervals[monitor.ke][monitor.id])objectCountIntervals[monitor.ke][monitor.id] = {}
|
||||
clearInterval(objectCountIntervals[monitor.ke][monitor.id])
|
||||
objectCountIntervals[monitor.ke][monitor.id] = setInterval(() => {
|
||||
const countsToSave = Object.assign(eventsCounted,{})
|
||||
activeMonitor.eventsCounted = {}
|
||||
const groupKey = monitor.ke
|
||||
const monitorId = monitor.id
|
||||
const startTime = new Date(activeMonitor.eventsCountStartTime + 0)
|
||||
const endTime = new Date()
|
||||
const countedKeys = Object.keys(countsToSave)
|
||||
activeMonitor.eventsCountStartTime = new Date()
|
||||
if(countedKeys.length > 0)countedKeys.forEach((tag) => {
|
||||
const tagInfo = countsToSave[tag]
|
||||
const count = tagInfo.count
|
||||
const times = tagInfo.times
|
||||
s.sqlQuery('INSERT INTO `Events Counts` (ke,mid,details,time,end,count,tag) VALUES (?,?,?,?,?,?,?)',[
|
||||
groupKey,
|
||||
monitorId,
|
||||
JSON.stringify({
|
||||
times: times
|
||||
}),
|
||||
startTime,
|
||||
endTime,
|
||||
count,
|
||||
tag
|
||||
])
|
||||
})
|
||||
},60000) //every minute
|
||||
}
|
||||
}
|
||||
const createCameraStreamHandlers = function(e){
|
||||
s.group[e.ke].activeMonitors[e.id].spawn.stdio[5].on('data',function(data){
|
||||
resetStreamCheck(e)
|
||||
|
@ -1442,6 +1480,7 @@ module.exports = function(s,config,lang){
|
|||
try{
|
||||
createCameraFfmpegProcess(e)
|
||||
createCameraStreamHandlers(e)
|
||||
createEventCounter(e)
|
||||
if(e.type === 'dashcam'){
|
||||
setTimeout(function(){
|
||||
activeMonitor.allowStdinWrite = true
|
||||
|
|
|
@ -140,7 +140,7 @@ module.exports = function(s,config){
|
|||
if(err)console.error(err)
|
||||
},true)
|
||||
//add Cloud Timelapse Frames table, will remove in future
|
||||
s.sqlQuery('CREATE TABLE IF NOT EXISTS `Cloud Timelapse Frames` (`ke` varchar(50) NOT NULL,`mid` varchar(50) NOT NULL,`href` text NOT NULL,`details` longtext,`filename` varchar(50) NOT NULL,`time` timestamp NULL DEFAULT NULL,`size` int(11) NOT NULL)' + mySQLtail + ';',[],function(err){
|
||||
s.sqlQuery('CREATE TABLE `Events Counts` (`ke` varchar(50) NOT NULL,`mid` varchar(50) NOT NULL,`details` longtext NOT NULL,`time` timestamp NOT NULL DEFAULT current_timestamp(),`end` timestamp NOT NULL DEFAULT current_timestamp(),`count` int(10) NOT NULL DEFAULT 1,`tag` varchar(30) DEFAULT NULL)' + mySQLtail + ';',[],function(err){
|
||||
if(err)console.error(err)
|
||||
},true)
|
||||
//create Files table
|
||||
|
|
|
@ -1793,25 +1793,9 @@ module.exports = function(s,config,lang,app,io){
|
|||
},res,req);
|
||||
})
|
||||
/**
|
||||
* API : Object Detection Counter Reset
|
||||
*/
|
||||
app.get(config.webPaths.apiPrefix+':auth/counterReset/:ke/:id', function (req,res){
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
s.auth(req.params,function(user){
|
||||
if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){
|
||||
res.end(user.lang['Not Permitted'])
|
||||
return
|
||||
}
|
||||
s.clearCountedObjectsForMonitor(req.params.ke,req.params.id)
|
||||
res.end(s.prettyPrint({
|
||||
ok: true
|
||||
}))
|
||||
},res,req);
|
||||
})
|
||||
/**
|
||||
* API : Object Detection Counter Status
|
||||
*/
|
||||
app.get(config.webPaths.apiPrefix+':auth/counterStatus/:ke/:id', function (req,res){
|
||||
app.get(config.webPaths.apiPrefix+':auth/eventCountStatus/:ke/:id', function (req,res){
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
s.auth(req.params,function(user){
|
||||
if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){
|
||||
|
@ -1827,6 +1811,120 @@ module.exports = function(s,config,lang,app,io){
|
|||
},res,req);
|
||||
})
|
||||
/**
|
||||
* API : Object Detection Counter Status
|
||||
*/
|
||||
app.get([
|
||||
config.webPaths.apiPrefix+':auth/eventCounts/:ke',
|
||||
config.webPaths.apiPrefix+':auth/eventCounts/:ke/:id'
|
||||
], function (req,res){
|
||||
res.setHeader('Content-Type', 'application/json')
|
||||
s.auth(req.params,function(user){
|
||||
var hasRestrictions = user.details.sub && user.details.allmonitors !== '1'
|
||||
if(
|
||||
user.permissions.watch_videos==="0" ||
|
||||
hasRestrictions && (!user.details.video_view || user.details.video_view.indexOf(req.params.id)===-1)
|
||||
){
|
||||
res.end(s.prettyPrint([]))
|
||||
return
|
||||
}
|
||||
var origURL = req.originalUrl.split('/')
|
||||
var videoParam = origURL[origURL.indexOf(req.params.auth) + 1]
|
||||
req.sql = 'SELECT * FROM `Events Counts` WHERE ke=?';req.ar=[req.params.ke];
|
||||
req.count_sql='SELECT COUNT(*) FROM `Events Counts` WHERE ke=?';req.count_ar=[req.params.ke];
|
||||
if(req.query.archived=='1'){
|
||||
req.sql+=' AND details LIKE \'%"archived":"1"\''
|
||||
req.count_sql+=' AND details LIKE \'%"archived":"1"\''
|
||||
}
|
||||
if(!req.params.id){
|
||||
if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){
|
||||
try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){}
|
||||
req.or=[];
|
||||
user.details.monitors.forEach(function(v,n){
|
||||
req.or.push('mid=?');req.ar.push(v)
|
||||
})
|
||||
req.sql+=' AND ('+req.or.join(' OR ')+')'
|
||||
req.count_sql+=' AND ('+req.or.join(' OR ')+')'
|
||||
}
|
||||
}else{
|
||||
if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){
|
||||
req.sql+=' and mid=?';req.ar.push(req.params.id)
|
||||
req.count_sql+=' and mid=?';req.count_ar.push(req.params.id)
|
||||
}else{
|
||||
res.end('[]');
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(req.query.start||req.query.end){
|
||||
if(req.query.start && req.query.start !== ''){
|
||||
req.query.start = s.stringToSqlTime(req.query.start)
|
||||
}
|
||||
if(req.query.end && req.query.end !== ''){
|
||||
req.query.end = s.stringToSqlTime(req.query.end)
|
||||
}
|
||||
if(!req.query.startOperator||req.query.startOperator==''){
|
||||
req.query.startOperator='>='
|
||||
}
|
||||
if(!req.query.endOperator||req.query.endOperator==''){
|
||||
req.query.endOperator='<='
|
||||
}
|
||||
var endIsStartTo
|
||||
var theEndParameter = '`end`'
|
||||
if(req.query.endIsStartTo){
|
||||
endIsStartTo = true
|
||||
theEndParameter = '`time`'
|
||||
}
|
||||
switch(true){
|
||||
case(req.query.start&&req.query.start!==''&&req.query.end&&req.query.end!==''):
|
||||
req.sql+=' AND `time` '+req.query.startOperator+' ? AND '+theEndParameter+' '+req.query.endOperator+' ?';
|
||||
req.count_sql+=' AND `time` '+req.query.startOperator+' ? AND '+theEndParameter+' '+req.query.endOperator+' ?';
|
||||
req.ar.push(req.query.start)
|
||||
req.ar.push(req.query.end)
|
||||
req.count_ar.push(req.query.start)
|
||||
req.count_ar.push(req.query.end)
|
||||
break;
|
||||
case(req.query.start&&req.query.start!==''):
|
||||
req.sql+=' AND `time` '+req.query.startOperator+' ?';
|
||||
req.count_sql+=' AND `time` '+req.query.startOperator+' ?';
|
||||
req.ar.push(req.query.start)
|
||||
req.count_ar.push(req.query.start)
|
||||
break;
|
||||
case(req.query.end&&req.query.end!==''):
|
||||
req.sql+=' AND '+theEndParameter+' '+req.query.endOperator+' ?';
|
||||
req.count_sql+=' AND '+theEndParameter+' '+req.query.endOperator+' ?';
|
||||
req.ar.push(req.query.end)
|
||||
req.count_ar.push(req.query.end)
|
||||
break;
|
||||
}
|
||||
}
|
||||
req.sql+=' ORDER BY `time` DESC';
|
||||
if(!req.query.limit||req.query.limit==''){
|
||||
req.query.limit='100'
|
||||
}
|
||||
if(req.query.limit!=='0'){
|
||||
req.sql+=' LIMIT '+req.query.limit
|
||||
}
|
||||
s.sqlQuery(req.sql,req.ar,function(err,r){
|
||||
if(!r){
|
||||
res.end(s.prettyPrint({total:0,limit:req.query.limit,skip:0,counts:[]}));
|
||||
return
|
||||
}
|
||||
r.forEach((row) => {
|
||||
row.details = JSON.parse(row.details)
|
||||
})
|
||||
s.sqlQuery(req.count_sql,req.count_ar,function(err,count){
|
||||
if(req.query.limit.indexOf(',')>-1){
|
||||
req.skip=parseInt(req.query.limit.split(',')[0])
|
||||
req.query.limit=parseInt(req.query.limit.split(',')[1])
|
||||
}else{
|
||||
req.skip=0
|
||||
req.query.limit=parseInt(req.query.limit)
|
||||
}
|
||||
res.end(s.prettyPrint({isUTC:config.useUTC,total:count[0]['COUNT(*)'],limit:req.query.limit,skip:req.skip,counts:r,endIsStartTo:endIsStartTo}));
|
||||
})
|
||||
})
|
||||
},res,req);
|
||||
})
|
||||
/**
|
||||
* API : Camera PTZ Controller
|
||||
*/
|
||||
app.get(config.webPaths.apiPrefix+':auth/control/:ke/:id/:direction', function (req,res){
|
||||
|
|
|
@ -158,6 +158,17 @@ CREATE TABLE IF NOT EXISTS `Timelapse Frames` (
|
|||
`size` int(11) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- Dumping structure for table ccio.Events Counts
|
||||
CREATE TABLE `Events Counts` (
|
||||
`ke` varchar(50) NOT NULL,
|
||||
`mid` varchar(50) NOT NULL,
|
||||
`details` longtext NOT NULL,
|
||||
`time` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`end` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`count` int(10) NOT NULL DEFAULT 1,
|
||||
`tag` varchar(30) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- Data exporting was unselected.
|
||||
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||
|
|
Loading…
Reference in New Issue