diff --git a/definitions/base.js b/definitions/base.js
index b1f70490..e97eec9b 100644
--- a/definitions/base.js
+++ b/definitions/base.js
@@ -475,25 +475,6 @@ module.exports = function(s,config,lang){
}
]
},
- {
- "name": "detail=onvif_non_standard",
- "field": lang['Non-Standard ONVIF'],
- "description": lang["fieldTextOnvifNonStandard"],
- "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",
@@ -3794,13 +3775,33 @@ module.exports = function(s,config,lang){
}
]
},
+ {
+ "name": "detail=onvif_non_standard",
+ "field": lang['ONVIF Home Control'],
+ "description": lang.fieldTextOnvifHomeControl,
+ "default": "0",
+ "form-group-class": "h_control_call_input h_control_call_ONVIF",
+ "fieldType": "select",
+ "possible": [
+ {
+ "name": lang.usingPreset1,
+ "value": "0"
+ },
+ {
+ "name": lang.usingPreset1HikvisionClone,
+ "value": "1"
+ },
+ {
+ "name": lang.usingHomePreset,
+ "value": "2"
+ }
+ ]
+ },
{
isAdvanced: true,
"name": "detail=control_digest_auth",
"field": lang['Digest Authentication'],
- "description": "",
"default": "0",
- "example": "",
"fieldType": "select",
"form-group-class": "h_control_call_input h_control_call_GET h_control_call_PUT h_control_call_POST",
"possible": [
@@ -3814,6 +3815,27 @@ module.exports = function(s,config,lang){
}
]
},
+ {
+ isAdvanced: true,
+ "name": "detail=control_axis_lock",
+ "field": lang['Pan/Tilt Only'],
+ "default": "",
+ "fieldType": "select",
+ "possible": [
+ {
+ "name": lang['Pan and Tilt'],
+ "value": ""
+ },
+ {
+ "name": lang['Pan Only'],
+ "value": "1"
+ },
+ {
+ "name": lang['Tilt Only'],
+ "value": "2"
+ }
+ ]
+ },
{
"name": "detail=control_stop",
"field": lang['Stop Command'],
diff --git a/languages/en_CA.json b/languages/en_CA.json
index 67f1b6bb..95c2488e 100644
--- a/languages/en_CA.json
+++ b/languages/en_CA.json
@@ -375,6 +375,14 @@
"for Global Access": "for Global Access",
"Help": "Help",
"Range": "Range",
+ "ONVIF Home Control": "ONVIF Home Control",
+ "usingPreset1": "Using Preset 1",
+ "usingPreset1HikvisionClone": "Using Preset 1, Non-Standard, Hikvision Clone",
+ "usingHomePreset": "Using \"Home\" Preset",
+ "Pan and Tilt": "Pan and Tilt",
+ "Tilt Only": "Tilt Only",
+ "Pan Only": "Pan Only",
+ "Pan/Tilt Only": "Pan/Tilt Only",
"Direction": "Direction",
"Field of View": "Field of View",
"Don't show this anymore": "Don't show this anymore",
@@ -1571,7 +1579,7 @@
"fieldTextFatalMax": "The number of times to retry for network connection between the server and camera before setting the monitor to Disabled. No decimals. Set to 0 to retry forever.",
"fieldTextSkipPing": "Choose if a successful ping is required before a monitor process is started.",
"fieldTextIsOnvif": "Is this an ONVIF compliant camera?",
- "fieldTextOnvifNonStandard": "Is this a Non-Standard ONVIF camera?",
+ "fieldTextOnvifHomeControl": "Some ONVIF cameras seem to follow different standards on how to PTZ to Home position. Try each of the following if your PTZ Auto Tracking doesn't automatically return to home after 7 seconds of inactivity.",
"fieldTextOnvifPort": "ONVIF is usually run on port 8000. This can be 80 as well depending on your camera model.",
"fieldTextAduration": "Specify how many microseconds are analyzed to probe the input. Set to 100000 if you are using RTSP and having stream issues.",
"fieldTextProbesize": "Specify how big to make the analyzation probe for the input. Set to 100000 if you are using RTSP and having stream issues.",
diff --git a/libs/control/ptz.js b/libs/control/ptz.js
index abdf0aec..e983ee0d 100644
--- a/libs/control/ptz.js
+++ b/libs/control/ptz.js
@@ -200,8 +200,10 @@ module.exports = function(s,config,lang){
options.direction = doMove ? options.direction : 'stopMove';
switch(options.direction){
case'center':
+ const onvifHomeControlMethod = monitorConfig.details.onvif_non_standard
+ const actionFunction = onvifHomeControlMethod === '2' ? moveToHomePosition : moveToPresetPosition
moveLock[options.ke + options.id] = true
- moveToPresetPosition({
+ actionFunction({
ke: options.ke,
id: options.id,
},(endData) => {
@@ -259,6 +261,8 @@ module.exports = function(s,config,lang){
const controlUrlMethod = monitorConfig.details.control_url_method || 'GET'
const controlUrlStopTimeout = options.moveTimeout || parseInt(monitorConfig.details.control_url_stop_timeout) || 1000
const stopCommandEnabled = monitorConfig.details.control_stop === '1' || monitorConfig.details.control_stop === '2';
+ const axisLock = monitorConfig.details.control_axis_lock
+ const direction = options.direction
if(monitorConfig.details.control !== "1"){
s.userLog(monitorConfig,{
type: lang['Control Error'],
@@ -270,14 +274,28 @@ module.exports = function(s,config,lang){
}
}
let response = {
- direction: options.direction,
+ direction,
+ }
+ if(axisLock){
+ const isHorizontalOnly = axisLock === '1'
+ const isVerticalOnly = axisLock === '2'
+ const moveIsHorizontal = direction === 'left' || direction === 'right'
+ const moveIsVertical = direction === 'up' || direction === 'down'
+ if(
+ isHorizontalOnly && moveIsVertical ||
+ isVerticalOnly && moveIsHorizontal
+ ){
+ response.ok = false
+ response.msg = isHorizontalOnly ? lang['Pan Only'] : lang['Tilt Only']
+ return response
+ }
}
if(controlUrlMethod === 'ONVIF'){
- if(options.direction === 'center'){
+ if(direction === 'center'){
response.moveResponse = await moveOnvifCamera(options,true)
}else if(stopCommandEnabled){
response.moveResponse = await moveOnvifCamera(options,true)
- if(options.direction !== 'stopMove' && options.direction !== 'center'){
+ if(direction !== 'stopMove' && direction !== 'center'){
await asyncSetTimeout(controlUrlStopTimeout)
response.stopMoveResponse = await moveOnvifCamera(options,false)
response.ok = response.moveResponse.ok && response.stopMoveResponse.ok;
@@ -288,7 +306,7 @@ module.exports = function(s,config,lang){
response = await relativeMoveOnvif(options);
}
}else{
- if(options.direction === 'stopMove'){
+ if(direction === 'stopMove'){
response = await moveGeneric(options,false)
}else{
// left, right, up, down, center
@@ -320,22 +338,25 @@ module.exports = function(s,config,lang){
},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 ? '1' : options.PresetToken || profileToken,
- PresetName: options.PresetName || nonStandardOnvif ? '1' : profileToken
- },
- },(endData) => {
- callback(endData)
+ return new Promise((resolve) => {
+ 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 ? '1' : options.PresetToken || profileToken,
+ PresetName: options.PresetName || nonStandardOnvif ? '1' : profileToken
+ },
+ },(response) => {
+ if(callback)callback(response)
+ resolve(response)
+ })
})
}
const moveToPresetPosition = (options,callback) => {
@@ -359,10 +380,50 @@ module.exports = function(s,config,lang){
},
},callback)
}
- const setHomePositionTimeout = (event) => {
+ const moveToHomePosition = (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: 'gotoHomePosition',
+ },
+ options: {
+ ProfileToken: profileToken,
+ },
+ },callback)
+ }
+ const setHomePosition = (options,callback) => {
+ return new Promise((resolve) => {
+ 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: 'setHomePosition',
+ },
+ options: {
+ ProfileToken: profileToken,
+ },
+ },(response) => {
+ if(callback)callback(response)
+ resolve(response)
+ })
+ })
+ }
+ const moveToHomePositionTimeout = (event) => {
+ const groupKey = event.ke
+ const monitorId = event.id
+ const monitorConfig = s.group[groupKey].rawMonitorConfigurations[monitorId]
+ const onvifHomeControlMethod = monitorConfig.details.onvif_non_standard
+ const actionFunction = onvifHomeControlMethod === '2' ? moveToHomePosition : moveToPresetPosition
clearTimeout(ptzTimeoutsUntilResetToHome[event.ke + event.id])
ptzTimeoutsUntilResetToHome[event.ke + event.id] = setTimeout(() => {
- moveToPresetPosition({
+ actionFunction({
ke: event.ke,
id: event.id,
},(endData) => {
@@ -426,47 +487,35 @@ module.exports = function(s,config,lang){
},(msg) => {
s.userLog(event,msg)
// console.log(msg)
- setHomePositionTimeout(event)
+ moveToHomePositionTimeout(event)
})
}else{
- setHomePositionTimeout(event)
+ moveToHomePositionTimeout(event)
}
}
- function setHomePositionPreset(e){
+ async function setHomePositionPreset(e){
+ const groupKey = e.ke
const monitorId = e.mid || e.id
- return new Promise((resolve) => {
- setTimeout(() => {
- setPresetForCurrentPosition({
- ke: e.ke,
- id: monitorId
- },(endData) => {
- if(endData.ok === false){
- setTimeout(() => {
- setPresetForCurrentPosition({
- ke: e.ke,
- id: monitorId
- },(endData) => {
- if(endData.ok === false){
- setTimeout(() => {
- setPresetForCurrentPosition({
- ke: e.ke,
- id: monitorId
- },(endData) => {
- console.log(endData)
- resolve()
- })
- },5000)
- }else{
- resolve()
- }
- })
- },5000)
- }else{
- resolve()
- }
- })
- },5000)
- })
+ const controlOptions = {
+ ke: groupKey,
+ id: monitorId
+ }
+ const waitTime = 5000
+ let response = {ok: false}
+ const monitorConfig = s.group[groupKey].rawMonitorConfigurations[monitorId]
+ const onvifHomeControlMethod = monitorConfig.details.onvif_non_standard
+ const actionFunction = onvifHomeControlMethod === '2' ? setHomePosition : setPresetForCurrentPosition
+ await asyncSetTimeout(waitTime)
+ response = await actionFunction(controlOptions)
+ if(response.ok === false){
+ await asyncSetTimeout(waitTime)
+ response = await actionFunction(controlOptions)
+ if(response.ok === false){
+ await asyncSetTimeout(waitTime)
+ response = await actionFunction(controlOptions)
+ }
+ }
+ return response
}
return {
startMove,
diff --git a/web/assets/js/bs5.monitorSettings.js b/web/assets/js/bs5.monitorSettings.js
index 69099712..cd1a5c8f 100644
--- a/web/assets/js/bs5.monitorSettings.js
+++ b/web/assets/js/bs5.monitorSettings.js
@@ -52,6 +52,7 @@ function generateDefaultMonitorSettings(){
"skip_ping": null,
"is_onvif": null,
"onvif_port": "",
+ "onvif_events": "0",
"primary_input": "0",
"aduration": "1000000000",
"probesize": "1000000000",
@@ -229,12 +230,16 @@ function generateDefaultMonitorSettings(){
"detector_buffer_hls_list_size": "",
"detector_buffer_start_number": "",
"detector_buffer_live_start_index": "",
+ "detector_ptz_follow": "0",
"control": "0",
"control_base_url": "",
- "control_url_method": null,
+ "onvif_non_standard":"1",
+ "control_url_method":"ONVIF",
+ "control_turn_speed":"0.01",
"control_digest_auth": null,
- "control_stop": "0",
- "control_url_stop_timeout": "",
+ "control_axis_lock": "",
+ "control_stop": "1",
+ "control_url_stop_timeout": "500",
"control_url_center": "",
"control_url_left": "",
"control_url_left_stop": "",