diff --git a/plugins/onvif/.vscode/settings.json b/plugins/onvif/.vscode/settings.json index 77ccdbd6db..a620593fa1 100644 --- a/plugins/onvif/.vscode/settings.json +++ b/plugins/onvif/.vscode/settings.json @@ -1,4 +1,4 @@ { - "scrypted.debugHost": "127.0.0.1", + "scrypted.debugHost": "scrypted-nvr", } \ No newline at end of file diff --git a/plugins/onvif/package-lock.json b/plugins/onvif/package-lock.json index 1097256540..58c13c60cc 100644 --- a/plugins/onvif/package-lock.json +++ b/plugins/onvif/package-lock.json @@ -1,12 +1,12 @@ { "name": "@scrypted/onvif", - "version": "0.1.24", + "version": "0.1.25", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@scrypted/onvif", - "version": "0.1.24", + "version": "0.1.25", "license": "Apache", "dependencies": { "@scrypted/common": "file:../../common", diff --git a/plugins/onvif/package.json b/plugins/onvif/package.json index 04157bead0..0495b75599 100644 --- a/plugins/onvif/package.json +++ b/plugins/onvif/package.json @@ -1,6 +1,6 @@ { "name": "@scrypted/onvif", - "version": "0.1.24", + "version": "0.1.25", "description": "ONVIF Camera Plugin for Scrypted", "author": "Scrypted", "license": "Apache", diff --git a/plugins/onvif/src/onvif-ptz.ts b/plugins/onvif/src/onvif-ptz.ts index 63ed71218a..51fe1ba7ae 100644 --- a/plugins/onvif/src/onvif-ptz.ts +++ b/plugins/onvif/src/onvif-ptz.ts @@ -25,7 +25,19 @@ export class OnvifPtzMixin extends SettingsMixinDeviceBase implements zoom: ptz.includes('Zoom'), } } - } + }, + ptzMovementType: { + title: 'PTZ Movement Type', + description: 'The type of movement to use for PTZ commands by default.', + type: 'string', + choices: [ + 'Default', + PanTiltZoomMovement.Absolute, + PanTiltZoomMovement.Relative, + PanTiltZoomMovement.Continuous, + ], + defaultValue: 'Default', + }, }); constructor(options: SettingsMixinDeviceOptions) { @@ -55,13 +67,29 @@ export class OnvifPtzMixin extends SettingsMixinDeviceBase implements }; } - if (command.movement === PanTiltZoomMovement.Absolute) { + let movement = command.movement || this.storageSettings.values.ptzMovementType; + if (movement === PanTiltZoomMovement.Absolute) { return new Promise((r, f) => { client.cam.absoluteMove({ x: command.pan, y: command.tilt, zoom: command.zoom, - speed: speed + speed: speed, + }, (e, result, xml) => { + if (e) + return f(e); + r(); + }) + }) + } + else if (movement === PanTiltZoomMovement.Continuous) { + return new Promise((r, f) => { + client.cam.continuousMove({ + x: command.pan, + y: command.tilt, + zoom: command.zoom, + speed: speed, + timeout: command.timeout || 1000, }, (e, result, xml) => { if (e) return f(e); diff --git a/sdk/types/scrypted_python/scrypted_sdk/types.py b/sdk/types/scrypted_python/scrypted_sdk/types.py index e0d9e8ecc7..4e334bc44c 100644 --- a/sdk/types/scrypted_python/scrypted_sdk/types.py +++ b/sdk/types/scrypted_python/scrypted_sdk/types.py @@ -64,6 +64,7 @@ class MediaPlayerState(str, Enum): class PanTiltZoomMovement(str, Enum): Absolute = "Absolute" + Continuous = "Continuous" Relative = "Relative" class ScryptedDeviceType(str, Enum): @@ -712,6 +713,7 @@ class PanTiltZoomCommand(TypedDict): pan: float # Ranges between -1 and 1. speed: Any # The speed of the movement. tilt: float # Ranges between -1 and 1. + timeout: float # The duration of the movement in milliseconds. zoom: float # Ranges between 0 and 1 for max zoom. class Position(TypedDict): diff --git a/sdk/types/src/types.input.ts b/sdk/types/src/types.input.ts index 175ae55c73..d85481551c 100644 --- a/sdk/types/src/types.input.ts +++ b/sdk/types/src/types.input.ts @@ -949,7 +949,8 @@ export interface VideoCameraMask { export enum PanTiltZoomMovement { Absolute = "Absolute", - Relative = "Relative" + Relative = "Relative", + Continuous = "Continuous", } export interface PanTiltZoomCommand { @@ -985,7 +986,11 @@ export interface PanTiltZoomCommand { * Ranges between 0 and 1 for max zoom. */ zoom?: number; - } + }; + /** + * The duration of the movement in milliseconds. + */ + timeout?: number; } export interface PanTiltZoomCapabilities {