Plugin Framework Upgrades
parent
01db3ac7a9
commit
db9895a236
|
@ -3151,12 +3151,30 @@ module.exports = function(s,config,lang){
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
hidden: true,
|
||||||
|
"id": "detectorsSelected",
|
||||||
|
"name": "detail=detectors_selected",
|
||||||
|
"field": lang["Detectors Selected"],
|
||||||
|
"description": lang.fieldTextDetectorsSelected,
|
||||||
|
"default": "all",
|
||||||
|
"attribute": "multiple",
|
||||||
|
"fieldType": "select",
|
||||||
|
"form-group-class": "h_casc_input h_casc_1",
|
||||||
|
"possible": [
|
||||||
|
{
|
||||||
|
"name": `${lang.All} (${lang.Default})`,
|
||||||
|
"value": "all"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "detail=detector_object_ignore_not_move",
|
"name": "detail=detector_object_ignore_not_move",
|
||||||
"field": lang["Ignore Non-Moving"],
|
"field": lang["Ignore Non-Moving"],
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldType": "select",
|
"fieldType": "select",
|
||||||
"selector": "h_obj_ignore_move",
|
"selector": "h_obj_ignore_move",
|
||||||
|
"form-group-class": "h_casc_input h_casc_1",
|
||||||
"possible": [
|
"possible": [
|
||||||
{
|
{
|
||||||
"name": lang.No,
|
"name": lang.No,
|
||||||
|
@ -3183,6 +3201,7 @@ module.exports = function(s,config,lang){
|
||||||
"description": lang["fieldTextDetectorSendFramesObject"],
|
"description": lang["fieldTextDetectorSendFramesObject"],
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"fieldType": "select",
|
"fieldType": "select",
|
||||||
|
"form-group-class": "h_casc_input h_casc_1",
|
||||||
"possible": [
|
"possible": [
|
||||||
{
|
{
|
||||||
"name": lang.No,
|
"name": lang.No,
|
||||||
|
@ -3222,6 +3241,7 @@ module.exports = function(s,config,lang){
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"example": "",
|
"example": "",
|
||||||
"fieldType": "select",
|
"fieldType": "select",
|
||||||
|
"form-group-class": "h_casc_input h_casc_1",
|
||||||
"possible": [
|
"possible": [
|
||||||
{
|
{
|
||||||
"name": lang.No,
|
"name": lang.No,
|
||||||
|
@ -3242,6 +3262,7 @@ module.exports = function(s,config,lang){
|
||||||
"example": "",
|
"example": "",
|
||||||
"selector": "h_det_mot_fir",
|
"selector": "h_det_mot_fir",
|
||||||
"fieldType": "select",
|
"fieldType": "select",
|
||||||
|
"form-group-class": "h_casc_input h_casc_1",
|
||||||
"possible": [
|
"possible": [
|
||||||
{
|
{
|
||||||
"name": lang.No,
|
"name": lang.No,
|
||||||
|
@ -3290,7 +3311,6 @@ module.exports = function(s,config,lang){
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isAdvanced: true,
|
|
||||||
hidden: true,
|
hidden: true,
|
||||||
"name": lang['Event-Based Recording'],
|
"name": lang['Event-Based Recording'],
|
||||||
"input-mapping": "detector_sip_buffer",
|
"input-mapping": "detector_sip_buffer",
|
||||||
|
|
|
@ -544,6 +544,7 @@
|
||||||
"Time-lapse Tool": "Time-lapse Tool",
|
"Time-lapse Tool": "Time-lapse Tool",
|
||||||
"total": "total",
|
"total": "total",
|
||||||
"MB": "MB",
|
"MB": "MB",
|
||||||
|
"All": "All",
|
||||||
"Calendar": "Calendar",
|
"Calendar": "Calendar",
|
||||||
"Leave blank for random.": "Leave blank for random.",
|
"Leave blank for random.": "Leave blank for random.",
|
||||||
"Currently viewing": "Currently viewing",
|
"Currently viewing": "Currently viewing",
|
||||||
|
@ -697,6 +698,7 @@
|
||||||
"Minutes": "Minutes",
|
"Minutes": "Minutes",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
"Detector": "Detector",
|
"Detector": "Detector",
|
||||||
|
"Detectors Selected": "Detectors Selected",
|
||||||
"Audio Detector": "Audio Detector",
|
"Audio Detector": "Audio Detector",
|
||||||
"Audio Detection": "Audio Detection",
|
"Audio Detection": "Audio Detection",
|
||||||
"Minimum dB": "Minimum dB",
|
"Minimum dB": "Minimum dB",
|
||||||
|
@ -1218,6 +1220,7 @@
|
||||||
"Preview": "Preview",
|
"Preview": "Preview",
|
||||||
"Websocket Connected": "Websocket Connected",
|
"Websocket Connected": "Websocket Connected",
|
||||||
"Websocket Disconnected": "Websocket Disconnected",
|
"Websocket Disconnected": "Websocket Disconnected",
|
||||||
|
"Disconnected": "Disconnected",
|
||||||
"Videos Merge": "Videos Merge",
|
"Videos Merge": "Videos Merge",
|
||||||
"Channel ID": "Channel ID",
|
"Channel ID": "Channel ID",
|
||||||
"Recipient ID": "Recipient ID",
|
"Recipient ID": "Recipient ID",
|
||||||
|
@ -1588,6 +1591,7 @@
|
||||||
"MQTT Client": "MQTT Client",
|
"MQTT Client": "MQTT Client",
|
||||||
"Buffer Time from Event": "Buffer Time from Event",
|
"Buffer Time from Event": "Buffer Time from Event",
|
||||||
"detected": "detected",
|
"detected": "detected",
|
||||||
|
"fieldTextDetectorsSelected": "Select which detectors to send frames to.",
|
||||||
"fieldTextEventFilters": "Enable to have all Events honor your Event Filter rules.",
|
"fieldTextEventFilters": "Enable to have all Events honor your Event Filter rules.",
|
||||||
"fieldTextBufferTimeFromEvent": "The amount of seconds to record before the trigger happened. If this is consistently inaccurate you will need to look at the <a target='_blank' href='https://hub.shinobi.video/articles/view/DmWIID78VtvEfnf'>optimization guide</a> or force encoding on the server.",
|
"fieldTextBufferTimeFromEvent": "The amount of seconds to record before the trigger happened. If this is consistently inaccurate you will need to look at the <a target='_blank' href='https://hub.shinobi.video/articles/view/DmWIID78VtvEfnf'>optimization guide</a> or force encoding on the server.",
|
||||||
"fieldTextMode": "This is the primary task of the monitor.",
|
"fieldTextMode": "This is the primary task of the monitor.",
|
||||||
|
@ -1932,6 +1936,8 @@
|
||||||
"HowToConnectDes1": "<b>This feature is available to Mobile License subscribers.</b> To get an API Key please login to your <a href='https: //licenses.shinobi.video/login' target='_blank'>Shinobi<b>Shop</b></a> account and create a key associated to <b>any active Subscription ID</b>. <a href='https://hub.shinobi.video/articles/view/3Yhivc6djTtuBPE' target='_blank'>Learn More.</a>",
|
"HowToConnectDes1": "<b>This feature is available to Mobile License subscribers.</b> To get an API Key please login to your <a href='https: //licenses.shinobi.video/login' target='_blank'>Shinobi<b>Shop</b></a> account and create a key associated to <b>any active Subscription ID</b>. <a href='https://hub.shinobi.video/articles/view/3Yhivc6djTtuBPE' target='_blank'>Learn More.</a>",
|
||||||
"HowToConnectDes2": "If you would like to get access to a private (dedicated) P2P server please create an account at the <a href='https: //licenses.shinobi.video/login' target='_blank'>Shinobi<b>Shop</b></a> and contact us via the Live Chat widget",
|
"HowToConnectDes2": "If you would like to get access to a private (dedicated) P2P server please create an account at the <a href='https: //licenses.shinobi.video/login' target='_blank'>Shinobi<b>Shop</b></a> and contact us via the Live Chat widget",
|
||||||
"User": "User",
|
"User": "User",
|
||||||
|
"Save Unknown Faces": "Save Unknown Faces",
|
||||||
|
"saveUnknownFacesFieldText": "Save Unknown faces to the Face Manager. Manual sorting may still be required.",
|
||||||
"Current Version": "Current Version",
|
"Current Version": "Current Version",
|
||||||
"Default is Global value": "Default is Global value",
|
"Default is Global value": "Default is Global value",
|
||||||
"rejectUnauth": "Ignore server certificate"
|
"rejectUnauth": "Ignore server certificate"
|
||||||
|
|
|
@ -40,7 +40,7 @@ module.exports = (s,config,lang) => {
|
||||||
const monitorId = options.mid || options.id
|
const monitorId = options.mid || options.id
|
||||||
const groupKey = options.ke
|
const groupKey = options.ke
|
||||||
//if(!frameBuffer || imageSaveEventLock[groupKey + monitorId])return;
|
//if(!frameBuffer || imageSaveEventLock[groupKey + monitorId])return;
|
||||||
if(!frameBuffer || frameBuffer.length === 0 || imageSaveEventLock[groupKey + monitorId]) return;
|
if(!frameBuffer || frameBuffer.length === 0 || imageSaveEventLock[groupKey + monitorId]) return;
|
||||||
const eventTime = options.time
|
const eventTime = options.time
|
||||||
const objectsFound = options.matrices
|
const objectsFound = options.matrices
|
||||||
const monitorConfig = Object.assign({id: monitorId},s.group[groupKey].rawMonitorConfigurations[monitorId])
|
const monitorConfig = Object.assign({id: monitorId},s.group[groupKey].rawMonitorConfigurations[monitorId])
|
||||||
|
@ -678,17 +678,37 @@ module.exports = (s,config,lang) => {
|
||||||
const activeMonitor = s.group[groupKey].activeMonitors[monitorId]
|
const activeMonitor = s.group[groupKey].activeMonitors[monitorId]
|
||||||
const theEmitter = activeMonitor.secondaryDetectorOutput
|
const theEmitter = activeMonitor.secondaryDetectorOutput
|
||||||
if(!activeMonitor.sendingFromSecondaryDetectorOuput){
|
if(!activeMonitor.sendingFromSecondaryDetectorOuput){
|
||||||
s.debugLog('start sending object frames',groupKey,monitorId)
|
const monitorConfig = s.group[groupKey].rawMonitorConfigurations[monitorId]
|
||||||
theEmitter.on('data',activeMonitor.secondaryDetectorOuputContentWriter = (data) => {
|
const monitorDetails = monitorConfig.details;
|
||||||
|
let chosenDetector = monitorDetails.detectors_selected;
|
||||||
|
if(chosenDetector instanceof Array)chosenDetector = chosenDetector.join(',');
|
||||||
|
let sendToDetector = (data) => {
|
||||||
s.ocvTx({
|
s.ocvTx({
|
||||||
f : 'frame',
|
f : 'frame',
|
||||||
mon : s.group[groupKey].rawMonitorConfigurations[monitorId].details,
|
mon : monitorDetails,
|
||||||
ke : groupKey,
|
ke : groupKey,
|
||||||
id : monitorId,
|
id : monitorId,
|
||||||
time : s.formattedTime(),
|
time : s.formattedTime(),
|
||||||
frame : data
|
frame : data
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
if(chosenDetector && !(chosenDetector.includes('all'))){
|
||||||
|
const pluginsGettingIt = chosenDetector.split(',').map(item => item.trim()).filter(item => !!item);
|
||||||
|
sendToDetector = (data) => {
|
||||||
|
for(pluginName of pluginsGettingIt){
|
||||||
|
s.sendToDetector(pluginName, {
|
||||||
|
f : 'frame',
|
||||||
|
mon : monitorDetails,
|
||||||
|
ke : groupKey,
|
||||||
|
id : monitorId,
|
||||||
|
time : s.formattedTime(),
|
||||||
|
frame : data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.debugLog('start sending object frames',groupKey,monitorId)
|
||||||
|
theEmitter.on('data', activeMonitor.secondaryDetectorOuputContentWriter = sendToDetector)
|
||||||
}
|
}
|
||||||
clearTimeout(activeMonitor.sendingFromSecondaryDetectorOuput)
|
clearTimeout(activeMonitor.sendingFromSecondaryDetectorOuput)
|
||||||
activeMonitor.sendingFromSecondaryDetectorOuput = setTimeout(() => {
|
activeMonitor.sendingFromSecondaryDetectorOuput = setTimeout(() => {
|
||||||
|
|
|
@ -87,6 +87,8 @@ module.exports = function(s,config){
|
||||||
createExtension(`onSubscriptionCheck`)
|
createExtension(`onSubscriptionCheck`)
|
||||||
createExtension(`onDataPortMessage`)
|
createExtension(`onDataPortMessage`)
|
||||||
createExtension(`onHttpRequestUpgrade`,null,true)
|
createExtension(`onHttpRequestUpgrade`,null,true)
|
||||||
|
createExtension(`onPluginConnected`)
|
||||||
|
createExtension(`onPluginDisconnected`)
|
||||||
/////// CRON ////////
|
/////// CRON ////////
|
||||||
createExtension(`onCronGroupProcessed`)
|
createExtension(`onCronGroupProcessed`)
|
||||||
createExtension(`onCronGroupProcessedAwaited`)
|
createExtension(`onCronGroupProcessedAwaited`)
|
||||||
|
|
|
@ -1186,7 +1186,6 @@ module.exports = (s,config,lang) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if(e.details.detector === '1'){
|
if(e.details.detector === '1'){
|
||||||
s.ocvTx({f:'init_monitor',id:monitorId,ke:groupKey})
|
|
||||||
//frames from motion detect
|
//frames from motion detect
|
||||||
if(e.details.detector_pam === '1'){
|
if(e.details.detector_pam === '1'){
|
||||||
// activeMonitor.spawn.stdio[3].pipe(activeMonitor.p2p).pipe(activeMonitor.pamDiff)
|
// activeMonitor.spawn.stdio[3].pipe(activeMonitor.p2p).pipe(activeMonitor.pamDiff)
|
||||||
|
|
|
@ -43,18 +43,7 @@ module.exports = function(s,config,lang,app,io){
|
||||||
s.detectorPluginArray = []
|
s.detectorPluginArray = []
|
||||||
s.isAtleatOneDetectorPluginConnected = false
|
s.isAtleatOneDetectorPluginConnected = false
|
||||||
s.addDetectorPlugin = function(name,d){
|
s.addDetectorPlugin = function(name,d){
|
||||||
if(config.useOldPluginConnectionMethod === true){
|
const newDetector = {
|
||||||
s.ocv = {
|
|
||||||
started: s.timeObject(),
|
|
||||||
id: d.id,
|
|
||||||
plug: d.plug,
|
|
||||||
notice: d.notice,
|
|
||||||
isClientPlugin: d.isClientPlugin,
|
|
||||||
isHostPlugin: d.isHostPlugin,
|
|
||||||
connectionType: d.connectionType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.connectedDetectorPlugins[d.plug] = {
|
|
||||||
started: s.timeObject(),
|
started: s.timeObject(),
|
||||||
id: d.id,
|
id: d.id,
|
||||||
plug: d.plug,
|
plug: d.plug,
|
||||||
|
@ -62,15 +51,22 @@ module.exports = function(s,config,lang,app,io){
|
||||||
isClientPlugin: d.isClientPlugin,
|
isClientPlugin: d.isClientPlugin,
|
||||||
isHostPlugin: d.isHostPlugin,
|
isHostPlugin: d.isHostPlugin,
|
||||||
connectionType: d.connectionType
|
connectionType: d.connectionType
|
||||||
|
};
|
||||||
|
if(config.useOldPluginConnectionMethod === true){
|
||||||
|
s.ocv = newDetector
|
||||||
}
|
}
|
||||||
|
s.connectedDetectorPlugins[d.plug] = newDetector
|
||||||
s.resetDetectorPluginArray()
|
s.resetDetectorPluginArray()
|
||||||
|
s.runExtensionsForArray('onPluginConnected', null, [d.plug, newDetector])
|
||||||
}
|
}
|
||||||
s.removeDetectorPlugin = function(name){
|
s.removeDetectorPlugin = function(name){
|
||||||
|
const theDetector = Object.assign({}, s.connectedDetectorPlugins[name])
|
||||||
if(config.oldPluginConnectionMethod === true && s.ocv && s.ocv.plug === name){
|
if(config.oldPluginConnectionMethod === true && s.ocv && s.ocv.plug === name){
|
||||||
delete(s.ocv)
|
delete(s.ocv)
|
||||||
}
|
}
|
||||||
delete(s.connectedDetectorPlugins[name])
|
delete(s.connectedDetectorPlugins[name])
|
||||||
s.resetDetectorPluginArray(name)
|
s.resetDetectorPluginArray(name)
|
||||||
|
s.runExtensionsForArray('onPluginDisconnected', null, [name, theDetector])
|
||||||
}
|
}
|
||||||
s.resetDetectorPluginArray = function(){
|
s.resetDetectorPluginArray = function(){
|
||||||
pluginArray = []
|
pluginArray = []
|
||||||
|
@ -164,6 +160,10 @@ module.exports = function(s,config,lang,app,io){
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s.sendToDetector = function(pluginName, data){
|
||||||
|
const detector = s.connectedPlugins[pluginName];
|
||||||
|
if(detector)detector.tx(data);
|
||||||
|
}
|
||||||
s.sendDetectorInfoToClient = function(data,txFunction){
|
s.sendDetectorInfoToClient = function(data,txFunction){
|
||||||
s.detectorPluginArray.forEach(function(name){
|
s.detectorPluginArray.forEach(function(name){
|
||||||
var detectorData = Object.assign(data,{
|
var detectorData = Object.assign(data,{
|
||||||
|
@ -363,7 +363,33 @@ module.exports = function(s,config,lang,app,io){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function onMonitorUpdate(monitorConfig){
|
||||||
|
// console.log('Sending Monitor Info to Plugin', monitorConfig.mid)
|
||||||
|
s.sendToAllDetectors({ f: 'monitorUpdate', monitorConfig });
|
||||||
|
}
|
||||||
|
function sendCopyOfAllMonitorConfigs(){
|
||||||
|
const groupKeys = Object.keys(s.group);
|
||||||
|
for(groupKey of groupKeys){
|
||||||
|
const monitorConfigs = Object.values(s.group[groupKey].rawMonitorConfigurations);
|
||||||
|
for(monitorConfig of monitorConfigs){
|
||||||
|
onMonitorUpdate(monitorConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* API : Get List of Connected Plugins
|
||||||
|
*/
|
||||||
|
app.get(config.webPaths.apiPrefix+':auth/plugins/list', async (req,res) => {
|
||||||
|
s.auth(req.params, async (resp) => {
|
||||||
|
s.closeJsonResponse(res,{
|
||||||
|
ok: true,
|
||||||
|
plugins: s.connectedDetectorPlugins
|
||||||
|
})
|
||||||
|
},res,req)
|
||||||
|
})
|
||||||
s.onSocketAuthentication(onSocketAuthentication)
|
s.onSocketAuthentication(onSocketAuthentication)
|
||||||
s.onWebSocketDisconnection(onWebSocketDisconnection)
|
s.onWebSocketDisconnection(onWebSocketDisconnection)
|
||||||
s.onWebSocketConnection(onWebSocketConnection)
|
s.onWebSocketConnection(onWebSocketConnection)
|
||||||
|
s.onMonitorStart(onMonitorUpdate)
|
||||||
|
s.onPluginConnected(sendCopyOfAllMonitorConfigs)
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,11 @@ module.exports = function(__dirname, config){
|
||||||
if(!config.hostPort){config.hostPort = 8082}
|
if(!config.hostPort){config.hostPort = 8082}
|
||||||
if(config.systemLog === undefined){config.systemLog = true}
|
if(config.systemLog === undefined){config.systemLog = true}
|
||||||
if(config.connectionType === undefined)config.connectionType = 'websocket'
|
if(config.connectionType === undefined)config.connectionType = 'websocket'
|
||||||
|
const imageBuffers = {}
|
||||||
s = {
|
s = {
|
||||||
group: {},
|
group: {},
|
||||||
|
monitors: {},
|
||||||
|
monitorInfo: {},
|
||||||
dir: {},
|
dir: {},
|
||||||
isWin: (process.platform === 'win32'),
|
isWin: (process.platform === 'win32'),
|
||||||
s: (json) => {
|
s: (json) => {
|
||||||
|
@ -217,16 +220,26 @@ module.exports = function(__dirname, config){
|
||||||
cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type})
|
cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type})
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case'init_monitor':
|
case'monitorUpdate':
|
||||||
retryConnection = 0
|
var monitorConfig = d.monitorConfig;
|
||||||
if(s.group[d.ke] && s.group[d.ke][d.id]){
|
var groupKey = monitorConfig.ke;
|
||||||
s.group[d.ke][d.id].numberOfTriggers = 0
|
var monitorId = monitorConfig.mid;
|
||||||
delete(s.group[d.ke][d.id].cords)
|
var monitorDetails = monitorConfig.details;
|
||||||
delete(s.group[d.ke][d.id].buffer)
|
var monitorKey = `${groupKey}${monitorId}`
|
||||||
s.onCameraInitExtensions.forEach((extender) => {
|
if(!s.monitors[monitorKey])s.monitors[monitorKey] = Object.assign({}, monitorConfig);
|
||||||
extender(d,cn,tx)
|
var isObjectDetectionSeparate = monitorDetails.detector_use_detect_object === '1'
|
||||||
})
|
var width = parseFloat(isObjectDetectionSeparate && monitorDetails.detector_scale_x_object ? monitorDetails.detector_scale_x_object : monitorDetails.detector_scale_x)
|
||||||
|
var height = parseFloat(isObjectDetectionSeparate && monitorDetails.detector_scale_y_object ? monitorDetails.detector_scale_y_object : monitorDetails.detector_scale_y)
|
||||||
|
s.monitorInfo[monitorKey] = {
|
||||||
|
isObjectDetectionSeparate,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
}
|
}
|
||||||
|
delete(imageBuffers[monitorKey])
|
||||||
|
for(extender of s.onCameraInitExtensions){
|
||||||
|
extender(monitorConfig, cn, tx)
|
||||||
|
}
|
||||||
|
// console.log(monitorId, 'registered', s.monitorInfo[monitorKey])
|
||||||
break;
|
break;
|
||||||
case'frameFromRam':
|
case'frameFromRam':
|
||||||
if(!s.group[d.ke]){
|
if(!s.group[d.ke]){
|
||||||
|
@ -239,29 +252,22 @@ module.exports = function(__dirname, config){
|
||||||
break;
|
break;
|
||||||
case'frame':
|
case'frame':
|
||||||
try{
|
try{
|
||||||
if(!s.group[d.ke]){
|
const monitorKey = `${d.id}${d.ke}`;
|
||||||
s.group[d.ke]={}
|
imageBuffers[monitorKey]
|
||||||
}
|
if(!imageBuffers[monitorKey]){
|
||||||
if(!s.group[d.ke][d.id]){
|
imageBuffers[monitorKey] = [d.frame];
|
||||||
s.group[d.ke][d.id] = {}
|
|
||||||
s.onCameraInitExtensions.forEach((extender) => {
|
|
||||||
extender(d,cn,tx)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if(!s.group[d.ke][d.id].buffer){
|
|
||||||
s.group[d.ke][d.id].buffer = [d.frame];
|
|
||||||
}else{
|
}else{
|
||||||
s.group[d.ke][d.id].buffer.push(d.frame)
|
imageBuffers[monitorKey].push(d.frame)
|
||||||
}
|
}
|
||||||
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||||
var buffer = Buffer.concat(s.group[d.ke][d.id].buffer);
|
var buffer = Buffer.concat(imageBuffers[monitorKey]);
|
||||||
processImage(buffer,d,tx)
|
processImage(buffer,d,tx)
|
||||||
s.group[d.ke][d.id].buffer = null
|
imageBuffers[monitorKey] = null
|
||||||
}
|
}
|
||||||
}catch(err){
|
}catch(err){
|
||||||
if(err){
|
if(err){
|
||||||
s.systemLog(err)
|
s.systemLog(err)
|
||||||
delete(s.group[d.ke][d.id].buffer)
|
delete(imageBuffers[monitorKey])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -32,8 +32,11 @@ module.exports = function(__dirname, config){
|
||||||
if(!config.hostPort){config.hostPort = 8082}
|
if(!config.hostPort){config.hostPort = 8082}
|
||||||
if(config.systemLog === undefined){config.systemLog = true}
|
if(config.systemLog === undefined){config.systemLog = true}
|
||||||
if(config.connectionType === undefined)config.connectionType = 'websocket'
|
if(config.connectionType === undefined)config.connectionType = 'websocket'
|
||||||
|
const imageBuffers = {}
|
||||||
s = {
|
s = {
|
||||||
group: {},
|
group: {},
|
||||||
|
monitors: {},
|
||||||
|
monitorInfo: {},
|
||||||
dir: {},
|
dir: {},
|
||||||
isWin: (process.platform === 'win32'),
|
isWin: (process.platform === 'win32'),
|
||||||
s: (json) => {
|
s: (json) => {
|
||||||
|
@ -192,16 +195,26 @@ module.exports = function(__dirname, config){
|
||||||
cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type})
|
cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type})
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case'init_monitor':
|
case'monitorUpdate':
|
||||||
retryConnection = 0
|
var monitorConfig = d.monitorConfig;
|
||||||
if(s.group[d.ke] && s.group[d.ke][d.id]){
|
var groupKey = monitorConfig.ke;
|
||||||
s.group[d.ke][d.id].numberOfTriggers = 0
|
var monitorId = monitorConfig.mid;
|
||||||
delete(s.group[d.ke][d.id].cords)
|
var monitorDetails = monitorConfig.details;
|
||||||
delete(s.group[d.ke][d.id].buffer)
|
var monitorKey = `${groupKey}${monitorId}`
|
||||||
s.onCameraInitExtensions.forEach((extender) => {
|
if(!s.monitors[monitorKey])s.monitors[monitorKey] = Object.assign({}, monitorConfig);
|
||||||
extender(d,cn,tx)
|
var isObjectDetectionSeparate = monitorDetails.detector_use_detect_object === '1'
|
||||||
})
|
var width = parseFloat(isObjectDetectionSeparate && monitorDetails.detector_scale_x_object ? monitorDetails.detector_scale_x_object : monitorDetails.detector_scale_x)
|
||||||
|
var height = parseFloat(isObjectDetectionSeparate && monitorDetails.detector_scale_y_object ? monitorDetails.detector_scale_y_object : monitorDetails.detector_scale_y)
|
||||||
|
s.monitorInfo[monitorKey] = {
|
||||||
|
isObjectDetectionSeparate,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
}
|
}
|
||||||
|
delete(imageBuffers[monitorKey])
|
||||||
|
for(extender of s.onCameraInitExtensions){
|
||||||
|
extender(monitorConfig, cn, tx)
|
||||||
|
}
|
||||||
|
// console.log(monitorId, 'registered', s.monitorInfo[monitorKey])
|
||||||
break;
|
break;
|
||||||
case'frameFromRam':
|
case'frameFromRam':
|
||||||
if(!s.group[d.ke]){
|
if(!s.group[d.ke]){
|
||||||
|
@ -214,29 +227,22 @@ module.exports = function(__dirname, config){
|
||||||
break;
|
break;
|
||||||
case'frame':
|
case'frame':
|
||||||
try{
|
try{
|
||||||
if(!s.group[d.ke]){
|
const monitorKey = `${d.id}${d.ke}`;
|
||||||
s.group[d.ke]={}
|
imageBuffers[monitorKey]
|
||||||
}
|
if(!imageBuffers[monitorKey]){
|
||||||
if(!s.group[d.ke][d.id]){
|
imageBuffers[monitorKey] = [d.frame];
|
||||||
s.group[d.ke][d.id] = {}
|
|
||||||
s.onCameraInitExtensions.forEach((extender) => {
|
|
||||||
extender(d,cn,tx)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if(!s.group[d.ke][d.id].buffer){
|
|
||||||
s.group[d.ke][d.id].buffer = [d.frame];
|
|
||||||
}else{
|
}else{
|
||||||
s.group[d.ke][d.id].buffer.push(d.frame)
|
imageBuffers[monitorKey].push(d.frame)
|
||||||
}
|
}
|
||||||
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||||
var buffer = Buffer.concat(s.group[d.ke][d.id].buffer);
|
var buffer = Buffer.concat(imageBuffers[monitorKey]);
|
||||||
processImage(buffer,d,tx)
|
processImage(buffer,d,tx)
|
||||||
s.group[d.ke][d.id].buffer = null
|
imageBuffers[monitorKey] = null
|
||||||
}
|
}
|
||||||
}catch(err){
|
}catch(err){
|
||||||
if(err){
|
if(err){
|
||||||
s.systemLog(err)
|
s.systemLog(err)
|
||||||
delete(s.group[d.ke][d.id].buffer)
|
delete(imageBuffers[monitorKey])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -15,6 +15,7 @@ var monSectionPresets = $('#monSectionPresets')
|
||||||
var copySettingsSelector = $('#copy_settings')
|
var copySettingsSelector = $('#copy_settings')
|
||||||
var monitorPresetsSelection = $('#monitorPresetsSelection')
|
var monitorPresetsSelection = $('#monitorPresetsSelection')
|
||||||
var monitorPresetsNameField = $('#monitorPresetsName')
|
var monitorPresetsNameField = $('#monitorPresetsName')
|
||||||
|
var detectorsSelected = $('#detectorsSelected')
|
||||||
var monitorsList = monitorEditorWindow.find('.monitors_list')
|
var monitorsList = monitorEditorWindow.find('.monitors_list')
|
||||||
var editorForm = monitorEditorWindow.find('form')
|
var editorForm = monitorEditorWindow.find('form')
|
||||||
var tagsInput = monitorEditorWindow.find('[name="tags"]')
|
var tagsInput = monitorEditorWindow.find('[name="tags"]')
|
||||||
|
@ -566,7 +567,37 @@ function drawInputMapSelectorHtml(options,parent){
|
||||||
</div>`
|
</div>`
|
||||||
parent.prepend(html)
|
parent.prepend(html)
|
||||||
}
|
}
|
||||||
function importIntoMonitorEditor(options){
|
function getPluginsList(monitorConfig){
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const chosenDetectors = safeJsonParse(monitorConfig.details).detectors_selected || [];
|
||||||
|
$.get(getApiPrefix() + '/plugins/list',function(data){
|
||||||
|
var plugins = data.plugins || {};
|
||||||
|
var pluginNames = Object.keys(plugins)
|
||||||
|
var disconnectedPlugins = chosenDetectors.filter(item => !pluginNames.includes(item));
|
||||||
|
var html = createOptionHtml({
|
||||||
|
value: 'all',
|
||||||
|
label: `${lang.All} (${lang.Default})`
|
||||||
|
});
|
||||||
|
$.each(plugins, function(name, pluginInfo){
|
||||||
|
html += createOptionHtml({
|
||||||
|
value: name,
|
||||||
|
label: name,
|
||||||
|
selected: chosenDetectors.includes(name),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
$.each(disconnectedPlugins, function(n, name){
|
||||||
|
html += createOptionHtml({
|
||||||
|
value: name,
|
||||||
|
label: `${name} (${lang.Disconnected})`,
|
||||||
|
selected: true,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
detectorsSelected.html(html)
|
||||||
|
resolve(plugins)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function importIntoMonitorEditor(options){
|
||||||
var monitorConfig = options.values || options
|
var monitorConfig = options.values || options
|
||||||
var monitorId = monitorConfig.mid
|
var monitorId = monitorConfig.mid
|
||||||
var monitorDetails = safeJsonParse(monitorConfig.details);
|
var monitorDetails = safeJsonParse(monitorConfig.details);
|
||||||
|
@ -686,6 +717,9 @@ function importIntoMonitorEditor(options){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
//
|
||||||
|
await getPluginsList(monitorConfig)
|
||||||
|
//
|
||||||
copySettingsSelector.val('0').change()
|
copySettingsSelector.val('0').change()
|
||||||
var tmp = '';
|
var tmp = '';
|
||||||
$.each(loadedMonitors,function(n,monitor){
|
$.each(loadedMonitors,function(n,monitor){
|
||||||
|
@ -1319,9 +1353,11 @@ editorForm.find('[name="type"]').change(function(e){
|
||||||
break;
|
break;
|
||||||
case'detector_plugged':
|
case'detector_plugged':
|
||||||
addDetectorPlugin(d.plug,d)
|
addDetectorPlugin(d.plug,d)
|
||||||
|
if(monitorEditorSelectedMonitor)getPluginsList(monitorEditorSelectedMonitor);
|
||||||
break;
|
break;
|
||||||
case'detector_unplugged':
|
case'detector_unplugged':
|
||||||
removeDetectorPlugin(d.plug)
|
removeDetectorPlugin(d.plug)
|
||||||
|
if(monitorEditorSelectedMonitor)getPluginsList(monitorEditorSelectedMonitor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1335,6 +1371,7 @@ editorForm.find('[name="type"]').change(function(e){
|
||||||
drawMonitorListToSelector(monitorsList.find('optgroup'),false,'host')
|
drawMonitorListToSelector(monitorsList.find('optgroup'),false,'host')
|
||||||
monitorsList.val(theSelected)
|
monitorsList.val(theSelected)
|
||||||
checkToOpenSideMenu()
|
checkToOpenSideMenu()
|
||||||
|
if(monitorEditorSelectedMonitor)getPluginsList(monitorEditorSelectedMonitor)
|
||||||
}
|
}
|
||||||
addOnTabAway('monitorSettings', function(){
|
addOnTabAway('monitorSettings', function(){
|
||||||
if(isSideBarMenuCollapsed()){
|
if(isSideBarMenuCollapsed()){
|
||||||
|
|
|
@ -147,7 +147,11 @@ $(document).ready(function(){
|
||||||
$.post(superApiPrefix + $user.sessionKey + '/plugins/download',{
|
$.post(superApiPrefix + $user.sessionKey + '/plugins/download',{
|
||||||
downloadUrl: url,
|
downloadUrl: url,
|
||||||
packageRoot: packageRoot,
|
packageRoot: packageRoot,
|
||||||
},callback)
|
},function(data){
|
||||||
|
setTimeout(function(){
|
||||||
|
callback(data)
|
||||||
|
},3000)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue