mirror of
https://github.com/koush/scrypted.git
synced 2026-02-06 23:42:19 +00:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d83d3ba97 | ||
|
|
1078faef62 | ||
|
|
47a981e15a | ||
|
|
e253cab555 | ||
|
|
80124ca83b | ||
|
|
f883d8738c | ||
|
|
bdca3b545c | ||
|
|
3ba02c44ab | ||
|
|
fe4733bb97 | ||
|
|
7ff893fbd3 | ||
|
|
e79c544690 | ||
|
|
13bf44ce50 | ||
|
|
544531122d | ||
|
|
778f0b7ad1 | ||
|
|
35e8a86593 | ||
|
|
c370773af4 | ||
|
|
184f293b92 | ||
|
|
6e10172f7e | ||
|
|
c5ae2cd539 | ||
|
|
e40566e89c | ||
|
|
59ccd4e4d8 | ||
|
|
ae80eb7727 | ||
|
|
f054172dcf |
12
.github/workflows/docker-common.yml
vendored
12
.github/workflows/docker-common.yml
vendored
@@ -10,7 +10,10 @@ jobs:
|
||||
# runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
NODE_VERSION: ["18", "20"]
|
||||
NODE_VERSION: [
|
||||
"18",
|
||||
# "20"
|
||||
]
|
||||
BASE: ["jammy"]
|
||||
FLAVOR: ["full", "lite", "thin"]
|
||||
steps:
|
||||
@@ -26,12 +29,6 @@ jobs:
|
||||
host: ${{ secrets.DOCKER_SSH_HOST_ARM64 }}
|
||||
private-key: ${{ secrets.DOCKER_SSH_PRIVATE_KEY }}
|
||||
|
||||
- name: Set up SSH
|
||||
uses: MrSquaare/ssh-setup-action@v2
|
||||
with:
|
||||
host: ${{ secrets.DOCKER_SSH_HOST_ARM7 }}
|
||||
private-key: ${{ secrets.DOCKER_SSH_PRIVATE_KEY }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
with:
|
||||
@@ -65,5 +62,6 @@ jobs:
|
||||
push: true
|
||||
tags: |
|
||||
koush/scrypted-common:${{ matrix.NODE_VERSION }}-${{ matrix.BASE }}-${{ matrix.FLAVOR }}
|
||||
ghcr.io/koush/scrypted-common:${{ matrix.NODE_VERSION }}-${{ matrix.BASE }}-${{ matrix.FLAVOR }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
6
.github/workflows/docker.yml
vendored
6
.github/workflows/docker.yml
vendored
@@ -52,12 +52,6 @@ jobs:
|
||||
host: ${{ secrets.DOCKER_SSH_HOST_ARM64 }}
|
||||
private-key: ${{ secrets.DOCKER_SSH_PRIVATE_KEY }}
|
||||
|
||||
- name: Set up SSH
|
||||
uses: MrSquaare/ssh-setup-action@v2
|
||||
with:
|
||||
host: ${{ secrets.DOCKER_SSH_HOST_ARM7 }}
|
||||
private-key: ${{ secrets.DOCKER_SSH_PRIVATE_KEY }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
with:
|
||||
|
||||
@@ -58,18 +58,13 @@ export async function scryptedEval(device: ScryptedDeviceBase, script: string, e
|
||||
worker.worker.terminate();
|
||||
}
|
||||
|
||||
const smProxy = new SystemManagerImpl();
|
||||
smProxy.state = systemManager.getSystemState();
|
||||
const apiProxy = new PluginAPIProxy(sdk.pluginHostAPI);
|
||||
smProxy.api = apiProxy;
|
||||
|
||||
const allParams = Object.assign({}, params, {
|
||||
sdk,
|
||||
fs: require('realfs'),
|
||||
fetch,
|
||||
ScryptedDeviceBase,
|
||||
MixinDeviceBase,
|
||||
systemManager: smProxy,
|
||||
systemManager,
|
||||
deviceManager,
|
||||
endpointManager,
|
||||
mediaManager,
|
||||
@@ -104,7 +99,6 @@ export async function scryptedEval(device: ScryptedDeviceBase, script: string, e
|
||||
return {
|
||||
value,
|
||||
defaultExport,
|
||||
apiProxy,
|
||||
};
|
||||
}
|
||||
catch (e) {
|
||||
|
||||
2
external/axios-digest-auth
vendored
2
external/axios-digest-auth
vendored
Submodule external/axios-digest-auth updated: e1735135be...1180ec6d53
@@ -1,6 +1,6 @@
|
||||
# Home Assistant Addon Configuration
|
||||
name: Scrypted
|
||||
version: "18-jammy-full.s6-v0.72.0"
|
||||
version: "18-jammy-full.s6-v0.79.0"
|
||||
slug: scrypted
|
||||
description: Scrypted is a high performance home video integration and automation platform
|
||||
url: "https://github.com/koush/scrypted"
|
||||
@@ -29,9 +29,9 @@ environment:
|
||||
SCRYPTED_ADMIN_USERNAME: "homeassistant"
|
||||
SCRYPTED_INSTALL_ENVIRONMENT: "ha"
|
||||
backup_exclude:
|
||||
- '/server/**'
|
||||
- '/data/scrypted_nvr/**'
|
||||
- '/data/scrypted_data/plugins/**'
|
||||
- '*/server/**'
|
||||
- '*/scrypted_nvr/**'
|
||||
- '*/scrypted_data/plugins/**'
|
||||
map:
|
||||
- config:rw
|
||||
- media:rw
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
ARG BASE="18-jammy-full"
|
||||
FROM koush/scrypted-common:${BASE}
|
||||
FROM ghcr.io/koush/scrypted-common:${BASE}
|
||||
|
||||
WORKDIR /
|
||||
# cache bust
|
||||
@@ -14,4 +14,8 @@ WORKDIR /server
|
||||
# https://github.com/nodejs/node/issues/41145#issuecomment-992948130
|
||||
ENV NODE_OPTIONS="--dns-result-order=ipv4first"
|
||||
|
||||
# changing this forces pip and npm to perform reinstalls.
|
||||
# if this base image changes, this version must be updated.
|
||||
ENV SCRYPTED_BASE_VERSION="20240103"
|
||||
|
||||
CMD npm --prefix /server exec scrypted-serve
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
ARG BASE="16-jammy"
|
||||
FROM koush/scrypted-common:${BASE}
|
||||
FROM ghcr.io/koush/scrypted-common:${BASE}
|
||||
|
||||
WORKDIR /
|
||||
RUN git clone --depth=1 https://github.com/koush/scrypted
|
||||
|
||||
@@ -109,7 +109,6 @@ ENV SCRYPTED_FFMPEG_PATH="/usr/bin/ffmpeg"
|
||||
|
||||
# changing this forces pip and npm to perform reinstalls.
|
||||
# if this base image changes, this version must be updated.
|
||||
ENV SCRYPTED_BASE_VERSION="20230727"
|
||||
ENV SCRYPTED_DOCKER_FLAVOR="full"
|
||||
|
||||
################################################################
|
||||
|
||||
@@ -44,7 +44,4 @@ ENV SCRYPTED_INSTALL_PATH="/server"
|
||||
RUN test -f "/usr/bin/ffmpeg"
|
||||
ENV SCRYPTED_FFMPEG_PATH="/usr/bin/ffmpeg"
|
||||
|
||||
# changing this forces pip and npm to perform reinstalls.
|
||||
# if this base image changes, this version must be updated.
|
||||
ENV SCRYPTED_BASE_VERSION="20230727"
|
||||
ENV SCRYPTED_DOCKER_FLAVOR="lite"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM koush/scrypted-common
|
||||
FROM ghcr.io/koush/scrypted-common
|
||||
|
||||
WORKDIR /
|
||||
COPY . .
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM koush/18-jammy-full.s6
|
||||
FROM ghcr.io/koush/18-jammy-full.s6
|
||||
|
||||
WORKDIR /
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
ARG BASE="18-jammy-full"
|
||||
FROM koush/scrypted-common:${BASE}
|
||||
FROM ghcr.io/koush/scrypted-common:${BASE}
|
||||
|
||||
# avahi advertiser support
|
||||
RUN apt-get update && apt-get -y install \
|
||||
@@ -44,4 +44,8 @@ WORKDIR /server
|
||||
# https://github.com/nodejs/node/issues/41145#issuecomment-992948130
|
||||
ENV NODE_OPTIONS="--dns-result-order=ipv4first"
|
||||
|
||||
# changing this forces pip and npm to perform reinstalls.
|
||||
# if this base image changes, this version must be updated.
|
||||
ENV SCRYPTED_BASE_VERSION="20240103"
|
||||
|
||||
CMD npm --prefix /server exec scrypted-serve
|
||||
|
||||
@@ -19,7 +19,4 @@ ENV SCRYPTED_INSTALL_PATH="/server"
|
||||
RUN test -f "/usr/bin/ffmpeg"
|
||||
ENV SCRYPTED_FFMPEG_PATH="/usr/bin/ffmpeg"
|
||||
|
||||
# changing this forces pip and npm to perform reinstalls.
|
||||
# if this base image changes, this version must be updated.
|
||||
ENV SCRYPTED_BASE_VERSION="20230727"
|
||||
ENV SCRYPTED_DOCKER_FLAVOR="thin"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
./template/generate-dockerfile.sh
|
||||
|
||||
docker build -t koush/scrypted-common -f Dockerfile.full . && \
|
||||
docker build -t koush/scrypted -f Dockerfile.local .
|
||||
docker build -t ghcr.io/koush/scrypted-common -f Dockerfile.full . && \
|
||||
docker build -t ghcr.io/koush/scrypted -f Dockerfile.local .
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
./docker-build.sh
|
||||
|
||||
docker build -t koush/scrypted:18-jammy-full.nvidia -f Dockerfile.nvidia
|
||||
docker build -t ghcr.io/koush/scrypted:18-jammy-full.nvidia -f Dockerfile.nvidia
|
||||
|
||||
@@ -11,8 +11,8 @@ echo $BASE
|
||||
SUPERVISOR=.s6
|
||||
SUPERVISOR_BASE=$BASE$SUPERVISOR
|
||||
|
||||
docker build -t koush/scrypted-common:$BASE -f Dockerfile.$FLAVOR \
|
||||
docker build -t ghcr.io/koush/scrypted-common:$BASE -f Dockerfile.$FLAVOR \
|
||||
--build-arg NODE_VERSION=$NODE_VERSION --build-arg BASE=$IMAGE_BASE . && \
|
||||
\
|
||||
docker build -t koush/scrypted:$SUPERVISOR_BASE -f Dockerfile$SUPERVISOR \
|
||||
docker build -t ghcr.io/koush/scrypted:$SUPERVISOR_BASE -f Dockerfile$SUPERVISOR \
|
||||
--build-arg BASE=$BASE --build-arg SCRYPTED_INSTALL_VERSION=$SCRYPTED_INSTALL_VERSION .
|
||||
|
||||
@@ -90,7 +90,7 @@ services:
|
||||
container_name: scrypted
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
image: koush/scrypted
|
||||
image: ghcr.io/koush/scrypted
|
||||
|
||||
# logging is noisy and will unnecessarily wear on flash storage.
|
||||
# scrypted has per device in memory logging that is preferred.
|
||||
|
||||
@@ -35,9 +35,6 @@ ENV SCRYPTED_INSTALL_PATH="/server"
|
||||
RUN test -f "/usr/bin/ffmpeg"
|
||||
ENV SCRYPTED_FFMPEG_PATH="/usr/bin/ffmpeg"
|
||||
|
||||
# changing this forces pip and npm to perform reinstalls.
|
||||
# if this base image changes, this version must be updated.
|
||||
ENV SCRYPTED_BASE_VERSION="20230727"
|
||||
ENV SCRYPTED_DOCKER_FLAVOR="full"
|
||||
|
||||
################################################################
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
cd /tmp
|
||||
curl -O -L https://github.com/koush/scrypted/releases/download/v0.72.0/scrypted.tar.zst
|
||||
pct restore 10443 scrypted.tar.zst
|
||||
|
||||
function readyn() {
|
||||
while true; do
|
||||
read -p "$1 (y/n) " yn
|
||||
@@ -13,6 +9,48 @@ function readyn() {
|
||||
done
|
||||
}
|
||||
|
||||
cd /tmp
|
||||
SCRYPTED_VERSION=v0.79.0
|
||||
SCRYPTED_TAR_ZST=scrypted-$SCRYPTED_VERSION.tar.zst
|
||||
if [ -z "$VMID" ]
|
||||
then
|
||||
VMID=10443
|
||||
fi
|
||||
|
||||
echo "Downloading scrypted container backup."
|
||||
if [ ! -f "$SCRYPTED_TAR_ZST" ]
|
||||
then
|
||||
curl -O -L https://github.com/koush/scrypted/releases/download/$SCRYPTED_VERSION/scrypted.tar.zst
|
||||
mv scrypted.tar.zst $SCRYPTED_TAR_ZST
|
||||
fi
|
||||
|
||||
echo "Checking for existing container."
|
||||
pct config $VMID
|
||||
if [ "$?" == "0" ]
|
||||
then
|
||||
echo ""
|
||||
echo "Existing container $VMID found. Run this script with --force to overwrite the existing container."
|
||||
echo "This will wipe all existing data. Clone the existing container to retain the data, then reassign the owner of the scrypted volume after installation is complete."
|
||||
echo ""
|
||||
echo "bash $0 --force"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
pct restore $VMID $SCRYPTED_TAR_ZST $@
|
||||
|
||||
if [ "$?" != "0" ]
|
||||
then
|
||||
echo ""
|
||||
echo "pct restore failed"
|
||||
echo ""
|
||||
echo "This may be caused by the server's 'local' storage not supporting containers."
|
||||
echo "Try running this script again with a different storage device (local-lvm, local-zfs). For example:"
|
||||
echo ""
|
||||
echo "bash $0 --storage local-lvm"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Adding udev rule: /etc/udev/rules.d/65-scrypted.rules"
|
||||
readyn "Add udev rule for hardware acceleration? This may conflict with existing rules."
|
||||
if [ "$yn" == "y" ]
|
||||
@@ -23,4 +61,6 @@ then
|
||||
udevadm control --reload-rules && udevadm trigger
|
||||
fi
|
||||
|
||||
echo "Scrypted setup is complete and the container can be started."
|
||||
echo "Scrypted setup is complete and the container resources can be started."
|
||||
echo "Scrypted NVR users should provide at least 4 cores and 16GB RAM prior to starting."
|
||||
|
||||
|
||||
14
plugins/amcrest/package-lock.json
generated
14
plugins/amcrest/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@scrypted/amcrest",
|
||||
"version": "0.0.130",
|
||||
"version": "0.0.131",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/amcrest",
|
||||
"version": "0.0.130",
|
||||
"version": "0.0.131",
|
||||
"license": "Apache",
|
||||
"dependencies": {
|
||||
"@koush/axios-digest-auth": "^0.8.5",
|
||||
"@koush/axios-digest-auth": "^0.8.7",
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/multiparty": "^0.0.33",
|
||||
@@ -36,7 +36,7 @@
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.4",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
@@ -72,9 +72,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@koush/axios-digest-auth": {
|
||||
"version": "0.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.6.tgz",
|
||||
"integrity": "sha512-e/XKs7/BYpPQkces0Cm4dUmhT9hR0rjvnNZAVRyRnNWdQ8cyCMFWS9HIrMWOdzAocKDNBXi1vKjJ8CywrW5xgQ==",
|
||||
"version": "0.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.7.tgz",
|
||||
"integrity": "sha512-sZepmWhDt4JUMB1ycX8k9SmDfHeCX+g+pGslrpLORHhEo2vLYFzTjAzL62NFmZO9uG4xmedDn4i0eJW5IK3//Q==",
|
||||
"dependencies": {
|
||||
"auth-header": "^1.0.0",
|
||||
"axios": "^0.21.4"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/amcrest",
|
||||
"version": "0.0.130",
|
||||
"version": "0.0.131",
|
||||
"description": "Amcrest Plugin for Scrypted",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache",
|
||||
@@ -35,7 +35,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@koush/axios-digest-auth": "^0.8.5",
|
||||
"@koush/axios-digest-auth": "^0.8.7",
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/multiparty": "^0.0.33",
|
||||
|
||||
2
plugins/core/.vscode/settings.json
vendored
2
plugins/core/.vscode/settings.json
vendored
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"scrypted.debugHost": "scrypted-server",
|
||||
"scrypted.debugHost": "127.0.0.1",
|
||||
}
|
||||
4
plugins/core/package-lock.json
generated
4
plugins/core/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/core",
|
||||
"version": "0.2.2",
|
||||
"version": "0.2.3",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/core",
|
||||
"version": "0.2.2",
|
||||
"version": "0.2.3",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/core",
|
||||
"version": "0.2.2",
|
||||
"version": "0.2.3",
|
||||
"description": "Scrypted Core plugin. Provides the UI, websocket, and engine.io APIs.",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Device, DeviceCreator, DeviceCreatorSettings, DeviceProvider, Readme, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedNativeId, Setting } from "@scrypted/sdk";
|
||||
import { Script } from "./script";
|
||||
import sdk from '@scrypted/sdk';
|
||||
import sdk, { Device, DeviceCreator, DeviceCreatorSettings, DeviceProvider, Readme, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedNativeId, Setting } from '@scrypted/sdk';
|
||||
import { randomBytes } from "crypto";
|
||||
import fs from 'fs';
|
||||
import path from "path/posix";
|
||||
import { Worker } from "worker_threads";
|
||||
import { Script } from "./script";
|
||||
|
||||
const { deviceManager } = sdk;
|
||||
export const ScriptCoreNativeId = 'scriptcore';
|
||||
@@ -42,6 +41,10 @@ export class ScriptCore extends ScryptedDeviceBase implements DeviceProvider, De
|
||||
const nativeId = 'script:' + randomBytes(8).toString('hex');
|
||||
await this.reportScript(nativeId, name?.toString());
|
||||
const script = new Script(nativeId);
|
||||
this.scripts.set(nativeId, {
|
||||
script,
|
||||
worker: undefined,
|
||||
});
|
||||
if (template) {
|
||||
try {
|
||||
await script.saveScript({
|
||||
@@ -76,20 +79,39 @@ export class ScriptCore extends ScryptedDeviceBase implements DeviceProvider, De
|
||||
|
||||
async getDevice(nativeId: string) {
|
||||
const e = this.scripts.get(nativeId);
|
||||
if (e)
|
||||
return e;
|
||||
if (e) {
|
||||
if (e.script)
|
||||
return e.script;
|
||||
e.worker?.terminate();
|
||||
this.scripts.delete(nativeId);
|
||||
}
|
||||
|
||||
let script = new Script(nativeId);
|
||||
let worker: Worker;
|
||||
|
||||
const triggerDeviceDiscover = async (name: string, type: ScryptedDeviceType, interfaces: string[]) => {
|
||||
const e = this.scripts.get(nativeId);
|
||||
if (e?.script == script)
|
||||
e.script = undefined;
|
||||
|
||||
const device: Device = {
|
||||
providerNativeId: this.nativeId,
|
||||
name,
|
||||
nativeId,
|
||||
type,
|
||||
interfaces,
|
||||
refresh: true,
|
||||
};
|
||||
return await deviceManager.onDeviceDiscovered(device);
|
||||
};
|
||||
|
||||
if (script.providedInterfaces.length > 2) {
|
||||
const fork = sdk.fork<{
|
||||
newScript: typeof newScript,
|
||||
}>();
|
||||
worker = fork.worker;
|
||||
try {
|
||||
script = await (await fork.result).newScript(nativeId);
|
||||
await script.run();
|
||||
script = await (await fork.result).newScript(nativeId, triggerDeviceDiscover);
|
||||
}
|
||||
catch (e) {
|
||||
worker.terminate();
|
||||
@@ -98,8 +120,14 @@ export class ScriptCore extends ScryptedDeviceBase implements DeviceProvider, De
|
||||
}
|
||||
|
||||
worker?.on('exit', () => {
|
||||
if (this.scripts.get(nativeId)?.worker === worker)
|
||||
if (this.scripts.get(nativeId)?.worker === worker) {
|
||||
this.scripts.delete(nativeId);
|
||||
// notify the system that the device needs to be refreshed.
|
||||
if (deviceManager.getNativeIds().includes(nativeId)) {
|
||||
const script = new Script(nativeId);
|
||||
triggerDeviceDiscover(script.providedName, script.providedType, script.providedInterfaces);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.scripts.set(nativeId, {
|
||||
@@ -110,10 +138,14 @@ export class ScriptCore extends ScryptedDeviceBase implements DeviceProvider, De
|
||||
}
|
||||
|
||||
async releaseDevice(id: string, nativeId: string): Promise<void> {
|
||||
this.scripts.get(nativeId)?.worker?.terminate();
|
||||
const worker = this.scripts.get(nativeId)?.worker;
|
||||
this.scripts.delete(nativeId);
|
||||
worker?.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
export async function newScript(nativeId: ScryptedNativeId) {
|
||||
return new Script(nativeId);
|
||||
export async function newScript(nativeId: ScryptedNativeId, triggerDeviceDiscover: (name: string, type: ScryptedDeviceType, interfaces: string[]) => Promise<string>) {
|
||||
const script = new Script(nativeId, triggerDeviceDiscover);
|
||||
await script.run();
|
||||
return script;
|
||||
}
|
||||
|
||||
@@ -8,9 +8,7 @@ import { PluginAPIProxy } from "../../../server/src/plugin/plugin-api";
|
||||
const { deviceManager } = sdk;
|
||||
|
||||
export class Script extends ScryptedDeviceBase implements Scriptable, Program, ScriptDeviceImpl {
|
||||
apiProxy: PluginAPIProxy;
|
||||
|
||||
constructor(nativeId: string) {
|
||||
constructor(nativeId: string, public triggerDeviceDiscover?: (name: string, type: ScryptedDeviceType, interfaces: string[]) => Promise<string>) {
|
||||
super(nativeId);
|
||||
}
|
||||
|
||||
@@ -18,6 +16,8 @@ export class Script extends ScryptedDeviceBase implements Scriptable, Program, S
|
||||
this.storage.setItem('data', JSON.stringify({
|
||||
'script.ts': source.script,
|
||||
}));
|
||||
|
||||
this.triggerDeviceDiscover?.(this.providedName, this.providedType, this.providedInterfaces);
|
||||
}
|
||||
|
||||
async loadScripts(): Promise<{ [filename: string]: ScriptSource; }> {
|
||||
@@ -70,46 +70,38 @@ export class Script extends ScryptedDeviceBase implements Scriptable, Program, S
|
||||
}
|
||||
|
||||
prepareScript() {
|
||||
this.apiProxy?.removeListeners();
|
||||
|
||||
Object.assign(this, createScriptDevice([
|
||||
ScryptedInterface.Scriptable,
|
||||
ScryptedInterface.Program,
|
||||
]));
|
||||
}
|
||||
|
||||
async run(variables?: { [name: string]: any; }): Promise<any> {
|
||||
async runInternal(script: string, variables?: { [name: string]: any; }): Promise<any> {
|
||||
this.prepareScript();
|
||||
|
||||
try {
|
||||
const data = JSON.parse(this.storage.getItem('data'));
|
||||
|
||||
const { value, defaultExport, apiProxy } = await scryptedEval(this, data['script.ts'], Object.assign({
|
||||
const { value, defaultExport } = await scryptedEval(this, script, Object.assign({
|
||||
device: this,
|
||||
}, variables));
|
||||
|
||||
this.apiProxy = apiProxy;
|
||||
|
||||
await this.postRunScript(defaultExport);
|
||||
return value;
|
||||
}
|
||||
catch (e) {
|
||||
this.console.error('error loading script', e);
|
||||
this.console.error('error evaluating script', e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
async run(variables?: { [name: string]: any; }): Promise<any> {
|
||||
const data = JSON.parse(this.storage.getItem('data'));
|
||||
return this.runInternal(data['script.ts'], variables)
|
||||
}
|
||||
|
||||
async eval(source: ScriptSource, variables?: { [name: string]: any }) {
|
||||
this.prepareScript();
|
||||
|
||||
const { value, defaultExport, apiProxy } = await scryptedEval(this, source.script, Object.assign({
|
||||
device: this,
|
||||
}, variables));
|
||||
|
||||
this.apiProxy = apiProxy;
|
||||
|
||||
await this.postRunScript(defaultExport);
|
||||
return value;
|
||||
return this.runInternal(source.script, variables);
|
||||
}
|
||||
|
||||
// will be done at runtime
|
||||
|
||||
20
plugins/hikvision/package-lock.json
generated
20
plugins/hikvision/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@scrypted/hikvision",
|
||||
"version": "0.0.132",
|
||||
"version": "0.0.133",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/hikvision",
|
||||
"version": "0.0.132",
|
||||
"version": "0.0.133",
|
||||
"license": "Apache",
|
||||
"dependencies": {
|
||||
"@koush/axios-digest-auth": "^0.8.5",
|
||||
"@koush/axios-digest-auth": "^0.8.7",
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/xml2js": "^0.4.11",
|
||||
@@ -38,7 +38,7 @@
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.4",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
@@ -77,9 +77,9 @@
|
||||
"extraneous": true
|
||||
},
|
||||
"node_modules/@koush/axios-digest-auth": {
|
||||
"version": "0.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.6.tgz",
|
||||
"integrity": "sha512-e/XKs7/BYpPQkces0Cm4dUmhT9hR0rjvnNZAVRyRnNWdQ8cyCMFWS9HIrMWOdzAocKDNBXi1vKjJ8CywrW5xgQ==",
|
||||
"version": "0.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.7.tgz",
|
||||
"integrity": "sha512-sZepmWhDt4JUMB1ycX8k9SmDfHeCX+g+pGslrpLORHhEo2vLYFzTjAzL62NFmZO9uG4xmedDn4i0eJW5IK3//Q==",
|
||||
"dependencies": {
|
||||
"auth-header": "^1.0.0",
|
||||
"axios": "^0.21.4"
|
||||
@@ -242,9 +242,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@koush/axios-digest-auth": {
|
||||
"version": "0.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.6.tgz",
|
||||
"integrity": "sha512-e/XKs7/BYpPQkces0Cm4dUmhT9hR0rjvnNZAVRyRnNWdQ8cyCMFWS9HIrMWOdzAocKDNBXi1vKjJ8CywrW5xgQ==",
|
||||
"version": "0.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.7.tgz",
|
||||
"integrity": "sha512-sZepmWhDt4JUMB1ycX8k9SmDfHeCX+g+pGslrpLORHhEo2vLYFzTjAzL62NFmZO9uG4xmedDn4i0eJW5IK3//Q==",
|
||||
"requires": {
|
||||
"auth-header": "^1.0.0",
|
||||
"axios": "^0.21.4"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/hikvision",
|
||||
"version": "0.0.132",
|
||||
"version": "0.0.133",
|
||||
"description": "Hikvision Plugin for Scrypted",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache",
|
||||
@@ -35,7 +35,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@koush/axios-digest-auth": "^0.8.5",
|
||||
"@koush/axios-digest-auth": "^0.8.7",
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/xml2js": "^0.4.11",
|
||||
|
||||
69
plugins/onvif/package-lock.json
generated
69
plugins/onvif/package-lock.json
generated
@@ -1,26 +1,26 @@
|
||||
{
|
||||
"name": "@scrypted/onvif",
|
||||
"version": "0.0.127",
|
||||
"version": "0.0.128",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/onvif",
|
||||
"version": "0.0.127",
|
||||
"version": "0.0.128",
|
||||
"license": "Apache",
|
||||
"dependencies": {
|
||||
"@koush/axios-digest-auth": "^0.8.5",
|
||||
"@koush/axios-digest-auth": "^0.8.7",
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"base-64": "^1.0.0",
|
||||
"http-auth-utils": "^3.0.5",
|
||||
"http-auth-utils": "^4.0.0",
|
||||
"md5": "^2.3.0",
|
||||
"onvif": "^0.6.8",
|
||||
"xml2js": "^0.4.23"
|
||||
"xml2js": "^0.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/md5": "^2.3.2",
|
||||
"@types/node": "^18.16.18",
|
||||
"@types/node": "^20.3.2",
|
||||
"@types/xml2js": "^0.4.11"
|
||||
}
|
||||
},
|
||||
@@ -41,7 +41,7 @@
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.2.103",
|
||||
"version": "0.3.4",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
@@ -77,9 +77,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@koush/axios-digest-auth": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.5.tgz",
|
||||
"integrity": "sha512-EZMM0gMJ3hMUD4EuUqSwP6UGt5Vmw2TZtY7Ypec55AnxkExSXM0ySgPtqkAcnL43g1R27yAg/dQL7dRTLMqO3Q==",
|
||||
"version": "0.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.7.tgz",
|
||||
"integrity": "sha512-sZepmWhDt4JUMB1ycX8k9SmDfHeCX+g+pGslrpLORHhEo2vLYFzTjAzL62NFmZO9uG4xmedDn4i0eJW5IK3//Q==",
|
||||
"dependencies": {
|
||||
"auth-header": "^1.0.0",
|
||||
"axios": "^0.21.4"
|
||||
@@ -100,10 +100,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.16.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.18.tgz",
|
||||
"integrity": "sha512-/aNaQZD0+iSBAGnvvN2Cx92HqE5sZCPZtx2TsK+4nvV23fFe09jVDvpArXr2j9DnYlzuU9WuoykDDc6wqvpNcw==",
|
||||
"dev": true
|
||||
"version": "20.10.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz",
|
||||
"integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/xml2js": {
|
||||
"version": "0.4.11",
|
||||
@@ -168,9 +171,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/http-auth-utils": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/http-auth-utils/-/http-auth-utils-3.0.5.tgz",
|
||||
"integrity": "sha512-A592YHM51dmcru5vePB1yo8zjr0iHJrSo67x8bdjXrazP1Zzvx6zu/Sece+g2gxgkHJsRnmbi1xShKQkIie+YA==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-auth-utils/-/http-auth-utils-4.0.0.tgz",
|
||||
"integrity": "sha512-jdX1sda7HuAOmCqHJ4FoYFEO6P3x9PQosEyZMqpi3EUsB/HxnoqauRThLelBTeOs+osAu8Y3VTdo4G4fdXk2Ig==",
|
||||
"dependencies": {
|
||||
"yerror": "^6.2.1"
|
||||
},
|
||||
@@ -199,26 +202,44 @@
|
||||
}
|
||||
},
|
||||
"node_modules/onvif": {
|
||||
"version": "0.6.8",
|
||||
"resolved": "https://registry.npmjs.org/onvif/-/onvif-0.6.8.tgz",
|
||||
"integrity": "sha512-GkrBlgusJCAGRBxfLBmykJpfKbPY16mChERORqt5J7aFt7y48KyqoynS+w7D3nZcjWPKR7WyHiJV9XN4e+Foiw==",
|
||||
"version": "0.6.9",
|
||||
"resolved": "https://registry.npmjs.org/onvif/-/onvif-0.6.9.tgz",
|
||||
"integrity": "sha512-aKr14CG8dkHMEF3bUqBZA1OdZi4ffzfmR5E1Y3v4WpweCGkywERAQDhQM3PRUvLNtqnWbcDEcq4l7gBSZ7JCyA==",
|
||||
"dependencies": {
|
||||
"lodash.get": "^4.4.2",
|
||||
"xml2js": "^0.4.23"
|
||||
"xml2js": "^0.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/onvif/node_modules/xml2js": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
|
||||
"integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
|
||||
"dependencies": {
|
||||
"sax": ">=0.6.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/xml2js": {
|
||||
"version": "0.4.23",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
|
||||
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
|
||||
"integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
|
||||
"dependencies": {
|
||||
"sax": ">=0.6.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/onvif",
|
||||
"version": "0.0.127",
|
||||
"version": "0.0.128",
|
||||
"description": "ONVIF Camera Plugin for Scrypted",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache",
|
||||
@@ -36,7 +36,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@koush/axios-digest-auth": "^0.8.5",
|
||||
"@koush/axios-digest-auth": "^0.8.7",
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"base-64": "^1.0.0",
|
||||
|
||||
@@ -43,6 +43,9 @@ export async function listenEvents(thisDevice: ScryptedDeviceBase, client: Onvif
|
||||
// thisDevice.motionDetected = true;
|
||||
}
|
||||
else if (event === OnvifEvent.MotionStop) {
|
||||
// reset the trigger to debounce per above.
|
||||
triggerMotion();
|
||||
|
||||
// thisDevice.motionDetected = false;
|
||||
}
|
||||
else if (event === OnvifEvent.AudioStart)
|
||||
|
||||
8
plugins/opencv/.vscode/settings.json
vendored
8
plugins/opencv/.vscode/settings.json
vendored
@@ -5,12 +5,12 @@
|
||||
// "scrypted.serverRoot": "/home/pi/.scrypted",
|
||||
|
||||
// docker installation
|
||||
"scrypted.debugHost": "koushik-ubuntu",
|
||||
"scrypted.serverRoot": "/server",
|
||||
// "scrypted.debugHost": "koushik-ubuntu",
|
||||
// "scrypted.serverRoot": "/server",
|
||||
|
||||
// local checkout
|
||||
// "scrypted.debugHost": "127.0.0.1",
|
||||
// "scrypted.serverRoot": "/Users/koush/.scrypted",
|
||||
"scrypted.debugHost": "127.0.0.1",
|
||||
"scrypted.serverRoot": "/Users/koush/.scrypted",
|
||||
// "scrypted.debugHost": "koushik-windows",
|
||||
// "scrypted.serverRoot": "C:\\Users\\koush\\.scrypted",
|
||||
|
||||
|
||||
4
plugins/opencv/package-lock.json
generated
4
plugins/opencv/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/opencv",
|
||||
"version": "0.0.89",
|
||||
"version": "0.0.90",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/opencv",
|
||||
"version": "0.0.89",
|
||||
"version": "0.0.90",
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
}
|
||||
|
||||
@@ -37,5 +37,5 @@
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
},
|
||||
"version": "0.0.89"
|
||||
"version": "0.0.90"
|
||||
}
|
||||
|
||||
@@ -6,4 +6,4 @@ pillow-simd; sys_platform == 'linux' and platform_machine == 'x86_64'
|
||||
imutils>=0.5.0
|
||||
# opencv-python is not available on armhf
|
||||
# locked to version because 4.8.0.76 is broken.
|
||||
opencv-python==4.8.0.74; sys_platform != 'linux' or platform_machine == 'x86_64'
|
||||
opencv-python==4.8.0.74; sys_platform != 'linux' or platform_machine == 'x86_64' or platform_machine == 'aarch64'
|
||||
|
||||
14
plugins/reolink/package-lock.json
generated
14
plugins/reolink/package-lock.json
generated
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "@scrypted/reolink",
|
||||
"version": "0.0.52",
|
||||
"version": "0.0.54",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/reolink",
|
||||
"version": "0.0.52",
|
||||
"version": "0.0.54",
|
||||
"license": "Apache",
|
||||
"dependencies": {
|
||||
"@koush/axios-digest-auth": "^0.8.5",
|
||||
"@koush/axios-digest-auth": "^0.8.7",
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/multiparty": "^0.0.33",
|
||||
@@ -37,7 +37,7 @@
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.4",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
@@ -73,9 +73,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@koush/axios-digest-auth": {
|
||||
"version": "0.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.6.tgz",
|
||||
"integrity": "sha512-e/XKs7/BYpPQkces0Cm4dUmhT9hR0rjvnNZAVRyRnNWdQ8cyCMFWS9HIrMWOdzAocKDNBXi1vKjJ8CywrW5xgQ==",
|
||||
"version": "0.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.7.tgz",
|
||||
"integrity": "sha512-sZepmWhDt4JUMB1ycX8k9SmDfHeCX+g+pGslrpLORHhEo2vLYFzTjAzL62NFmZO9uG4xmedDn4i0eJW5IK3//Q==",
|
||||
"dependencies": {
|
||||
"auth-header": "^1.0.0",
|
||||
"axios": "^0.21.4"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/reolink",
|
||||
"version": "0.0.52",
|
||||
"version": "0.0.54",
|
||||
"description": "Reolink Plugin for Scrypted",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache",
|
||||
@@ -35,7 +35,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@koush/axios-digest-auth": "^0.8.5",
|
||||
"@koush/axios-digest-auth": "^0.8.7",
|
||||
"@scrypted/common": "file:../../common",
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/multiparty": "^0.0.33",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { sleep } from '@scrypted/common/src/sleep';
|
||||
import sdk, { Camera, DeviceCreatorSettings, DeviceInformation, Intercom, MediaObject, ObjectDetectionTypes, ObjectDetector, ObjectsDetected, PictureOptions, Reboot, ScryptedDeviceType, ScryptedInterface, Setting } from "@scrypted/sdk";
|
||||
import sdk, { Camera, DeviceCreatorSettings, DeviceInformation, Intercom, MediaObject, ObjectDetectionTypes, ObjectDetector, ObjectsDetected, PanTiltZoom, PanTiltZoomCommand, PictureOptions, Reboot, ScryptedDeviceType, ScryptedInterface, Setting } from "@scrypted/sdk";
|
||||
import { StorageSettings } from '@scrypted/sdk/storage-settings';
|
||||
import { EventEmitter } from "stream";
|
||||
import { Destroyable, RtspProvider, RtspSmartCamera, UrlMediaStreamOptions } from "../../rtsp/src/rtsp";
|
||||
@@ -8,7 +8,7 @@ import { listenEvents } from './onvif-events';
|
||||
import { OnvifIntercom } from './onvif-intercom';
|
||||
import { AIState, DevInfo, Enc, ReolinkCameraClient } from './reolink-api';
|
||||
|
||||
class ReolinkCamera extends RtspSmartCamera implements Camera, Reboot, Intercom, ObjectDetector {
|
||||
class ReolinkCamera extends RtspSmartCamera implements Camera, Reboot, Intercom, ObjectDetector, PanTiltZoom {
|
||||
client: ReolinkCameraClient;
|
||||
onvifClient: OnvifCameraAPI;
|
||||
onvifIntercom = new OnvifIntercom(this);
|
||||
@@ -36,6 +36,19 @@ class ReolinkCamera extends RtspSmartCamera implements Camera, Reboot, Intercom,
|
||||
hasObjectDetector: {
|
||||
json: true,
|
||||
hide: true,
|
||||
},
|
||||
ptz: {
|
||||
title: 'PTZ Capabilities',
|
||||
choices: [
|
||||
'Pan',
|
||||
'Tilt',
|
||||
'Zoom',
|
||||
],
|
||||
multiple: true,
|
||||
onPut: async () => {
|
||||
await this.updateDevice();
|
||||
this.updatePtzCaps();
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -44,12 +57,28 @@ class ReolinkCamera extends RtspSmartCamera implements Camera, Reboot, Intercom,
|
||||
|
||||
this.updateDeviceInfo();
|
||||
this.updateDevice();
|
||||
|
||||
this.updatePtzCaps();
|
||||
}
|
||||
|
||||
updatePtzCaps() {
|
||||
const { ptz } = this.storageSettings.values;
|
||||
this.ptzCapabilities = {
|
||||
pan: ptz?.includes('Pan'),
|
||||
tilt: ptz?.includes('Tilt'),
|
||||
zoom: ptz?.includes('Zoom'),
|
||||
}
|
||||
}
|
||||
|
||||
async getDetectionInput(detectionId: string, eventId?: any): Promise<MediaObject> {
|
||||
return;
|
||||
}
|
||||
|
||||
async ptzCommand(command: PanTiltZoomCommand): Promise<void> {
|
||||
const client = this.getClient();
|
||||
client.ptz(command);
|
||||
}
|
||||
|
||||
async getObjectTypes(): Promise<ObjectDetectionTypes> {
|
||||
try {
|
||||
const ai: AIState = this.storageSettings.values.hasObjectDetector[0]?.value;
|
||||
@@ -86,7 +115,7 @@ class ReolinkCamera extends RtspSmartCamera implements Camera, Reboot, Intercom,
|
||||
return this.onvifIntercom.stopIntercom();
|
||||
}
|
||||
|
||||
updateDevice() {
|
||||
async updateDevice() {
|
||||
const interfaces = this.provider.getInterfaces();
|
||||
let type = ScryptedDeviceType.Camera;
|
||||
let name = 'Reolink Camera';
|
||||
@@ -98,10 +127,13 @@ class ReolinkCamera extends RtspSmartCamera implements Camera, Reboot, Intercom,
|
||||
type = ScryptedDeviceType.Doorbell;
|
||||
name = 'Reolink Doorbell';
|
||||
}
|
||||
if (this.storageSettings.values.ptz?.length) {
|
||||
interfaces.push(ScryptedInterface.PanTiltZoom);
|
||||
}
|
||||
if (this.storageSettings.values.hasObjectDetector) {
|
||||
interfaces.push(ScryptedInterface.ObjectDetector);
|
||||
}
|
||||
this.provider.updateDevice(this.nativeId, name, interfaces, type);
|
||||
await this.provider.updateDevice(this.nativeId, name, interfaces, type);
|
||||
}
|
||||
|
||||
async reboot() {
|
||||
@@ -393,7 +425,12 @@ class ReolinkCamera extends RtspSmartCamera implements Camera, Reboot, Intercom,
|
||||
|
||||
async putSetting(key: string, value: string) {
|
||||
this.client = undefined;
|
||||
super.putSetting(key, value);
|
||||
if (this.storageSettings.keys[key]) {
|
||||
await this.storageSettings.putSetting(key, value);
|
||||
}
|
||||
else {
|
||||
await super.putSetting(key, value);
|
||||
}
|
||||
this.updateDevice();
|
||||
this.updateDeviceInfo();
|
||||
}
|
||||
|
||||
@@ -1,44 +1,46 @@
|
||||
import AxiosDigestAuth from "@koush/axios-digest-auth";
|
||||
import { getMotionState, reolinkHttpsAgent } from './probe';
|
||||
import { PanTiltZoomCommand } from "@scrypted/sdk";
|
||||
import { sleep } from "@scrypted/common/src/sleep";
|
||||
|
||||
export interface Enc {
|
||||
audio: number;
|
||||
channel: number;
|
||||
audio: number;
|
||||
channel: number;
|
||||
mainStream: Stream;
|
||||
subStream: Stream;
|
||||
subStream: Stream;
|
||||
}
|
||||
|
||||
export interface Stream {
|
||||
bitRate: number;
|
||||
bitRate: number;
|
||||
frameRate: number;
|
||||
gop: number;
|
||||
height: number;
|
||||
profile: string;
|
||||
size: string;
|
||||
vType: string;
|
||||
width: number;
|
||||
gop: number;
|
||||
height: number;
|
||||
profile: string;
|
||||
size: string;
|
||||
vType: string;
|
||||
width: number;
|
||||
}
|
||||
|
||||
export interface DevInfo {
|
||||
B485: number;
|
||||
IOInputNum: number;
|
||||
IOOutputNum: number;
|
||||
audioNum: number;
|
||||
buildDay: string;
|
||||
cfgVer: string;
|
||||
channelNum: number;
|
||||
detail: string;
|
||||
diskNum: number;
|
||||
exactType: string;
|
||||
firmVer: string;
|
||||
B485: number;
|
||||
IOInputNum: number;
|
||||
IOOutputNum: number;
|
||||
audioNum: number;
|
||||
buildDay: string;
|
||||
cfgVer: string;
|
||||
channelNum: number;
|
||||
detail: string;
|
||||
diskNum: number;
|
||||
exactType: string;
|
||||
firmVer: string;
|
||||
frameworkVer: number;
|
||||
hardVer: string;
|
||||
model: string;
|
||||
name: string;
|
||||
pakSuffix: string;
|
||||
serial: string;
|
||||
type: string;
|
||||
wifi: number;
|
||||
hardVer: string;
|
||||
model: string;
|
||||
name: string;
|
||||
pakSuffix: string;
|
||||
serial: string;
|
||||
type: string;
|
||||
wifi: number;
|
||||
}
|
||||
|
||||
export interface AIDetectionState {
|
||||
@@ -156,4 +158,62 @@ export class ReolinkCameraClient {
|
||||
|
||||
return response.data?.[0]?.value?.DevInfo;
|
||||
}
|
||||
|
||||
async ptz(command: PanTiltZoomCommand) {
|
||||
let op = '';
|
||||
if (command.pan < 0)
|
||||
op += 'Left';
|
||||
else if (command.pan > 0)
|
||||
op += 'Right'
|
||||
if (command.tilt < 0)
|
||||
op += 'Down';
|
||||
else if (command.tilt > 0)
|
||||
op += 'Up';
|
||||
|
||||
if (!op)
|
||||
return;
|
||||
|
||||
const url = new URL(`http://${this.host}/api.cgi`);
|
||||
const params = url.searchParams;
|
||||
params.set('cmd', 'PtzCtrl');
|
||||
params.set('user', this.username);
|
||||
params.set('password', this.password);
|
||||
|
||||
const c1 = this.digestAuth.request({
|
||||
method: 'POST',
|
||||
url: url.toString(),
|
||||
httpsAgent: reolinkHttpsAgent,
|
||||
data: [
|
||||
{
|
||||
cmd: "PtzCtrl",
|
||||
param: {
|
||||
channel: this.channelId,
|
||||
op,
|
||||
speed: 10,
|
||||
timeout: 1,
|
||||
}
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const c2 = this.digestAuth.request({
|
||||
method: 'POST',
|
||||
url: url.toString(),
|
||||
httpsAgent: reolinkHttpsAgent,
|
||||
data: [
|
||||
{
|
||||
cmd: "PtzCtrl",
|
||||
param: {
|
||||
channel: this.channelId,
|
||||
op: "Stop"
|
||||
}
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
this.console.log(await c1);
|
||||
this.console.log(await c2);
|
||||
}
|
||||
}
|
||||
|
||||
181
plugins/snapshot/package-lock.json
generated
181
plugins/snapshot/package-lock.json
generated
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"name": "@scrypted/snapshot",
|
||||
"version": "0.2.23",
|
||||
"version": "0.2.31",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/snapshot",
|
||||
"version": "0.2.23",
|
||||
"version": "0.2.31",
|
||||
"dependencies": {
|
||||
"@koush/axios-digest-auth": "^0.8.5",
|
||||
"@types/node": "^20.10.5",
|
||||
"axios": "^1.4.0",
|
||||
"@koush/axios-digest-auth": "^0.8.7",
|
||||
"@types/node": "^20.10.6",
|
||||
"axios": "^0.21.4",
|
||||
"sharp": "^0.33.1",
|
||||
"whatwg-mimetype": "^4.0.0"
|
||||
},
|
||||
@@ -38,7 +38,7 @@
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.3.3",
|
||||
"version": "0.3.4",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
@@ -515,22 +515,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@koush/axios-digest-auth": {
|
||||
"version": "0.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.6.tgz",
|
||||
"integrity": "sha512-e/XKs7/BYpPQkces0Cm4dUmhT9hR0rjvnNZAVRyRnNWdQ8cyCMFWS9HIrMWOdzAocKDNBXi1vKjJ8CywrW5xgQ==",
|
||||
"version": "0.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.7.tgz",
|
||||
"integrity": "sha512-sZepmWhDt4JUMB1ycX8k9SmDfHeCX+g+pGslrpLORHhEo2vLYFzTjAzL62NFmZO9uG4xmedDn4i0eJW5IK3//Q==",
|
||||
"dependencies": {
|
||||
"auth-header": "^1.0.0",
|
||||
"axios": "^0.21.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@koush/axios-digest-auth/node_modules/axios": {
|
||||
"version": "0.21.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
|
||||
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@scrypted/common": {
|
||||
"resolved": "../../common",
|
||||
"link": true
|
||||
@@ -540,9 +532,9 @@
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz",
|
||||
"integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==",
|
||||
"version": "20.10.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz",
|
||||
"integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
@@ -553,24 +545,17 @@
|
||||
"integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/auth-header": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/auth-header/-/auth-header-1.0.0.tgz",
|
||||
"integrity": "sha512-CPPazq09YVDUNNVWo4oSPTQmtwIzHusZhQmahCKvIsk0/xH6U3QsMAv3sM+7+Q0B1K2KJ/Q38OND317uXs4NHA=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
|
||||
"integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
|
||||
"version": "0.21.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
|
||||
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.0",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
"follow-redirects": "^1.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color": {
|
||||
@@ -610,25 +595,6 @@
|
||||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
|
||||
@@ -656,19 +622,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arrayish": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||
@@ -685,30 +638,6 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
@@ -947,22 +876,12 @@
|
||||
"optional": true
|
||||
},
|
||||
"@koush/axios-digest-auth": {
|
||||
"version": "0.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.6.tgz",
|
||||
"integrity": "sha512-e/XKs7/BYpPQkces0Cm4dUmhT9hR0rjvnNZAVRyRnNWdQ8cyCMFWS9HIrMWOdzAocKDNBXi1vKjJ8CywrW5xgQ==",
|
||||
"version": "0.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@koush/axios-digest-auth/-/axios-digest-auth-0.8.7.tgz",
|
||||
"integrity": "sha512-sZepmWhDt4JUMB1ycX8k9SmDfHeCX+g+pGslrpLORHhEo2vLYFzTjAzL62NFmZO9uG4xmedDn4i0eJW5IK3//Q==",
|
||||
"requires": {
|
||||
"auth-header": "^1.0.0",
|
||||
"axios": "^0.21.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": {
|
||||
"version": "0.21.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
|
||||
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.14.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@scrypted/common": {
|
||||
@@ -1001,9 +920,9 @@
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "20.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz",
|
||||
"integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==",
|
||||
"version": "20.10.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz",
|
||||
"integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==",
|
||||
"requires": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
@@ -1014,24 +933,17 @@
|
||||
"integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==",
|
||||
"dev": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"auth-header": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/auth-header/-/auth-header-1.0.0.tgz",
|
||||
"integrity": "sha512-CPPazq09YVDUNNVWo4oSPTQmtwIzHusZhQmahCKvIsk0/xH6U3QsMAv3sM+7+Q0B1K2KJ/Q38OND317uXs4NHA=="
|
||||
},
|
||||
"axios": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
|
||||
"integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
|
||||
"version": "0.21.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
|
||||
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.15.0",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
"follow-redirects": "^1.14.0"
|
||||
}
|
||||
},
|
||||
"color": {
|
||||
@@ -1065,19 +977,6 @@
|
||||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
|
||||
@@ -1088,16 +987,6 @@
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
|
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"is-arrayish": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||
@@ -1111,24 +1000,6 @@
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"requires": {
|
||||
"mime-db": "1.52.0"
|
||||
}
|
||||
},
|
||||
"proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/snapshot",
|
||||
"version": "0.2.23",
|
||||
"version": "0.2.31",
|
||||
"description": "Snapshot Plugin for Scrypted",
|
||||
"scripts": {
|
||||
"scrypted-setup-project": "scrypted-setup-project",
|
||||
@@ -34,9 +34,9 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@koush/axios-digest-auth": "^0.8.5",
|
||||
"@types/node": "^20.10.5",
|
||||
"axios": "^1.4.0",
|
||||
"@koush/axios-digest-auth": "^0.8.7",
|
||||
"@types/node": "^20.10.6",
|
||||
"axios": "^0.21.4",
|
||||
"sharp": "^0.33.1",
|
||||
"whatwg-mimetype": "^4.0.0"
|
||||
},
|
||||
|
||||
@@ -12,8 +12,12 @@ import { ffmpegFilterImage, ffmpegFilterImageBuffer } from './ffmpeg-image-filte
|
||||
import { ImageConverter, ImageConverterNativeId } from './image-converter';
|
||||
import { ImageReader, ImageReaderNativeId, loadSharp, loadVipsImage } from './image-reader';
|
||||
import { ImageWriter, ImageWriterNativeId } from './image-writer';
|
||||
import os from 'os';
|
||||
|
||||
const { mediaManager, systemManager } = sdk;
|
||||
if (os.cpus().find(cpu => cpu.model?.toLowerCase().includes('qemu'))) {
|
||||
sdk.log.a('QEMU CPU detected. Set your CPU model to host.');
|
||||
}
|
||||
|
||||
const httpsAgent = new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
@@ -300,7 +304,7 @@ class SnapshotMixin extends SettingsMixinDeviceBase<Camera> implements Camera {
|
||||
picture = this.currentPicture;
|
||||
}
|
||||
|
||||
const needSoftwareResize = !!(options?.picture?.width || options?.picture?.height);
|
||||
const needSoftwareResize = !!(options?.picture?.width || options?.picture?.height) && this.storageSettings.values.snapshotResolution !== 'Full Resolution';
|
||||
if (needSoftwareResize) {
|
||||
try {
|
||||
picture = await this.snapshotDebouncer({
|
||||
@@ -669,6 +673,9 @@ export class SnapshotPlugin extends AutoenableMixinProvider implements MixinProv
|
||||
}
|
||||
};
|
||||
|
||||
if (mixin.storageSettings.values.snapshotResolution === 'Full Resolution')
|
||||
delete rpo.picture;
|
||||
|
||||
if (mixin && iface === ScryptedInterface.Camera) {
|
||||
buffer = await mixin.takePictureRaw(rpo)
|
||||
}
|
||||
|
||||
2
server/.vscode/launch.json
vendored
2
server/.vscode/launch.json
vendored
@@ -27,7 +27,7 @@
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"env": {
|
||||
"SCRYPTED_DEFAULT_AUTHENTICATION": "demo"
|
||||
// "SCRYPTED_DEFAULT_AUTHENTICATION": "demo"
|
||||
// force usage of system python because brew python is 3.11
|
||||
// which has no wheels for coreml tools or tflite-runtime
|
||||
// "SCRYPTED_PYTHON_PATH": "/usr/bin/python3",
|
||||
|
||||
19
server/package-lock.json
generated
19
server/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/server",
|
||||
"version": "0.77.0",
|
||||
"version": "0.80.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/server",
|
||||
"version": "0.77.0",
|
||||
"version": "0.80.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.11",
|
||||
@@ -25,7 +25,7 @@
|
||||
"linkfs": "^2.1.0",
|
||||
"lodash": "^4.17.21",
|
||||
"memfs": "^4.6.0",
|
||||
"mime": "^4.0.1",
|
||||
"mime": "^3.0.0",
|
||||
"nan": "^2.18.0",
|
||||
"node-dijkstra": "^2.5.0",
|
||||
"node-forge": "^1.3.1",
|
||||
@@ -2491,17 +2491,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mime": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-4.0.1.tgz",
|
||||
"integrity": "sha512-5lZ5tyrIfliMXzFtkYyekWbtRXObT9OWa8IwQ5uxTBDHucNNwniRqo0yInflj+iYi5CBa6qxadGzGarDfuEOxA==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa"
|
||||
],
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
|
||||
"integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
|
||||
"bin": {
|
||||
"mime": "bin/cli.js"
|
||||
"mime": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/server",
|
||||
"version": "0.78.0",
|
||||
"version": "0.80.0",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.11",
|
||||
@@ -19,7 +19,7 @@
|
||||
"linkfs": "^2.1.0",
|
||||
"lodash": "^4.17.21",
|
||||
"memfs": "^4.6.0",
|
||||
"mime": "^4.0.1",
|
||||
"mime": "^3.0.0",
|
||||
"nan": "^2.18.0",
|
||||
"node-dijkstra": "^2.5.0",
|
||||
"node-forge": "^1.3.1",
|
||||
|
||||
@@ -31,6 +31,7 @@ export async function safeKillFFmpeg(cp: ChildProcess) {
|
||||
catch (e) {
|
||||
}
|
||||
}
|
||||
cp.kill();
|
||||
await sleep(2000);
|
||||
cp.kill('SIGKILL');
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ export interface StdPassThroughs {
|
||||
}
|
||||
|
||||
export function getConsole(hook: (stdout: PassThrough, stderr: PassThrough) => Promise<void>,
|
||||
also?: Console, alsoPrefix?: string) {
|
||||
also?: Console, alsoPrefix?: string) {
|
||||
|
||||
const stdout = new PassThrough();
|
||||
const stderr = new PassThrough();
|
||||
@@ -63,7 +63,7 @@ export function getConsole(hook: (stdout: PassThrough, stderr: PassThrough) => P
|
||||
|
||||
export function prepareConsoles(getConsoleName: () => string, systemManager: () => SystemManager, deviceManager: () => DeviceManager, getPlugins: () => Promise<any>) {
|
||||
const deviceConsoles = new Map<string, Console>();
|
||||
function getDeviceConsole (nativeId?: ScryptedNativeId) {
|
||||
function getDeviceConsole(nativeId?: ScryptedNativeId) {
|
||||
// the the plugin console is simply the default console
|
||||
// and gets read from stderr/stdout.
|
||||
if (!nativeId)
|
||||
@@ -126,13 +126,16 @@ export function prepareConsoles(getConsoleName: () => string, systemManager: ()
|
||||
|
||||
const connect = async () => {
|
||||
const ds = deviceManager().getDeviceState(nativeId);
|
||||
if (!ds) {
|
||||
// deleted?
|
||||
// device deleted
|
||||
if (!ds)
|
||||
return;
|
||||
}
|
||||
|
||||
const plugins = await getPlugins();
|
||||
const { pluginId, nativeId: mixinNativeId } = await plugins.getDeviceInfo(mixinId);
|
||||
const mixin = systemManager().getDeviceById(mixinId);
|
||||
// mixin deleted
|
||||
if (!mixin)
|
||||
return;
|
||||
const { pluginId, nativeId: mixinNativeId } = mixin;
|
||||
const port = await plugins.getRemoteServicePort(pluginId, 'console-writer');
|
||||
const socket = net.connect(port);
|
||||
socket.write(mixinNativeId + '\n');
|
||||
@@ -161,7 +164,7 @@ export function prepareConsoles(getConsoleName: () => string, systemManager: ()
|
||||
nativeIdConsoles.set(mixinId, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
getDeviceConsole,
|
||||
getMixinConsole,
|
||||
|
||||
Reference in New Issue
Block a user