Add PTZ Preset Patrol with Generic Gamepad
parent
ae070a114c
commit
cd8d3d4ab2
|
@ -74,11 +74,15 @@
|
|||
"Failed to Edit Account": "Failed to Edit Account",
|
||||
"How to Connect": "How to Connect",
|
||||
"Cycle": "Cycle",
|
||||
"Auto Placement": "Auto Placement",
|
||||
"Cycle Interval": "Cycle Interval",
|
||||
"Cycle Monitor Height": "Cycle Monitor Height",
|
||||
"Number of Cycle Monitors": "Number of Cycle Monitors",
|
||||
"Rows and Columns": "Rows and Columns",
|
||||
"Number of Monitors": "Number of Monitors",
|
||||
"Number of Rows": "Number of Rows",
|
||||
"Number of Columns": "Number of Columns",
|
||||
"Cycle Monitors": "Cycle Monitors",
|
||||
"Cycle Monitors per row": "Cycle Monitors per row",
|
||||
"General": "General",
|
||||
"Login": "Login",
|
||||
"Room ID": "Room ID",
|
||||
"Substream": "Substream",
|
||||
|
@ -170,6 +174,7 @@
|
|||
"Open All Monitors": "Open All Monitors",
|
||||
"Open Wall Display": "Open Wall Display",
|
||||
"New Wall Display": "New Wall Display",
|
||||
"Wall Display Settings": "Wall Display Settings",
|
||||
"openWallViewInfo": "Open Monitors in the top right of this window.",
|
||||
"Accounts": "Accounts",
|
||||
"Settings": "Settings",
|
||||
|
@ -468,6 +473,7 @@
|
|||
"ONVIF Port": "ONVIF Port",
|
||||
"ONVIF Scanner": "ONVIF Scanner",
|
||||
"ONVIF Events": "ONVIF Events",
|
||||
"ONVIFNotEnabled": "ONVIF Not Enabled in Monitor Settings",
|
||||
"ONVIFEventsNotAvailable": "ONVIF Events not Available",
|
||||
"ONVIFEventsNotAvailableText1": "This service may not be available for this camera or ONVIF has not initialized yet.",
|
||||
"ONVIFnotCompliantProfileT": "Camera is not ONVIF Profile T Compliant",
|
||||
|
|
|
@ -9,6 +9,10 @@ module.exports = function(s,config,lang,app,io){
|
|||
createSnapshot,
|
||||
addCredentialsToStreamLink,
|
||||
} = require('../monitor/utils.js')(s,config,lang)
|
||||
const {
|
||||
startPatrolPresets,
|
||||
stopPatrolPresets,
|
||||
} = require('../onvifDeviceManager/utils.js')(s,config,lang)
|
||||
const createOnvifDevice = async (onvifAuth) => {
|
||||
var response = {ok: false}
|
||||
const monitorConfig = s.group[onvifAuth.ke].rawMonitorConfigurations[onvifAuth.id]
|
||||
|
@ -43,6 +47,14 @@ module.exports = function(s,config,lang,app,io){
|
|||
})
|
||||
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) => {
|
||||
return new Promise((resolve) => {
|
||||
var onvifAuth = onvifOptions.auth
|
||||
|
@ -181,6 +193,52 @@ module.exports = function(s,config,lang,app,io){
|
|||
})
|
||||
},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.createOnvifDevice = createOnvifDevice
|
||||
s.runOnvifMethod = runOnvifMethod
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// relies on https://gitlab.com/Shinobi-Systems/shinobi-onvif
|
||||
const currentlyPatrolling = {};
|
||||
const {
|
||||
mergeDeep
|
||||
} = require('../common.js')
|
||||
|
@ -498,6 +499,65 @@ const getUIFieldValues = async (onvifDevice) => {
|
|||
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 = {
|
||||
getDeviceInformation: getDeviceInformation,
|
||||
setHostname: setHostname,
|
||||
|
@ -514,4 +574,9 @@ module.exports = {
|
|||
setDiscoveryMode: setDiscoveryMode,
|
||||
setNetworkInterface: setNetworkInterface,
|
||||
getUIFieldValues: getUIFieldValues,
|
||||
getPresets,
|
||||
goToPreset,
|
||||
getNextPresetToken,
|
||||
startPatrolPresets,
|
||||
stopPatrolPresets,
|
||||
}
|
||||
|
|
|
@ -160,6 +160,14 @@ $(document).ready(function() {
|
|||
runPtzCommand(selectedMonitor, 'center')
|
||||
}
|
||||
|
||||
function startPatrol(){
|
||||
return onvifStartPatrol(selectedMonitor)
|
||||
}
|
||||
|
||||
function stopPatrol(){
|
||||
return onvifStopPatrol(selectedMonitor)
|
||||
}
|
||||
|
||||
function translatePointTiltStick(x, y){
|
||||
if(x > stickBase && !lastPtzDirection['right']){
|
||||
lastPtzDirection['right'] = true
|
||||
|
@ -264,10 +272,9 @@ $(document).ready(function() {
|
|||
const gp = navigator.getGamepads()[0];
|
||||
getButtonsPressed(gp, function(buttonCode){
|
||||
if(buttonCode == 10){
|
||||
closeSnapshot()
|
||||
openSnapshot()
|
||||
startPatrol()
|
||||
}else if(buttonCode == 11){
|
||||
closeSnapshot()
|
||||
stopPatrol()
|
||||
}else{
|
||||
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 monitor = loadedMonitors[monitorKeys[addedOneToButtonCode]];
|
||||
const monitorId = monitor.mid;
|
||||
return { monitor, monitorId }
|
||||
}
|
||||
|
||||
function setCameraFromButtonCode(buttonCode = 0, preAdded){
|
||||
try{
|
||||
console.log('addedOneToButtonCode', addedOneToButtonCode)
|
||||
console.log('monitorKeys', monitorKeys)
|
||||
const monitor = loadedMonitors[monitorKeys[addedOneToButtonCode]];
|
||||
console.log('monitor', monitor)
|
||||
const monitorId = monitor.mid;
|
||||
const { monitor, monitorId } = getMonitorFromButtonCode(buttonCode, preAdded)
|
||||
const isFullscreened = !!document.fullscreenElement;
|
||||
if(isFullscreened) {
|
||||
document.exitFullscreen()
|
||||
|
@ -180,6 +182,14 @@ $(document).ready(function() {
|
|||
runPtzCommand(selectedMonitor, 'center')
|
||||
}
|
||||
|
||||
function startPatrol(){
|
||||
return onvifStartPatrol(selectedMonitor)
|
||||
}
|
||||
|
||||
function stopPatrol(){
|
||||
return onvifStopPatrol(selectedMonitor)
|
||||
}
|
||||
|
||||
function translatePointTiltStick(x, y){
|
||||
if(x > stickBase && !lastPtzDirection['right']){
|
||||
lastPtzDirection['right'] = true
|
||||
|
@ -286,10 +296,9 @@ $(document).ready(function() {
|
|||
const gp = navigator.getGamepads()[0];
|
||||
getButtonsPressed(gp, function(buttonCode){
|
||||
if(buttonCode == 10){
|
||||
// closeSnapshot()
|
||||
startPatrol()
|
||||
}else if(buttonCode == 11){
|
||||
// closeSnapshot()
|
||||
// openSnapshot()
|
||||
stopPatrol()
|
||||
}else{
|
||||
buttonPressAction(buttonCode)
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
<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.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.cycle.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.websocket.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.cycle.js"></script>
|
||||
|
|
Loading…
Reference in New Issue