Shinobi/libs/control/onvif.js

146 lines
6.0 KiB
JavaScript

var os = require('os');
var exec = require('child_process').exec;
const onvif = require("shinobi-onvif");
module.exports = function(s,config,lang,app,io){
const createOnvifDevice = async (onvifAuth) => {
var response = {ok: false}
const monitorConfig = s.group[onvifAuth.ke].rawMonitorConfigurations[onvifAuth.id]
const controlBaseUrl = monitorConfig.details.control_base_url || s.buildMonitorUrl(monitorConfig, true)
const controlURLOptions = s.cameraControlOptionsFromUrl(controlBaseUrl,monitorConfig)
//create onvif connection
const device = new onvif.OnvifDevice({
address : controlURLOptions.host + ':' + controlURLOptions.port,
user : controlURLOptions.username,
pass : controlURLOptions.password
})
s.group[onvifAuth.ke].activeMonitors[onvifAuth.id].onvifConnection = device
try{
const info = await device.init()
response.ok = true
response.device = device
}catch(err){
response.msg = 'Device responded with an error'
response.error = err
}
return response
}
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){
response.ok = false
response.msg = msg
response.error = error
callback(response)
}
var actionCallback = function(onvifActionResponse){
response.ok = true
if(onvifActionResponse.data){
response.responseFromDevice = onvifActionResponse.data
}else{
response.responseFromDevice = onvifActionResponse
}
if(onvifActionResponse.soap)response.soap = onvifActionResponse.soap
callback(response)
}
var isEmpty = function(obj) {
for(var key in obj) {
if(obj.hasOwnProperty(key))
return false;
}
return true;
}
var doAction = function(Camera){
var completeAction = function(command){
if(command && command.then){
command.then(actionCallback).catch(function(error){
errorMessage('Device Action responded with an error',error)
})
}else if(command){
response.ok = true
response.repsonseFromDevice = command
callback(response)
}else{
response.error = 'Big Errors, Please report it to Shinobi Development'
callback(response)
}
}
var action
if(onvifAuth.service){
if(Camera.services[onvifAuth.service] === undefined){
return errorMessage('This is not an available service. Please use one of the following : '+Object.keys(Camera.services).join(', '))
}
if(Camera.services[onvifAuth.service] === null){
return errorMessage('This service is not activated. Maybe you are not connected through ONVIF. You can test by attempting to use the "Control" feature with ONVIF in Shinobi.')
}
action = Camera.services[onvifAuth.service][onvifAuth.action]
}else{
action = Camera[onvifAuth.action]
}
if(!action || typeof action !== 'function'){
errorMessage(onvifAuth.action+' is not an available ONVIF function. See https://github.com/futomi/node-onvif for functions.')
}else{
var argNames = s.getFunctionParamNames(action)
var options
var command
if(argNames[0] === 'options' || argNames[0] === 'params'){
options = replaceDynamicInOptions(Camera,onvifOptions.options || {})
response.options = options
}
if(onvifAuth.service){
command = Camera.services[onvifAuth.service][onvifAuth.action](options)
}else{
command = Camera[onvifAuth.action](options)
}
completeAction(command)
}
}
if(!s.group[onvifAuth.ke].activeMonitors[onvifAuth.id].onvifConnection){
const response = await createOnvifDevice(onvifAuth)
if(response.ok){
doAction(response.device)
}else{
errorMessage(response.msg,response.error)
}
}else{
doAction(s.group[onvifAuth.ke].activeMonitors[onvifAuth.id].onvifConnection)
}
}
/**
* API : ONVIF Method Controller
*/
app.all([
config.webPaths.apiPrefix+':auth/onvif/:ke/:id/:action',
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,
action: req.params.action,
service: req.params.service,
},
options: options,
},(endData) => {
s.closeJsonResponse(res,endData)
})
},res,req);
})
s.createOnvifDevice = createOnvifDevice
s.runOnvifMethod = runOnvifMethod
}