Merge branch 'ptz-improvements' into 'dev'
Improve Automatic PTZ (Return Home when Object lost) + More See merge request Shinobi-Systems/Shinobi!237fix-non-showing-inputs
commit
ecc4b5f42c
|
|
@ -420,6 +420,25 @@ module.exports = function(s,config,lang){
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "detail=onvif_non_standard",
|
||||
"field": lang['Non-Standard ONVIF'],
|
||||
"description": "Is this a Non-Standard ONVIF camera?",
|
||||
"default": "0",
|
||||
"example": "",
|
||||
"form-group-class": "h_onvif_input h_onvif_1",
|
||||
"fieldType": "select",
|
||||
"possible": [
|
||||
{
|
||||
"name": lang.No,
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": lang.Yes,
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
hidden: true,
|
||||
"name": "detail=onvif_port",
|
||||
|
|
@ -3608,6 +3627,24 @@ module.exports = function(s,config,lang){
|
|||
"form-group-class": "h_control_call_input h_control_call_GET h_control_call_PUT h_control_call_POST",
|
||||
"possible": ""
|
||||
},
|
||||
{
|
||||
"name": "detail=control_invert_y",
|
||||
"field": lang["Invert Y-Axis"],
|
||||
"description": "For When your camera is mounted upside down or uses inverted vertical controls.",
|
||||
"default": "0",
|
||||
"example": "",
|
||||
"fieldType": "select",
|
||||
"possible": [
|
||||
{
|
||||
"name": lang.No,
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": lang.Yes,
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
"Grouping": {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
"Token": "Token",
|
||||
"OAuth Code": "OAuth Code",
|
||||
"Google Drive": "Google Drive",
|
||||
"Invert Y-Axis": "Invert Y-Axis",
|
||||
"Get Code": "Get Code",
|
||||
"PTZ Tracking": "PTZ Tracking",
|
||||
"PTZ Tracking Target": "PTZ Tracking Target",
|
||||
|
|
@ -88,6 +89,7 @@
|
|||
"Never": "Never",
|
||||
"API": "API",
|
||||
"ONVIF": "ONVIF",
|
||||
"Non-Standard ONVIF": "Non-Standard ONVIF",
|
||||
"FFprobe": "Probe",
|
||||
"Monitor States": "Monitor States",
|
||||
"Schedule": "Schedule",
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ var os = require('os');
|
|||
var exec = require('child_process').exec;
|
||||
module.exports = function(s,config,lang,app,io){
|
||||
require('./control/onvif.js')(s,config,lang,app,io)
|
||||
const ptz = require('./control/ptz.js')(s,config,lang,app,io)
|
||||
// const ptz = require('./control/ptz.js')(s,config,lang,app,io)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,13 +17,26 @@ module.exports = function(s,config,lang,app,io){
|
|||
try{
|
||||
const info = await device.init()
|
||||
response.ok = true
|
||||
response.device = device
|
||||
}catch(err){
|
||||
response.msg = 'Device responded with an error'
|
||||
response.error = error
|
||||
response.error = err
|
||||
}
|
||||
return response
|
||||
}
|
||||
const runOnvifMethod = (onvifOptions,callback) => {
|
||||
const replaceDynamicInOptions = (Camera,options) => {
|
||||
const newOptions = {}
|
||||
Object.keys(options).forEach((key) => {
|
||||
const value = options[key]
|
||||
if(typeof value === 'string'){
|
||||
newOptions[key] = value.replace(/__CURRENT_TOKEN/g,Camera.current_profile.token)
|
||||
}else if(value !== undefined && value !== null){
|
||||
newOptions[key] = value
|
||||
}
|
||||
})
|
||||
return newOptions
|
||||
}
|
||||
const runOnvifMethod = async (onvifOptions,callback) => {
|
||||
var onvifAuth = onvifOptions.auth
|
||||
var response = {ok: false}
|
||||
var errorMessage = function(msg,error){
|
||||
|
|
@ -83,7 +96,8 @@ module.exports = function(s,config,lang,app,io){
|
|||
var options
|
||||
var command
|
||||
if(argNames[0] === 'options' || argNames[0] === 'params'){
|
||||
options = onvifOptions.options || {}
|
||||
options = replaceDynamicInOptions(Camera,onvifOptions.options || {})
|
||||
response.options = options
|
||||
}
|
||||
if(onvifAuth.service){
|
||||
command = Camera.services[onvifAuth.service][onvifAuth.action](options)
|
||||
|
|
@ -94,7 +108,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
}
|
||||
}
|
||||
if(!s.group[onvifAuth.ke].activeMonitors[onvifAuth.id].onvifConnection){
|
||||
const response = createOnvifDevice(onvifAuth)
|
||||
const response = await createOnvifDevice(onvifAuth)
|
||||
if(response.ok){
|
||||
doAction(response.device)
|
||||
}else{
|
||||
|
|
@ -112,15 +126,15 @@ module.exports = function(s,config,lang,app,io){
|
|||
config.webPaths.apiPrefix+':auth/onvif/:ke/:id/:service/:action'
|
||||
],function (req,res){
|
||||
s.auth(req.params,function(user){
|
||||
const options = s.getPostData(req,'options',true) || s.getPostData(req,'params',true)
|
||||
runOnvifMethod({
|
||||
auth: {
|
||||
ke: req.params.ke,
|
||||
id: req.params.id,
|
||||
auth: req.params.auth,
|
||||
action: req.params.action,
|
||||
service: req.params.service,
|
||||
},
|
||||
options: s.getPostData(req,'options',true) || s.getPostData(req,'params',true),
|
||||
options: options,
|
||||
},(endData) => {
|
||||
s.closeJsonResponse(res,endData)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
var os = require('os');
|
||||
var exec = require('child_process').exec;
|
||||
var request = require('request')
|
||||
module.exports = function(s,config,lang,app,io){
|
||||
module.exports = function(s,config,lang){
|
||||
const moveLock = {}
|
||||
const ptzTimeoutsUntilResetToHome = {}
|
||||
const startMove = async function(options,callback){
|
||||
const device = s.group[options.ke].activeMonitors[options.id].onvifConnection
|
||||
if(!device){
|
||||
|
|
@ -41,6 +42,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
}
|
||||
const moveOnvifCamera = function(options,callback){
|
||||
const monitorConfig = s.group[options.ke].rawMonitorConfigurations[options.id]
|
||||
const invertedVerticalAxis = monitorConfig.details.control_invert_y === '1'
|
||||
const controlUrlStopTimeout = parseInt(monitorConfig.details.control_url_stop_timeout) || 1000
|
||||
switch(options.direction){
|
||||
case'center':
|
||||
|
|
@ -68,8 +70,8 @@ module.exports = function(s,config,lang,app,io){
|
|||
var onvifDirections = {
|
||||
"left": [-1.0,'x'],
|
||||
"right": [1.0,'x'],
|
||||
"down": [-1.0,'y'],
|
||||
"up": [1.0,'y'],
|
||||
"down": [invertedVerticalAxis ? 1.0 : -1.0,'y'],
|
||||
"up": [invertedVerticalAxis ? -1.0 : 1.0,'y'],
|
||||
"zoom_in": [1.0,'z'],
|
||||
"zoom_out": [-1.0,'z']
|
||||
}
|
||||
|
|
@ -258,10 +260,123 @@ module.exports = function(s,config,lang,app,io){
|
|||
}
|
||||
}
|
||||
}
|
||||
s.cameraControl = ptzControl
|
||||
const getPresetPositions = (options,callback) => {
|
||||
const profileToken = options.ProfileToken || "__CURRENT_TOKEN"
|
||||
return s.runOnvifMethod({
|
||||
auth: {
|
||||
ke: options.ke,
|
||||
id: options.id,
|
||||
service: 'ptz',
|
||||
action: 'getPresets',
|
||||
},
|
||||
options: {
|
||||
ProfileToken: profileToken
|
||||
},
|
||||
},callback)
|
||||
}
|
||||
const setPresetForCurrentPosition = (options,callback) => {
|
||||
const nonStandardOnvif = s.group[options.ke].rawMonitorConfigurations[options.id].details.onvif_non_standard === '1'
|
||||
const profileToken = options.ProfileToken || "__CURRENT_TOKEN"
|
||||
s.runOnvifMethod({
|
||||
auth: {
|
||||
ke: options.ke,
|
||||
id: options.id,
|
||||
service: 'ptz',
|
||||
action: 'setPreset',
|
||||
},
|
||||
options: {
|
||||
ProfileToken: profileToken,
|
||||
PresetToken: nonStandardOnvif ? null : options.PresetToken || profileToken,
|
||||
PresetName: options.PresetName || nonStandardOnvif ? '1' : profileToken
|
||||
},
|
||||
},(endData) => {
|
||||
callback(endData)
|
||||
})
|
||||
}
|
||||
const moveToPresetPosition = (options,callback) => {
|
||||
const nonStandardOnvif = s.group[options.ke].rawMonitorConfigurations[options.id].details.onvif_non_standard === '1'
|
||||
const profileToken = options.ProfileToken || "__CURRENT_TOKEN"
|
||||
return s.runOnvifMethod({
|
||||
auth: {
|
||||
ke: options.ke,
|
||||
id: options.id,
|
||||
service: 'ptz',
|
||||
action: 'gotoPreset',
|
||||
},
|
||||
options: {
|
||||
ProfileToken: profileToken,
|
||||
PresetToken: options.PresetToken || nonStandardOnvif ? '1' : profileToken,
|
||||
Speed: {
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
},
|
||||
},callback)
|
||||
}
|
||||
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 moveCameraPtzToMatrix = function(event,trackingTarget){
|
||||
if(moveLock[event.ke + event.id])return;
|
||||
clearTimeout(moveLock[event.ke + event.id])
|
||||
moveLock[event.ke + event.id] = setTimeout(() => {
|
||||
delete(moveLock[event.ke + event.id])
|
||||
},1000)
|
||||
const imgHeight = event.details.imgHeight
|
||||
const imgWidth = event.details.imgWidth
|
||||
const thresholdX = imgWidth * 0.125
|
||||
const thresholdY = imgHeight * 0.125
|
||||
const imageCenterX = imgWidth / 2
|
||||
const imageCenterY = imgHeight / 2
|
||||
const matrices = event.details.matrices
|
||||
const largestMatrix = getLargestMatrix(matrices.filter(matrix => matrix.tag === (trackingTarget || 'person')))
|
||||
// console.log(matrices.find(matrix => matrix.tag === 'person'))
|
||||
if(!largestMatrix)return;
|
||||
const matrixCenterX = largestMatrix.x + (largestMatrix.width / 2)
|
||||
const matrixCenterY = largestMatrix.y + (largestMatrix.height / 2)
|
||||
const rawDistanceX = (matrixCenterX - imageCenterX)
|
||||
const rawDistanceY = (matrixCenterY - imageCenterY)
|
||||
const distanceX = imgWidth / rawDistanceX
|
||||
const distanceY = imgHeight / rawDistanceY
|
||||
const axisX = rawDistanceX > thresholdX || rawDistanceX < -thresholdX ? distanceX : 0
|
||||
const axisY = largestMatrix.y < 30 && largestMatrix.height > imgHeight * 0.8 ? 0.5 : rawDistanceY > thresholdY || rawDistanceY < -thresholdY ? -distanceY : 0
|
||||
if(axisX !== 0 || axisY !== 0){
|
||||
ptzControl({
|
||||
axis: [
|
||||
{direction: 'x', amount: axisX === 0 ? 0 : axisX > 0 ? 0.01 : -0.01},
|
||||
{direction: 'y', amount: axisY === 0 ? 0 : axisY > 0 ? 0.01 : -0.01},
|
||||
{direction: 'z', amount: 0},
|
||||
],
|
||||
// axis: [{direction: 'x', amount: 1.0}],
|
||||
id: event.id,
|
||||
ke: event.ke
|
||||
},(msg) => {
|
||||
s.userLog(event,msg)
|
||||
// console.log(msg)
|
||||
clearTimeout(ptzTimeoutsUntilResetToHome[event.ke + event.id])
|
||||
ptzTimeoutsUntilResetToHome[event.ke + event.id] = setTimeout(() => {
|
||||
moveToPresetPosition({
|
||||
ke: event.ke,
|
||||
id: event.id,
|
||||
},(endData) => {
|
||||
console.log(endData)
|
||||
})
|
||||
},7000)
|
||||
})
|
||||
}
|
||||
}
|
||||
return {
|
||||
control: ptzControl,
|
||||
ptzControl: ptzControl,
|
||||
startMove: startMove,
|
||||
stopMove: stopMove,
|
||||
getPresetPositions: getPresetPositions,
|
||||
setPresetForCurrentPosition: setPresetForCurrentPosition,
|
||||
moveToPresetPosition: moveToPresetPosition,
|
||||
moveCameraPtzToMatrix: moveCameraPtzToMatrix
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ var P = SAT.Polygon;
|
|||
var B = SAT.Box;
|
||||
// Matrix In Region Libs />
|
||||
module.exports = function(s,config,lang){
|
||||
const ptz = require('./control/ptz.js')(s,config,lang)
|
||||
const {
|
||||
moveCameraPtzToMatrix,
|
||||
} = require('./control/ptz.js')(s,config,lang)
|
||||
const countObjects = async (event) => {
|
||||
const matrices = event.details.matrices
|
||||
const eventsCounted = s.group[event.ke].activeMonitors[event.id].eventsCounted || {}
|
||||
|
|
@ -78,54 +80,6 @@ module.exports = function(s,config,lang){
|
|||
return collisions
|
||||
}
|
||||
const nonEmpty = (element) => element.length !== 0;
|
||||
const moveLock = {}
|
||||
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 moveCameraPtzToMatrix = function(event,trackingTarget){
|
||||
if(moveLock[event.ke + event.id])return;
|
||||
clearTimeout(moveLock[event.ke + event.id])
|
||||
moveLock[event.ke + event.id] = setTimeout(() => {
|
||||
delete(moveLock[event.ke + event.id])
|
||||
},1000)
|
||||
const imgHeight = event.details.imgHeight
|
||||
const imgWidth = event.details.imgWidth
|
||||
const thresholdX = imgWidth * 0.125
|
||||
const thresholdY = imgHeight * 0.125
|
||||
const imageCenterX = imgWidth / 2
|
||||
const imageCenterY = imgHeight / 2
|
||||
const matrices = event.details.matrices
|
||||
const largestMatrix = getLargestMatrix(matrices.filter(matrix => matrix.tag === (trackingTarget || 'person')))
|
||||
// console.log(matrices.find(matrix => matrix.tag === 'person'))
|
||||
if(!largestMatrix)return;
|
||||
const matrixCenterX = largestMatrix.x + (largestMatrix.width / 2)
|
||||
const matrixCenterY = largestMatrix.y + (largestMatrix.height / 2)
|
||||
const rawDistanceX = (matrixCenterX - imageCenterX)
|
||||
const rawDistanceY = (matrixCenterY - imageCenterY)
|
||||
const distanceX = imgWidth / rawDistanceX
|
||||
const distanceY = imgHeight / rawDistanceY
|
||||
const axisX = rawDistanceX > thresholdX || rawDistanceX < -thresholdX ? distanceX : 0
|
||||
const axisY = largestMatrix.y < 30 && largestMatrix.height > imgHeight * 0.8 ? 0.5 : rawDistanceY > thresholdY || rawDistanceY < -thresholdY ? -distanceY : 0
|
||||
if(axisX !== 0 || axisY !== 0){
|
||||
ptz.control({
|
||||
axis: [
|
||||
{direction: 'x', amount: axisX === 0 ? 0 : axisX > 0 ? 0.01 : -0.01},
|
||||
{direction: 'y', amount: axisY === 0 ? 0 : axisY > 0 ? 0.01 : -0.01},
|
||||
{direction: 'z', amount: 0},
|
||||
],
|
||||
// axis: [{direction: 'x', amount: 1.0}],
|
||||
id: event.id,
|
||||
ke: event.ke
|
||||
},(msg) => {
|
||||
s.userLog(event,msg)
|
||||
// console.log(msg)
|
||||
})
|
||||
}
|
||||
}
|
||||
s.addEventDetailsToString = function(eventData,string,addOps){
|
||||
//d = event data
|
||||
if(!addOps)addOps = {}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ const URL = require('url')
|
|||
const { copyObject, createQueue } = require('./common.js')
|
||||
module.exports = function(s,config,lang){
|
||||
const { cameraDestroy } = require('./monitor/utils.js')(s,config,lang)
|
||||
const {
|
||||
setPresetForCurrentPosition
|
||||
} = require('./control/ptz.js')(s,config,lang)
|
||||
const startMonitorInQueue = createQueue(1, 3)
|
||||
s.initiateMonitorObject = function(e){
|
||||
if(!s.group[e.ke]){s.group[e.ke]={}};
|
||||
|
|
@ -455,7 +458,6 @@ module.exports = function(s,config,lang){
|
|||
ke: e.ke
|
||||
},'GRP_'+e.ke)
|
||||
}else{
|
||||
console.log('not image')
|
||||
s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke)
|
||||
}
|
||||
}else{
|
||||
|
|
@ -1607,6 +1609,34 @@ module.exports = function(s,config,lang){
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(e.details.detector_ptz_follow === '1'){
|
||||
setTimeout(() => {
|
||||
setPresetForCurrentPosition({
|
||||
ke: e.ke,
|
||||
id: e.id
|
||||
},(endData) => {
|
||||
if(endData.ok === false){
|
||||
setTimeout(() => {
|
||||
setPresetForCurrentPosition({
|
||||
ke: e.ke,
|
||||
id: e.id
|
||||
},(endData) => {
|
||||
if(endData.ok === false){
|
||||
setTimeout(() => {
|
||||
setPresetForCurrentPosition({
|
||||
ke: e.ke,
|
||||
id: e.id
|
||||
},(endData) => {
|
||||
console.log(endData)
|
||||
})
|
||||
},5000)
|
||||
}
|
||||
})
|
||||
},5000)
|
||||
}
|
||||
})
|
||||
},5000)
|
||||
}
|
||||
launchMonitorProcesses(e)
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
ip = addressRange.join(',')
|
||||
}
|
||||
if(ports === ''){
|
||||
ports = '80,8080,8000,7575,8081,9080,8090,8999'
|
||||
ports = '80,8080,8000,7575,8081,9080,8090,8999,8899'
|
||||
}
|
||||
if(ports.indexOf('-') > -1){
|
||||
ports = ports.split('-')
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ var exec = require('child_process').exec;
|
|||
var spawn = require('child_process').spawn;
|
||||
var jsonfile = require("jsonfile");
|
||||
module.exports = function(s,config,lang,io){
|
||||
const {
|
||||
ptzControl
|
||||
} = require('./control/ptz.js')(s,config,lang)
|
||||
s.clientSocketConnection = {}
|
||||
//send data to socket client function
|
||||
s.tx = function(z,y,x){
|
||||
|
|
@ -649,7 +652,7 @@ module.exports = function(s,config,lang,io){
|
|||
}
|
||||
break;
|
||||
case'control':
|
||||
s.cameraControl(d,function(msg){
|
||||
ptzControl(d,function(msg){
|
||||
s.userLog(d,msg)
|
||||
tx({f:'control',response:msg})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ var proxy = httpProxy.createProxyServer({})
|
|||
var ejs = require('ejs');
|
||||
var fileupload = require("express-fileupload");
|
||||
module.exports = function(s,config,lang,app,io){
|
||||
const {
|
||||
ptzControl
|
||||
} = require('./control/ptz.js')(s,config,lang,app,io)
|
||||
if(config.productType === 'Pro'){
|
||||
var LdapAuth = require('ldapauth-fork');
|
||||
}
|
||||
|
|
@ -1655,7 +1658,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
app.get(config.webPaths.apiPrefix+':auth/control/:ke/:id/:direction', function (req,res){
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
s.auth(req.params,function(user){
|
||||
s.cameraControl(req.params,function(msg){
|
||||
ptzControl(req.params,function(msg){
|
||||
s.userLog({
|
||||
id: req.params.id,
|
||||
ke: req.params.ke,
|
||||
|
|
|
|||
Loading…
Reference in New Issue