Add PTZ Preset Patrol with Generic Gamepad
parent
ae070a114c
commit
cd8d3d4ab2
|
|
@ -74,11 +74,15 @@
|
||||||
"Failed to Edit Account": "Failed to Edit Account",
|
"Failed to Edit Account": "Failed to Edit Account",
|
||||||
"How to Connect": "How to Connect",
|
"How to Connect": "How to Connect",
|
||||||
"Cycle": "Cycle",
|
"Cycle": "Cycle",
|
||||||
|
"Auto Placement": "Auto Placement",
|
||||||
"Cycle Interval": "Cycle Interval",
|
"Cycle Interval": "Cycle Interval",
|
||||||
"Cycle Monitor Height": "Cycle Monitor Height",
|
"Rows and Columns": "Rows and Columns",
|
||||||
"Number of Cycle Monitors": "Number of Cycle Monitors",
|
"Number of Monitors": "Number of Monitors",
|
||||||
|
"Number of Rows": "Number of Rows",
|
||||||
|
"Number of Columns": "Number of Columns",
|
||||||
"Cycle Monitors": "Cycle Monitors",
|
"Cycle Monitors": "Cycle Monitors",
|
||||||
"Cycle Monitors per row": "Cycle Monitors per row",
|
"Cycle Monitors per row": "Cycle Monitors per row",
|
||||||
|
"General": "General",
|
||||||
"Login": "Login",
|
"Login": "Login",
|
||||||
"Room ID": "Room ID",
|
"Room ID": "Room ID",
|
||||||
"Substream": "Substream",
|
"Substream": "Substream",
|
||||||
|
|
@ -170,6 +174,7 @@
|
||||||
"Open All Monitors": "Open All Monitors",
|
"Open All Monitors": "Open All Monitors",
|
||||||
"Open Wall Display": "Open Wall Display",
|
"Open Wall Display": "Open Wall Display",
|
||||||
"New Wall Display": "New Wall Display",
|
"New Wall Display": "New Wall Display",
|
||||||
|
"Wall Display Settings": "Wall Display Settings",
|
||||||
"openWallViewInfo": "Open Monitors in the top right of this window.",
|
"openWallViewInfo": "Open Monitors in the top right of this window.",
|
||||||
"Accounts": "Accounts",
|
"Accounts": "Accounts",
|
||||||
"Settings": "Settings",
|
"Settings": "Settings",
|
||||||
|
|
@ -468,6 +473,7 @@
|
||||||
"ONVIF Port": "ONVIF Port",
|
"ONVIF Port": "ONVIF Port",
|
||||||
"ONVIF Scanner": "ONVIF Scanner",
|
"ONVIF Scanner": "ONVIF Scanner",
|
||||||
"ONVIF Events": "ONVIF Events",
|
"ONVIF Events": "ONVIF Events",
|
||||||
|
"ONVIFNotEnabled": "ONVIF Not Enabled in Monitor Settings",
|
||||||
"ONVIFEventsNotAvailable": "ONVIF Events not Available",
|
"ONVIFEventsNotAvailable": "ONVIF Events not Available",
|
||||||
"ONVIFEventsNotAvailableText1": "This service may not be available for this camera or ONVIF has not initialized yet.",
|
"ONVIFEventsNotAvailableText1": "This service may not be available for this camera or ONVIF has not initialized yet.",
|
||||||
"ONVIFnotCompliantProfileT": "Camera is not ONVIF Profile T Compliant",
|
"ONVIFnotCompliantProfileT": "Camera is not ONVIF Profile T Compliant",
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,10 @@ module.exports = function(s,config,lang,app,io){
|
||||||
createSnapshot,
|
createSnapshot,
|
||||||
addCredentialsToStreamLink,
|
addCredentialsToStreamLink,
|
||||||
} = require('../monitor/utils.js')(s,config,lang)
|
} = require('../monitor/utils.js')(s,config,lang)
|
||||||
|
const {
|
||||||
|
startPatrolPresets,
|
||||||
|
stopPatrolPresets,
|
||||||
|
} = require('../onvifDeviceManager/utils.js')(s,config,lang)
|
||||||
const createOnvifDevice = async (onvifAuth) => {
|
const createOnvifDevice = async (onvifAuth) => {
|
||||||
var response = {ok: false}
|
var response = {ok: false}
|
||||||
const monitorConfig = s.group[onvifAuth.ke].rawMonitorConfigurations[onvifAuth.id]
|
const monitorConfig = s.group[onvifAuth.ke].rawMonitorConfigurations[onvifAuth.id]
|
||||||
|
|
@ -43,6 +47,14 @@ module.exports = function(s,config,lang,app,io){
|
||||||
})
|
})
|
||||||
return newOptions
|
return newOptions
|
||||||
}
|
}
|
||||||
|
const getOnvifDevice = async (groupKey, monitorId) => {
|
||||||
|
const onvifDevice = s.group[groupKey].activeMonitors[monitorId].onvifConnection;
|
||||||
|
if(!onvifDevice){
|
||||||
|
return (await createOnvifDevice(onvifAuth)).device
|
||||||
|
}else{
|
||||||
|
return onvifDevice
|
||||||
|
}
|
||||||
|
}
|
||||||
const runOnvifMethod = (onvifOptions,callback) => {
|
const runOnvifMethod = (onvifOptions,callback) => {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
var onvifAuth = onvifOptions.auth
|
var onvifAuth = onvifOptions.auth
|
||||||
|
|
@ -181,6 +193,52 @@ module.exports = function(s,config,lang,app,io){
|
||||||
})
|
})
|
||||||
},res,req);
|
},res,req);
|
||||||
})
|
})
|
||||||
|
/**
|
||||||
|
* API : ONVIF Start Patrol
|
||||||
|
*/
|
||||||
|
app.post(config.webPaths.apiPrefix+':auth/onvifStartPatrol/:ke/:id',function (req,res){
|
||||||
|
s.auth(req.params, async function(user){
|
||||||
|
const endData = { ok: true }
|
||||||
|
try{
|
||||||
|
const groupKey = req.params.ke;
|
||||||
|
const monitorId = req.params.id;
|
||||||
|
const onvifEnabled = s.group[groupKey].rawMonitorConfigurations[monitorId].details.is_onvif === '1';
|
||||||
|
if(onvifEnabled){
|
||||||
|
const patrolId = `${groupKey}_${monitorId}`;
|
||||||
|
const onvifDevice = await getOnvifDevice(groupKey, monitorId);
|
||||||
|
const startingPresetToken = s.getPostData(req,'startingPresetToken');
|
||||||
|
const patrolIndexTimeout = s.getPostData(req,'patrolIndexTimeout');
|
||||||
|
const speed = s.getPostData(req,'speed');
|
||||||
|
await startPatrolPresets(patrolId, onvifDevice, startingPresetToken, patrolIndexTimeout, speed)
|
||||||
|
}else{
|
||||||
|
endData.ok = false;
|
||||||
|
endData.err = lang.ONVIFNotEnabled;
|
||||||
|
}
|
||||||
|
}catch(err){
|
||||||
|
endData.ok = false;
|
||||||
|
endData.err = err.toString()
|
||||||
|
}
|
||||||
|
s.closeJsonResponse(res,endData)
|
||||||
|
},res,req);
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* API : ONVIF Stop Patrol
|
||||||
|
*/
|
||||||
|
app.get(config.webPaths.apiPrefix+':auth/onvifStopPatrol/:ke/:id',function (req,res){
|
||||||
|
s.auth(req.params, async function(user){
|
||||||
|
const endData = { ok: true }
|
||||||
|
try{
|
||||||
|
const groupKey = req.params.ke;
|
||||||
|
const monitorId = req.params.id;
|
||||||
|
const patrolId = `${groupKey}_${monitorId}`;
|
||||||
|
await stopPatrolPresets(patrolId)
|
||||||
|
}catch(err){
|
||||||
|
endData.ok = false;
|
||||||
|
endData.err = err.toString()
|
||||||
|
}
|
||||||
|
s.closeJsonResponse(res,endData)
|
||||||
|
},res,req);
|
||||||
|
})
|
||||||
s.getSnapshotFromOnvif = getSnapshotFromOnvif
|
s.getSnapshotFromOnvif = getSnapshotFromOnvif
|
||||||
s.createOnvifDevice = createOnvifDevice
|
s.createOnvifDevice = createOnvifDevice
|
||||||
s.runOnvifMethod = runOnvifMethod
|
s.runOnvifMethod = runOnvifMethod
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// relies on https://gitlab.com/Shinobi-Systems/shinobi-onvif
|
// relies on https://gitlab.com/Shinobi-Systems/shinobi-onvif
|
||||||
|
const currentlyPatrolling = {};
|
||||||
const {
|
const {
|
||||||
mergeDeep
|
mergeDeep
|
||||||
} = require('../common.js')
|
} = require('../common.js')
|
||||||
|
|
@ -498,6 +499,65 @@ const getUIFieldValues = async (onvifDevice) => {
|
||||||
all: true,
|
all: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const getPresets = async (onvifDevice, asObject = false, profileToken = "__CURRENT_TOKEN") => {
|
||||||
|
const presets = (await runOnvifMethod({
|
||||||
|
device: onvifDevice,
|
||||||
|
action: 'getPresets',
|
||||||
|
service: 'ptz',
|
||||||
|
options: { "ProfileToken": profileToken }
|
||||||
|
})).responseFromDevice.GetPresetsResponse.Preset.map((item) => {
|
||||||
|
return { token: item.$.token, name: item.Name }
|
||||||
|
});
|
||||||
|
if(asObject){
|
||||||
|
const theObject = {};
|
||||||
|
for(preset of presets){
|
||||||
|
theObject[preset.token] = preset
|
||||||
|
}
|
||||||
|
return theObject
|
||||||
|
}
|
||||||
|
return presets
|
||||||
|
}
|
||||||
|
const goToPreset = async (onvifDevice, presetToken, speed = 1) => {
|
||||||
|
const response = (await runOnvifMethod({
|
||||||
|
device: onvifDevice,
|
||||||
|
action: 'getPresets',
|
||||||
|
service: 'ptz',
|
||||||
|
options: {
|
||||||
|
"ProfileToken":"__CURRENT_TOKEN",
|
||||||
|
"PresetToken": presetToken,
|
||||||
|
"Speed": { x: speed, y: speed, z: speed }
|
||||||
|
}
|
||||||
|
})).responseFromDevice;
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
const getNextPresetToken = (presetsAsObject, presetToken) => {
|
||||||
|
const nextToken = parseInt(presetToken) + 1;
|
||||||
|
const chosenToken = presetsAsObject[nextToken] ? `${nextToken}` : Object.values(presets)[0].token
|
||||||
|
return chosenToken
|
||||||
|
}
|
||||||
|
const startPatrolPresets = async (patrolId, onvifDevice, startingPresetToken, patrolIndexTimeout = 5000, speed = 1) => {
|
||||||
|
await stopPatrolPresets(patrolId)
|
||||||
|
const presets = await getPresets(onvifDevice, true);
|
||||||
|
await goToPreset(onvifDevice, startingPresetToken, speed)
|
||||||
|
const nextFromStartToken = getNextPresetToken(presets, startingPresetToken)
|
||||||
|
const moveToPresetOnTimeout = (presetToken) => {
|
||||||
|
currentlyPatrolling[patrolId] = setTimeout(async () => {
|
||||||
|
await goToPreset(onvifDevice, presetToken, speed)
|
||||||
|
const nextToken = getNextPresetToken(presets, presetToken)
|
||||||
|
moveToPresetOnTimeout(nextToken)
|
||||||
|
}, patrolIndexTimeout)
|
||||||
|
}
|
||||||
|
moveToPresetOnTimeout(nextFromStartToken)
|
||||||
|
}
|
||||||
|
const stopPatrolPresets = (patrolId) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
clearTimeout(currentlyPatrolling[patrolId])
|
||||||
|
setTimeout(() => {
|
||||||
|
clearTimeout(currentlyPatrolling[patrolId])
|
||||||
|
resolve()
|
||||||
|
},1000)
|
||||||
|
})
|
||||||
|
}
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getDeviceInformation: getDeviceInformation,
|
getDeviceInformation: getDeviceInformation,
|
||||||
setHostname: setHostname,
|
setHostname: setHostname,
|
||||||
|
|
@ -514,4 +574,9 @@ module.exports = {
|
||||||
setDiscoveryMode: setDiscoveryMode,
|
setDiscoveryMode: setDiscoveryMode,
|
||||||
setNetworkInterface: setNetworkInterface,
|
setNetworkInterface: setNetworkInterface,
|
||||||
getUIFieldValues: getUIFieldValues,
|
getUIFieldValues: getUIFieldValues,
|
||||||
|
getPresets,
|
||||||
|
goToPreset,
|
||||||
|
getNextPresetToken,
|
||||||
|
startPatrolPresets,
|
||||||
|
stopPatrolPresets,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,14 @@ $(document).ready(function() {
|
||||||
runPtzCommand(selectedMonitor, 'center')
|
runPtzCommand(selectedMonitor, 'center')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startPatrol(){
|
||||||
|
return onvifStartPatrol(selectedMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopPatrol(){
|
||||||
|
return onvifStopPatrol(selectedMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
function translatePointTiltStick(x, y){
|
function translatePointTiltStick(x, y){
|
||||||
if(x > stickBase && !lastPtzDirection['right']){
|
if(x > stickBase && !lastPtzDirection['right']){
|
||||||
lastPtzDirection['right'] = true
|
lastPtzDirection['right'] = true
|
||||||
|
|
@ -264,10 +272,9 @@ $(document).ready(function() {
|
||||||
const gp = navigator.getGamepads()[0];
|
const gp = navigator.getGamepads()[0];
|
||||||
getButtonsPressed(gp, function(buttonCode){
|
getButtonsPressed(gp, function(buttonCode){
|
||||||
if(buttonCode == 10){
|
if(buttonCode == 10){
|
||||||
closeSnapshot()
|
startPatrol()
|
||||||
openSnapshot()
|
|
||||||
}else if(buttonCode == 11){
|
}else if(buttonCode == 11){
|
||||||
closeSnapshot()
|
stopPatrol()
|
||||||
}else{
|
}else{
|
||||||
buttonPressAction(buttonCode)
|
buttonPressAction(buttonCode)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
function onvifStartPatrol(monitorId, startingPresetToken = '1', patrolIndexTimeout = 5000, speed = 1){
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
$.post(getApiPrefix('onvifStartPatrol') + '/' + monitorId, {
|
||||||
|
startingPresetToken,
|
||||||
|
patrolIndexTimeout,
|
||||||
|
speed,
|
||||||
|
},function(response){
|
||||||
|
resolve(response)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function onvifStopPatrol(monitorId){
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
$.get(getApiPrefix('onvifStopPatrol') + '/' + monitorId,function(response){
|
||||||
|
resolve(response)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -134,14 +134,16 @@ $(document).ready(function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setCameraFromButtonCode(buttonCode = 0, preAdded){
|
function getMonitorFromButtonCode(buttonCode = 0, preAdded){
|
||||||
const addedOneToButtonCode = preAdded ? buttonCode : parseInt(buttonCode) + 1
|
const addedOneToButtonCode = preAdded ? buttonCode : parseInt(buttonCode) + 1
|
||||||
try{
|
|
||||||
console.log('addedOneToButtonCode', addedOneToButtonCode)
|
|
||||||
console.log('monitorKeys', monitorKeys)
|
|
||||||
const monitor = loadedMonitors[monitorKeys[addedOneToButtonCode]];
|
const monitor = loadedMonitors[monitorKeys[addedOneToButtonCode]];
|
||||||
console.log('monitor', monitor)
|
|
||||||
const monitorId = monitor.mid;
|
const monitorId = monitor.mid;
|
||||||
|
return { monitor, monitorId }
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCameraFromButtonCode(buttonCode = 0, preAdded){
|
||||||
|
try{
|
||||||
|
const { monitor, monitorId } = getMonitorFromButtonCode(buttonCode, preAdded)
|
||||||
const isFullscreened = !!document.fullscreenElement;
|
const isFullscreened = !!document.fullscreenElement;
|
||||||
if(isFullscreened) {
|
if(isFullscreened) {
|
||||||
document.exitFullscreen()
|
document.exitFullscreen()
|
||||||
|
|
@ -180,6 +182,14 @@ $(document).ready(function() {
|
||||||
runPtzCommand(selectedMonitor, 'center')
|
runPtzCommand(selectedMonitor, 'center')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startPatrol(){
|
||||||
|
return onvifStartPatrol(selectedMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopPatrol(){
|
||||||
|
return onvifStopPatrol(selectedMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
function translatePointTiltStick(x, y){
|
function translatePointTiltStick(x, y){
|
||||||
if(x > stickBase && !lastPtzDirection['right']){
|
if(x > stickBase && !lastPtzDirection['right']){
|
||||||
lastPtzDirection['right'] = true
|
lastPtzDirection['right'] = true
|
||||||
|
|
@ -286,10 +296,9 @@ $(document).ready(function() {
|
||||||
const gp = navigator.getGamepads()[0];
|
const gp = navigator.getGamepads()[0];
|
||||||
getButtonsPressed(gp, function(buttonCode){
|
getButtonsPressed(gp, function(buttonCode){
|
||||||
if(buttonCode == 10){
|
if(buttonCode == 10){
|
||||||
// closeSnapshot()
|
startPatrol()
|
||||||
}else if(buttonCode == 11){
|
}else if(buttonCode == 11){
|
||||||
// closeSnapshot()
|
stopPatrol()
|
||||||
// openSnapshot()
|
|
||||||
}else{
|
}else{
|
||||||
buttonPressAction(buttonCode)
|
buttonPressAction(buttonCode)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
<script src="<%-window.libURL%>assets/js/bs5.monitorsUtils.js"></script>
|
<script src="<%-window.libURL%>assets/js/bs5.monitorsUtils.js"></script>
|
||||||
<script src="<%-window.libURL%>assets/js/bs5.monitorStates.js"></script>
|
<script src="<%-window.libURL%>assets/js/bs5.monitorStates.js"></script>
|
||||||
<script src="<%-window.libURL%>assets/js/bs5.schedules.js"></script>
|
<script src="<%-window.libURL%>assets/js/bs5.schedules.js"></script>
|
||||||
|
<script src="<%-window.libURL%>assets/js/bs5.onvif.js"></script>
|
||||||
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.js"></script>
|
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.js"></script>
|
||||||
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.cycle.js"></script>
|
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.cycle.js"></script>
|
||||||
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.gamepad.js"></script>
|
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.gamepad.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -92,5 +92,6 @@
|
||||||
<script src="<%- urlPrefix %>assets/js/bs5.extenders.js"></script>
|
<script src="<%- urlPrefix %>assets/js/bs5.extenders.js"></script>
|
||||||
<script src="<%- urlPrefix %>assets/js/bs5.websocket.js"></script>
|
<script src="<%- urlPrefix %>assets/js/bs5.websocket.js"></script>
|
||||||
<script src="<%- urlPrefix %>assets/js/bs5.wallview.js"></script>
|
<script src="<%- urlPrefix %>assets/js/bs5.wallview.js"></script>
|
||||||
|
<script src="<%- urlPrefix %>assets/js/bs5.onvif.js"></script>
|
||||||
<script src="<%- urlPrefix %>assets/js/bs5.wallview.gamepad.js"></script>
|
<script src="<%- urlPrefix %>assets/js/bs5.wallview.gamepad.js"></script>
|
||||||
<script src="<%- urlPrefix %>assets/js/bs5.wallview.cycle.js"></script>
|
<script src="<%- urlPrefix %>assets/js/bs5.wallview.cycle.js"></script>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue