mirror of
https://github.com/koush/scrypted.git
synced 2026-02-12 01:54:27 +00:00
Merge branch 'main' of github.com:koush/scrypted into main
This commit is contained in:
27
plugins/synology-ss/package-lock.json
generated
27
plugins/synology-ss/package-lock.json
generated
@@ -17,8 +17,7 @@
|
||||
}
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.0.93",
|
||||
"version": "0.0.121",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
@@ -38,7 +37,10 @@
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.2.6",
|
||||
"typedoc": "^0.22.8",
|
||||
"typescript-json-schema": "^0.50.1",
|
||||
"webpack": "^5.59.0"
|
||||
},
|
||||
@@ -49,6 +51,10 @@
|
||||
"scrypted-package-json": "bin/scrypted-package-json.js",
|
||||
"scrypted-readme": "bin/scrypted-readme.js",
|
||||
"scrypted-webpack": "bin/scrypted-webpack.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"ts-node": "^10.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@scrypted/sdk": {
|
||||
@@ -56,9 +62,9 @@
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "16.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz",
|
||||
"integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==",
|
||||
"version": "16.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz",
|
||||
"integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/axios": {
|
||||
@@ -101,6 +107,7 @@
|
||||
"@babel/plugin-transform-typescript": "^7.15.8",
|
||||
"@babel/preset-typescript": "^7.15.0",
|
||||
"@types/node": "^16.11.1",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"babel-loader": "^8.2.3",
|
||||
@@ -109,15 +116,19 @@
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.2.6",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.22.8",
|
||||
"typescript-json-schema": "^0.50.1",
|
||||
"webpack": "^5.59.0"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "16.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz",
|
||||
"integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==",
|
||||
"version": "16.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz",
|
||||
"integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import sdk, { ScryptedDeviceBase, DeviceProvider, Settings, Setting, ScryptedDeviceType, VideoCamera, MediaObject, Device, ScryptedInterface, Camera, MediaStreamOptions, PictureOptions } from "@scrypted/sdk";
|
||||
import sdk, { ScryptedDeviceBase, DeviceProvider, HttpRequest, HttpRequestHandler, HttpResponse, Settings, Setting, ScryptedDeviceType, VideoCamera, MediaObject, Device, MotionSensor, ScryptedInterface, Camera, MediaStreamOptions, PictureOptions } from "@scrypted/sdk";
|
||||
import { createInstanceableProviderPlugin, enableInstanceableProviderMode, isInstanceableProviderModeEnabled } from '../../../common/src/provider-plugin';
|
||||
import { recommendRebroadcast } from "../../rtsp/src/recommend";
|
||||
import {SynologyApiClient, SynologyCameraStream, SynologyCamera} from "./api/synology-api-client";
|
||||
|
||||
const { log, deviceManager, mediaManager } = sdk;
|
||||
|
||||
class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, Settings, VideoCamera {
|
||||
class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, HttpRequestHandler, MotionSensor, Settings, VideoCamera {
|
||||
private static readonly DefaultSensorTimeoutSecs: number = 30;
|
||||
|
||||
private motionTimeout?: NodeJS.Timeout;
|
||||
private provider: SynologySurveillanceStation;
|
||||
private streams: SynologyCameraStream[];
|
||||
|
||||
@@ -13,6 +16,7 @@ class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, Setting
|
||||
super(nativeId);
|
||||
this.provider = provider;
|
||||
|
||||
this.motionDetected = false;
|
||||
this.streams = SynologyCameraDevice.identifyStreams(camera);
|
||||
}
|
||||
|
||||
@@ -38,6 +42,7 @@ class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, Setting
|
||||
public async getSettings(): Promise<Setting[]> {
|
||||
const vsos = await this.getVideoStreamOptions();
|
||||
const defaultStream = this.getDefaultStream(vsos);
|
||||
|
||||
return [
|
||||
{
|
||||
title: 'Default Stream',
|
||||
@@ -45,6 +50,20 @@ class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, Setting
|
||||
value: defaultStream?.name,
|
||||
choices: vsos.map(vso => vso.name),
|
||||
description: 'The default stream to use when not specified',
|
||||
},
|
||||
{
|
||||
title: 'Motion Sensor Timeout',
|
||||
key: 'sensorTimeout',
|
||||
type: 'integer',
|
||||
value: this.storage.getItem('sensorTimeout') || SynologyCameraDevice.DefaultSensorTimeoutSecs,
|
||||
description: 'Time to wait in seconds before clearing the motion detected state.',
|
||||
},
|
||||
{
|
||||
title: 'Motion Sensor Webhook',
|
||||
type: 'string',
|
||||
readonly: true,
|
||||
value: await this.getMotionDetectedWebhookUrl(),
|
||||
description: 'To get motion alerts, create an alert rule in Surveillance Station that POSTs to this webhook URL upon motion detected.',
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -61,6 +80,17 @@ class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, Setting
|
||||
this.onDeviceEvent(ScryptedInterface.Settings, undefined);
|
||||
}
|
||||
|
||||
getSensorTimeout() {
|
||||
return (parseInt(this.storage.getItem('sensorTimeout')) || SynologyCameraDevice.DefaultSensorTimeoutSecs) * 1000;
|
||||
}
|
||||
|
||||
resetMotionTimeout() {
|
||||
clearTimeout(this.motionTimeout);
|
||||
this.motionTimeout = setTimeout(() => {
|
||||
this.motionDetected = false;
|
||||
}, this.getSensorTimeout());
|
||||
}
|
||||
|
||||
private async getSnapshot(options?: PictureOptions): Promise<Buffer> {
|
||||
const data = await this.provider.api.getCameraSnapshot(this.nativeId);
|
||||
|
||||
@@ -83,6 +113,7 @@ class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, Setting
|
||||
throw new Error(`Unable to locate RTSP stream for camera ${this.nativeId}`);
|
||||
|
||||
return mediaManager.createFFmpegMediaObject({
|
||||
url: liveViewPaths[0].rtspPath,
|
||||
inputArguments: [
|
||||
"-rtsp_transport",
|
||||
"tcp",
|
||||
@@ -127,6 +158,26 @@ class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, Setting
|
||||
return;
|
||||
}
|
||||
|
||||
public async onRequest(request: HttpRequest, response: HttpResponse): Promise<void> {
|
||||
if (request.url.endsWith('/motionDetected')) {
|
||||
this.motionDetected = true;
|
||||
this.resetMotionTimeout();
|
||||
|
||||
response.send('Success', {
|
||||
code: 200,
|
||||
});
|
||||
} else {
|
||||
response.send('Unsupported operation', {
|
||||
code: 400,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async getMotionDetectedWebhookUrl(): Promise<string> {
|
||||
const webhookUrl = await sdk.endpointManager.getInsecurePublicLocalEndpoint(this.nativeId);
|
||||
return `${webhookUrl}motionDetected`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify and return available streams on the provided camera.
|
||||
*/
|
||||
@@ -207,11 +258,13 @@ class SynologySurveillanceStation extends ScryptedDeviceBase implements Settings
|
||||
manufacturer: camera.vendor,
|
||||
model: camera.model,
|
||||
firmware: camera.firmware,
|
||||
serialNumber: '' + camera.id
|
||||
serialNumber: `Camera-${camera.id}`,
|
||||
},
|
||||
interfaces: [
|
||||
ScryptedInterface.Settings,
|
||||
ScryptedInterface.Camera,
|
||||
ScryptedInterface.HttpRequestHandler,
|
||||
ScryptedInterface.MotionSensor,
|
||||
ScryptedInterface.Settings,
|
||||
ScryptedInterface.VideoCamera,
|
||||
],
|
||||
type: ScryptedDeviceType.Camera
|
||||
|
||||
Reference in New Issue
Block a user