@scrypted/server 0.1.12 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @scrypted/server might be problematic. Click here for more details.
- package/dist/plugin/descriptor.js +23 -18
- package/dist/plugin/descriptor.js.map +1 -1
- package/dist/plugin/media.js +2 -2
- package/dist/plugin/media.js.map +1 -1
- package/dist/plugin/plugin-api.js +3 -0
- package/dist/plugin/plugin-api.js.map +1 -1
- package/dist/plugin/plugin-device.js +24 -14
- package/dist/plugin/plugin-device.js.map +1 -1
- package/dist/plugin/plugin-host-api.js +13 -4
- package/dist/plugin/plugin-host-api.js.map +1 -1
- package/dist/plugin/plugin-npm-dependencies.js +5 -1
- package/dist/plugin/plugin-npm-dependencies.js.map +1 -1
- package/dist/plugin/plugin-remote.js.map +1 -1
- package/dist/plugin/plugin-volume.js +2 -1
- package/dist/plugin/plugin-volume.js.map +1 -1
- package/dist/plugin/runtime/python-worker.js +2 -1
- package/dist/plugin/runtime/python-worker.js.map +1 -1
- package/dist/plugin/system.js +40 -4
- package/dist/plugin/system.js.map +1 -1
- package/dist/rpc-serializer.js +23 -10
- package/dist/rpc-serializer.js.map +1 -1
- package/dist/rpc.js +11 -0
- package/dist/rpc.js.map +1 -1
- package/dist/runtime.js +23 -23
- package/dist/runtime.js.map +1 -1
- package/dist/scrypted-server-main.js +1 -0
- package/dist/scrypted-server-main.js.map +1 -1
- package/dist/state.js +10 -19
- package/dist/state.js.map +1 -1
- package/package.json +4 -3
- package/python/plugin-remote.py +28 -19
- package/src/plugin/descriptor.ts +24 -18
- package/src/plugin/media.ts +2 -2
- package/src/plugin/plugin-api.ts +7 -1
- package/src/plugin/plugin-device.ts +31 -23
- package/src/plugin/plugin-host-api.ts +16 -7
- package/src/plugin/plugin-npm-dependencies.ts +5 -1
- package/src/plugin/plugin-remote.ts +0 -1
- package/src/plugin/plugin-volume.ts +2 -1
- package/src/plugin/runtime/python-worker.ts +3 -1
- package/src/plugin/system.ts +51 -13
- package/src/rpc-serializer.ts +30 -13
- package/src/rpc.ts +11 -0
- package/src/runtime.ts +28 -29
- package/src/scrypted-server-main.ts +1 -0
- package/src/state.ts +15 -26
package/dist/state.js
CHANGED
@@ -5,11 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
6
|
exports.getState = exports.setState = exports.ScryptedStateManager = void 0;
|
7
7
|
const types_1 = require("@scrypted/types");
|
8
|
-
const plugin_device_1 = require("./plugin/plugin-device");
|
9
8
|
const throttle_1 = __importDefault(require("lodash/throttle"));
|
10
|
-
const sleep_1 = require("./sleep");
|
11
9
|
const event_registry_1 = require("./event-registry");
|
12
10
|
const descriptor_1 = require("./plugin/descriptor");
|
11
|
+
const plugin_device_1 = require("./plugin/plugin-device");
|
12
|
+
const sleep_1 = require("./sleep");
|
13
13
|
class ScryptedStateManager extends event_registry_1.EventRegistry {
|
14
14
|
scrypted;
|
15
15
|
upserts = new Set();
|
@@ -35,33 +35,24 @@ class ScryptedStateManager extends event_registry_1.EventRegistry {
|
|
35
35
|
super();
|
36
36
|
this.scrypted = scrypted;
|
37
37
|
}
|
38
|
-
setPluginState(pluginId, nativeId, property, value) {
|
38
|
+
setPluginState(pluginId, nativeId, eventInterface, property, value) {
|
39
39
|
const device = this.scrypted.findPluginDevice(pluginId, nativeId);
|
40
40
|
if (!device)
|
41
41
|
throw new Error(`device not found for plugin id ${pluginId} native id ${nativeId}`);
|
42
|
-
this.setPluginDeviceState(device, property, value);
|
42
|
+
this.setPluginDeviceState(device, property, value, eventInterface);
|
43
43
|
}
|
44
|
-
setPluginDeviceState(device, property, value) {
|
45
|
-
|
46
|
-
|
47
|
-
// this currently doesn't work because inherited properties are not detected.
|
48
|
-
// ie, MediaPlayer implements StartStop and Pause
|
49
|
-
// if (!isValidInterfaceProperty(device.state.interfaces.value, property))
|
50
|
-
// throw new Error(`interface for property ${property} not implemented`);
|
51
|
-
if (!descriptor_1.allInterfaceProperties.includes(property))
|
44
|
+
setPluginDeviceState(device, property, value, eventInterface) {
|
45
|
+
eventInterface = eventInterface || descriptor_1.propertyInterfaces[property];
|
46
|
+
if (!eventInterface)
|
52
47
|
throw new Error(`${property} is not a valid property`);
|
53
48
|
const changed = setState(device, property, value);
|
54
|
-
this.notifyPropertyEvent(device, property, value, changed);
|
55
|
-
this.upserts.add(device._id);
|
56
|
-
this.upsertThrottle();
|
57
|
-
return changed;
|
58
|
-
}
|
59
|
-
notifyPropertyEvent(device, property, value, changed) {
|
60
49
|
const eventTime = device?.state?.[property]?.lastEventTime;
|
61
|
-
const eventInterface = descriptor_1.propertyInterfaces[property];
|
62
50
|
if (this.notify(device?._id, eventTime, eventInterface, property, value, changed) && device) {
|
63
51
|
this.scrypted.getDeviceLogger(device).log('i', `state change: ${property} ${value}`);
|
64
52
|
}
|
53
|
+
this.upserts.add(device._id);
|
54
|
+
this.upsertThrottle();
|
55
|
+
return changed;
|
65
56
|
}
|
66
57
|
updateDescriptor(device) {
|
67
58
|
this.notify(device._id, undefined, types_1.ScryptedInterface.ScryptedDevice, undefined, device.state, true);
|
package/dist/state.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":";;;;;;
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
{
|
2
2
|
"name": "@scrypted/server",
|
3
|
-
"version": "0.1.
|
3
|
+
"version": "0.1.15",
|
4
4
|
"description": "",
|
5
5
|
"dependencies": {
|
6
6
|
"@mapbox/node-pre-gyp": "^1.0.8",
|
7
|
-
"@scrypted/ffmpeg": "^1.0.10",
|
8
7
|
"@scrypted/types": "^0.0.44",
|
9
8
|
"adm-zip": "^0.5.3",
|
10
9
|
"axios": "^0.21.1",
|
@@ -13,6 +12,7 @@
|
|
13
12
|
"debug": "^4.3.1",
|
14
13
|
"engine.io": "^6.2.0",
|
15
14
|
"express": "^4.17.2",
|
15
|
+
"ffmpeg-static": "^5.0.2",
|
16
16
|
"http-auth": "^4.1.9",
|
17
17
|
"ip": "^1.1.8",
|
18
18
|
"level": "^6.0.1",
|
@@ -26,7 +26,7 @@
|
|
26
26
|
"node-dijkstra": "^2.5.0",
|
27
27
|
"node-forge": "^1.2.0",
|
28
28
|
"node-gyp": "^8.4.1",
|
29
|
-
"node-pty": "^0.10.1",
|
29
|
+
"node-pty-prebuilt-multiarch": "^0.10.1-pre.5",
|
30
30
|
"query-string": "^6.14.1",
|
31
31
|
"router": "^1.3.6",
|
32
32
|
"semver": "^7.3.5",
|
@@ -46,6 +46,7 @@
|
|
46
46
|
"@types/cookie-parser": "^1.4.2",
|
47
47
|
"@types/debug": "^4.1.5",
|
48
48
|
"@types/express": "^4.17.11",
|
49
|
+
"@types/ffmpeg-static": "^3.0.1",
|
49
50
|
"@types/http-auth": "^4.1.1",
|
50
51
|
"@types/ip": "^1.1.0",
|
51
52
|
"@types/lodash": "^4.14.168",
|
package/python/plugin-remote.py
CHANGED
@@ -6,7 +6,6 @@ import gc
|
|
6
6
|
import json
|
7
7
|
import os
|
8
8
|
import platform
|
9
|
-
import resource
|
10
9
|
import shutil
|
11
10
|
import subprocess
|
12
11
|
import threading
|
@@ -21,7 +20,6 @@ from os import sys
|
|
21
20
|
from typing import Any, Optional, Set, Tuple
|
22
21
|
|
23
22
|
import aiofiles
|
24
|
-
import gi
|
25
23
|
import scrypted_python.scrypted_sdk.types
|
26
24
|
from scrypted_python.scrypted_sdk.types import (Device, DeviceManifest,
|
27
25
|
MediaManager,
|
@@ -31,12 +29,6 @@ from typing_extensions import TypedDict
|
|
31
29
|
|
32
30
|
import rpc
|
33
31
|
|
34
|
-
gi.require_version('Gst', '1.0')
|
35
|
-
|
36
|
-
from gi.repository import GLib, Gst
|
37
|
-
|
38
|
-
Gst.init(None)
|
39
|
-
|
40
32
|
class SystemDeviceState(TypedDict):
|
41
33
|
lastEventTime: int
|
42
34
|
stateTime: int
|
@@ -227,9 +219,9 @@ class PluginRemote:
|
|
227
219
|
if not os.path.exists(python_prefix):
|
228
220
|
os.makedirs(python_prefix)
|
229
221
|
|
230
|
-
|
222
|
+
python_version = 'python%s' % str(
|
231
223
|
sys.version_info[0])+"."+str(sys.version_info[1])
|
232
|
-
print('python:',
|
224
|
+
print('python version:', python_version)
|
233
225
|
|
234
226
|
if 'requirements.txt' in zip.namelist():
|
235
227
|
requirements = zip.open('requirements.txt').read()
|
@@ -254,7 +246,7 @@ class PluginRemote:
|
|
254
246
|
f.write(requirements)
|
255
247
|
f.close()
|
256
248
|
|
257
|
-
p = subprocess.Popen([
|
249
|
+
p = subprocess.Popen([sys.executable, '-m', 'pip', 'install', '-r', requirementstxt,
|
258
250
|
'--prefix', python_prefix], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
259
251
|
while True:
|
260
252
|
line = p.stdout.readline()
|
@@ -275,8 +267,13 @@ class PluginRemote:
|
|
275
267
|
print(str_requirements)
|
276
268
|
|
277
269
|
sys.path.insert(0, zipPath)
|
278
|
-
|
279
|
-
|
270
|
+
if platform.system() != 'Windows':
|
271
|
+
site_packages = os.path.join(
|
272
|
+
python_prefix, 'lib', python_version, 'site-packages')
|
273
|
+
else:
|
274
|
+
site_packages = os.path.join(
|
275
|
+
python_prefix, 'Lib', 'site-packages')
|
276
|
+
print('site-packages: %s' % site_packages)
|
280
277
|
sys.path.insert(0, site_packages)
|
281
278
|
from scrypted_sdk import sdk_init # type: ignore
|
282
279
|
self.systemManager = SystemManager(self.api, self.systemState)
|
@@ -366,7 +363,11 @@ async def async_main(loop: AbstractEventLoop):
|
|
366
363
|
|
367
364
|
def stats_runner():
|
368
365
|
ptime = round(time.process_time() * 1000000)
|
369
|
-
|
366
|
+
try:
|
367
|
+
import resource
|
368
|
+
heapTotal = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
|
369
|
+
except:
|
370
|
+
heapTotal = 0
|
370
371
|
stats = {
|
371
372
|
'type': 'stats',
|
372
373
|
'cpuUsage': {
|
@@ -399,8 +400,16 @@ def main():
|
|
399
400
|
|
400
401
|
|
401
402
|
if __name__ == "__main__":
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
403
|
+
try:
|
404
|
+
import gi
|
405
|
+
gi.require_version('Gst', '1.0')
|
406
|
+
from gi.repository import GLib, Gst
|
407
|
+
Gst.init(None)
|
408
|
+
|
409
|
+
worker = threading.Thread(target=main)
|
410
|
+
worker.start()
|
411
|
+
|
412
|
+
loop = GLib.MainLoop()
|
413
|
+
loop.run()
|
414
|
+
except:
|
415
|
+
main()
|
package/src/plugin/descriptor.ts
CHANGED
@@ -1,29 +1,35 @@
|
|
1
|
-
import { ScryptedInterface, ScryptedInterfaceDescriptors } from "@scrypted/types";
|
1
|
+
import { ScryptedInterface, ScryptedInterfaceDescriptor, ScryptedInterfaceDescriptors } from "@scrypted/types";
|
2
2
|
|
3
|
-
export const
|
4
|
-
export const allInterfaceProperties: string[] = [].concat(...Object.values(ScryptedInterfaceDescriptors).map((type: any) => type.properties));
|
5
|
-
export const deviceMethods: string[] = ['listen', 'setName', 'setRoom', 'setType'];
|
3
|
+
export const allInterfaceProperties: string[] = [].concat(...Object.values(ScryptedInterfaceDescriptors).map(type => type.properties));
|
6
4
|
|
7
|
-
export
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
export function getPropertyInterfaces(descriptors: { [scryptedInterface: string]: ScryptedInterfaceDescriptor }) {
|
6
|
+
const propertyInterfaces: { [property: string]: ScryptedInterface } = {};
|
7
|
+
|
8
|
+
for (const descriptor of Object.values(descriptors)) {
|
9
|
+
for (const property of descriptor.properties) {
|
10
|
+
propertyInterfaces[property] = descriptor.name as ScryptedInterface;
|
11
|
+
}
|
11
12
|
}
|
13
|
+
|
14
|
+
return propertyInterfaces;
|
12
15
|
}
|
13
16
|
|
14
|
-
export const propertyInterfaces
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
export const propertyInterfaces = getPropertyInterfaces(ScryptedInterfaceDescriptors);
|
18
|
+
|
19
|
+
export function getInterfaceMethods(descriptors: { [scryptedInterface: string]: ScryptedInterfaceDescriptor }, interfaces: Set<string>) {
|
20
|
+
return Object.values(descriptors).filter(e => interfaces.has(e.name)).map(type => type.methods).flat();
|
21
|
+
}
|
22
|
+
|
23
|
+
export function getInterfaceProperties(descriptors: { [scryptedInterface: string]: ScryptedInterfaceDescriptor }, interfaces: Set<string>) {
|
24
|
+
return Object.values(descriptors).filter(e => interfaces.has(e.name)).map(type => type.properties).flat();
|
19
25
|
}
|
20
26
|
|
21
|
-
export function isValidInterfaceMethod(
|
22
|
-
const availableMethods
|
23
|
-
return availableMethods.includes(method) ||
|
27
|
+
export function isValidInterfaceMethod(descriptors: { [scryptedInterface: string]: ScryptedInterfaceDescriptor }, interfaces: Set<string>, method: string) {
|
28
|
+
const availableMethods = getInterfaceMethods(descriptors, interfaces);
|
29
|
+
return availableMethods.includes(method) || descriptors[ScryptedInterface.ScryptedDevice].methods.includes(method);
|
24
30
|
}
|
25
31
|
|
26
|
-
export function isValidInterfaceProperty(interfaces: string[], property: string): boolean {
|
27
|
-
const availableProperties
|
32
|
+
export function isValidInterfaceProperty(descriptors: { [scryptedInterface: string]: ScryptedInterfaceDescriptor }, interfaces: string[], property: string): boolean {
|
33
|
+
const availableProperties = getInterfaceProperties(descriptors, new Set(interfaces));
|
28
34
|
return availableProperties.includes(property);
|
29
35
|
}
|
package/src/plugin/media.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import
|
1
|
+
import pathToFfmpeg from 'ffmpeg-static';
|
2
2
|
import { BufferConverter, BufferConvertorOptions, DeviceManager, FFmpegInput, MediaManager, MediaObject, MediaObjectOptions, MediaStreamUrl, ScryptedInterface, ScryptedInterfaceProperty, ScryptedMimeTypes, ScryptedNativeId, SystemDeviceState, SystemManager } from "@scrypted/types";
|
3
3
|
import axios from 'axios';
|
4
4
|
import child_process from 'child_process';
|
@@ -188,7 +188,7 @@ export abstract class MediaManagerBase implements MediaManager {
|
|
188
188
|
return f;
|
189
189
|
|
190
190
|
const defaultPath = os.platform() === 'win32' ? 'ffmpeg.exe' : 'ffmpeg';
|
191
|
-
return
|
191
|
+
return pathToFfmpeg || defaultPath;
|
192
192
|
}
|
193
193
|
|
194
194
|
async getFilesPath(): Promise<string> {
|
package/src/plugin/plugin-api.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { ScryptedNativeId, ScryptedDevice, Device, DeviceManifest, EventDetails, EventListenerOptions, EventListenerRegister, ScryptedInterfaceProperty, MediaObject, SystemDeviceState, MediaManager, HttpRequest } from '@scrypted/types'
|
1
|
+
import type { ScryptedNativeId, ScryptedDevice, Device, DeviceManifest, EventDetails, EventListenerOptions, EventListenerRegister, ScryptedInterfaceProperty, MediaObject, SystemDeviceState, MediaManager, HttpRequest, ScryptedInterfaceDescriptor } from '@scrypted/types'
|
2
2
|
|
3
3
|
export interface PluginLogger {
|
4
4
|
log(level: string, message: string): Promise<void>;
|
@@ -34,6 +34,8 @@ export interface PluginAPI {
|
|
34
34
|
getMediaManager(): Promise<MediaManager>;
|
35
35
|
|
36
36
|
requestRestart(): Promise<void>;
|
37
|
+
|
38
|
+
setScryptedInterfaceDescriptors(typesVersion: string, descriptors: { [scryptedInterface: string]: ScryptedInterfaceDescriptor }): Promise<void>;
|
37
39
|
}
|
38
40
|
|
39
41
|
class EventListenerRegisterProxy implements EventListenerRegister {
|
@@ -71,6 +73,10 @@ export class PluginAPIProxy extends PluginAPIManagedListeners implements PluginA
|
|
71
73
|
super();
|
72
74
|
}
|
73
75
|
|
76
|
+
setScryptedInterfaceDescriptors(typesVersion: string, descriptors: { [scryptedInterface: string]: ScryptedInterfaceDescriptor }): Promise<void> {
|
77
|
+
return this.api.setScryptedInterfaceDescriptors(typesVersion, descriptors);
|
78
|
+
}
|
79
|
+
|
74
80
|
setState(nativeId: ScryptedNativeId, key: string, value: any): Promise<void> {
|
75
81
|
return this.api.setState(nativeId, key, value);
|
76
82
|
}
|
@@ -1,15 +1,14 @@
|
|
1
|
-
import { DeviceProvider,
|
2
|
-
import
|
1
|
+
import { DeviceProvider, EventListener, EventListenerOptions, EventListenerRegister, MixinProvider, ScryptedDevice, ScryptedDeviceType, ScryptedInterface, ScryptedInterfaceDescriptors, ScryptedInterfaceProperty } from "@scrypted/types";
|
2
|
+
import fs from 'fs';
|
3
|
+
import path from 'path';
|
3
4
|
import { PluginDevice } from "../db-types";
|
4
|
-
import { MixinProvider } from "@scrypted/types";
|
5
|
-
import { RpcPeer, PrimitiveProxyHandler } from "../rpc";
|
6
|
-
import { getState } from "../state";
|
7
5
|
import { getDisplayType } from "../infer-defaults";
|
8
|
-
import {
|
9
|
-
import {
|
6
|
+
import { PrimitiveProxyHandler, RpcPeer } from "../rpc";
|
7
|
+
import { ScryptedRuntime } from "../runtime";
|
10
8
|
import { sleep } from "../sleep";
|
11
|
-
import
|
12
|
-
import
|
9
|
+
import { getState } from "../state";
|
10
|
+
import { allInterfaceProperties, getInterfaceMethods, getPropertyInterfaces } from "./descriptor";
|
11
|
+
import { PluginError } from "./plugin-error";
|
13
12
|
|
14
13
|
interface MixinTable {
|
15
14
|
mixinProviderId: string;
|
@@ -17,7 +16,8 @@ interface MixinTable {
|
|
17
16
|
}
|
18
17
|
|
19
18
|
interface MixinTableEntry {
|
20
|
-
interfaces: Set<string
|
19
|
+
interfaces: Set<string>;
|
20
|
+
methods?: Set<string>;
|
21
21
|
allInterfaces: string[];
|
22
22
|
proxy: any;
|
23
23
|
error?: Error;
|
@@ -244,9 +244,10 @@ export class PluginDeviceProxyHandler implements PrimitiveProxyHandler<any>, Scr
|
|
244
244
|
|
245
245
|
const implementer = await (mixinProvider as any)[QueryInterfaceSymbol](ScryptedInterface.MixinProvider);
|
246
246
|
const host = this.scrypted.getPluginHostForDeviceId(implementer);
|
247
|
+
const propertyInterfaces = getPropertyInterfaces(host.api.descriptors || ScryptedInterfaceDescriptors);
|
247
248
|
// todo: remove this and pass the setter directly.
|
248
249
|
const deviceState = await host.remote.createDeviceState(this.id,
|
249
|
-
async (property, value) => this.scrypted.stateManager.setPluginDeviceState(pluginDevice, property, value));
|
250
|
+
async (property, value) => this.scrypted.stateManager.setPluginDeviceState(pluginDevice, property, value, propertyInterfaces[property]));
|
250
251
|
const mixinProxy = await mixinProvider.getMixin(wrappedProxy, previousInterfaces as ScryptedInterface[], deviceState);
|
251
252
|
if (!mixinProxy)
|
252
253
|
throw new PluginError(`mixin provider ${mixinId} did not return mixin for ${this.id}`);
|
@@ -283,7 +284,7 @@ export class PluginDeviceProxyHandler implements PrimitiveProxyHandler<any>, Scr
|
|
283
284
|
}
|
284
285
|
|
285
286
|
get(target: any, p: PropertyKey, receiver: any): any {
|
286
|
-
if (p
|
287
|
+
if (RpcPeer.PROBED_PROPERTIES.has(p))
|
287
288
|
return;
|
288
289
|
const handled = RpcPeer.handleFunctionInvocations(this, target, p, receiver);
|
289
290
|
if (handled)
|
@@ -300,9 +301,6 @@ export class PluginDeviceProxyHandler implements PrimitiveProxyHandler<any>, Scr
|
|
300
301
|
if (p === RefreshSymbol || p === QueryInterfaceSymbol)
|
301
302
|
return new Proxy(() => p, this);
|
302
303
|
|
303
|
-
if (!isValidInterfaceMethod(pluginDevice.state.interfaces.value, prop))
|
304
|
-
return;
|
305
|
-
|
306
304
|
if (ScryptedInterfaceDescriptors[ScryptedInterface.ScryptedDevice].methods.includes(prop))
|
307
305
|
return (this as any)[p].bind(this);
|
308
306
|
|
@@ -339,11 +337,7 @@ export class PluginDeviceProxyHandler implements PrimitiveProxyHandler<any>, Scr
|
|
339
337
|
}
|
340
338
|
|
341
339
|
async applyMixin(method: string, argArray?: any): Promise<any> {
|
342
|
-
const
|
343
|
-
if (!iface)
|
344
|
-
throw new PluginError(`unknown method ${method}`);
|
345
|
-
|
346
|
-
const found = await this.findMixin(iface);
|
340
|
+
const found = await this.findMethod(method);
|
347
341
|
if (found) {
|
348
342
|
const { mixin, entry } = found;
|
349
343
|
const { proxy } = entry;
|
@@ -355,6 +349,23 @@ export class PluginDeviceProxyHandler implements PrimitiveProxyHandler<any>, Scr
|
|
355
349
|
throw new PluginError(`${method} not implemented`)
|
356
350
|
}
|
357
351
|
|
352
|
+
async findMethod(method: string) {
|
353
|
+
for (const mixin of this.mixinTable) {
|
354
|
+
const entry = await mixin.entry;
|
355
|
+
if (!entry.methods) {
|
356
|
+
const pluginDevice = this.scrypted.findPluginDeviceById(mixin.mixinProviderId || this.id);
|
357
|
+
const plugin = this.scrypted.plugins[pluginDevice.pluginId];
|
358
|
+
let methods = new Set<string>(getInterfaceMethods(ScryptedInterfaceDescriptors, entry.interfaces))
|
359
|
+
if (plugin.api.descriptors)
|
360
|
+
methods = new Set<string>([...methods, ...getInterfaceMethods(plugin.api.descriptors, entry.interfaces)]);
|
361
|
+
entry.methods = methods;
|
362
|
+
}
|
363
|
+
if (entry.methods.has(method)) {
|
364
|
+
return { mixin, entry };
|
365
|
+
}
|
366
|
+
}
|
367
|
+
}
|
368
|
+
|
358
369
|
async findMixin(iface: string) {
|
359
370
|
for (const mixin of this.mixinTable) {
|
360
371
|
const entry = await mixin.entry;
|
@@ -407,9 +418,6 @@ export class PluginDeviceProxyHandler implements PrimitiveProxyHandler<any>, Scr
|
|
407
418
|
return this.scrypted.getPackageJson(pluginDevice.pluginId);
|
408
419
|
}
|
409
420
|
|
410
|
-
if (!isValidInterfaceMethod(pluginDevice.state.interfaces.value, method))
|
411
|
-
throw new PluginError(`device ${this.id} does not support method ${method}`);
|
412
|
-
|
413
421
|
if (method === 'refresh') {
|
414
422
|
const refreshInterface = argArray[0];
|
415
423
|
const userInitiated = argArray[1];
|
@@ -1,17 +1,20 @@
|
|
1
|
-
import {
|
2
|
-
import
|
1
|
+
import { Device, DeviceManifest, EventDetails, EventListenerOptions, EventListenerRegister, HttpRequest, MediaManager, ScryptedDevice, ScryptedInterfaceDescriptor, ScryptedInterfaceProperty, ScryptedNativeId } from '@scrypted/types';
|
2
|
+
import debounce from 'lodash/debounce';
|
3
3
|
import { Plugin } from '../db-types';
|
4
|
-
import { PluginAPI, PluginAPIManagedListeners } from './plugin-api';
|
5
4
|
import { Logger } from '../logger';
|
5
|
+
import { RpcPeer } from '../rpc';
|
6
|
+
import { ScryptedRuntime } from '../runtime';
|
6
7
|
import { getState } from '../state';
|
8
|
+
import { getPropertyInterfaces } from './descriptor';
|
9
|
+
import { PluginAPI, PluginAPIManagedListeners } from './plugin-api';
|
7
10
|
import { PluginHost } from './plugin-host';
|
8
|
-
import debounce from 'lodash/debounce';
|
9
|
-
import { RpcPeer } from '../rpc';
|
10
|
-
import { propertyInterfaces } from './descriptor';
|
11
11
|
import { checkProperty } from './plugin-state-check';
|
12
12
|
|
13
13
|
export class PluginHostAPI extends PluginAPIManagedListeners implements PluginAPI {
|
14
14
|
pluginId: string;
|
15
|
+
typesVersion: string;
|
16
|
+
descriptors: { [scryptedInterface: string]: ScryptedInterfaceDescriptor };
|
17
|
+
propertyInterfaces: ReturnType<typeof getPropertyInterfaces>;
|
15
18
|
|
16
19
|
[RpcPeer.PROPERTY_PROXY_ONEWAY_METHODS] = [
|
17
20
|
'onMixinEvent',
|
@@ -116,7 +119,7 @@ export class PluginHostAPI extends PluginAPIManagedListeners implements PluginAP
|
|
116
119
|
|
117
120
|
async setState(nativeId: ScryptedNativeId, key: string, value: any) {
|
118
121
|
checkProperty(key, value);
|
119
|
-
this.scrypted.stateManager.setPluginState(this.pluginId, nativeId, key, value);
|
122
|
+
this.scrypted.stateManager.setPluginState(this.pluginId, nativeId, this.propertyInterfaces?.[key], key, value);
|
120
123
|
}
|
121
124
|
|
122
125
|
async setStorage(nativeId: ScryptedNativeId, storage: { [key: string]: string }) {
|
@@ -179,4 +182,10 @@ export class PluginHostAPI extends PluginAPIManagedListeners implements PluginAP
|
|
179
182
|
logger.log('i', 'plugin restart was requested');
|
180
183
|
return this.restartDebounced();
|
181
184
|
}
|
185
|
+
|
186
|
+
async setScryptedInterfaceDescriptors(typesVersion: string, descriptors: { [scryptedInterface: string]: ScryptedInterfaceDescriptor }): Promise<void> {
|
187
|
+
this.typesVersion = typesVersion;
|
188
|
+
this.descriptors = descriptors;
|
189
|
+
this.propertyInterfaces = getPropertyInterfaces(descriptors);
|
190
|
+
}
|
182
191
|
}
|
@@ -6,6 +6,7 @@ import { once } from 'events';
|
|
6
6
|
import process from 'process';
|
7
7
|
import mkdirp from "mkdirp";
|
8
8
|
import semver from 'semver';
|
9
|
+
import os from 'os';
|
9
10
|
|
10
11
|
export function getPluginNodePath(name: string) {
|
11
12
|
const pluginVolume = ensurePluginVolume(name);
|
@@ -48,7 +49,10 @@ export async function installOptionalDependencies(console: Console, packageJson:
|
|
48
49
|
mkdirp.sync(nodePrefix);
|
49
50
|
fs.writeFileSync(packageJsonPath, JSON.stringify(reduced));
|
50
51
|
|
51
|
-
|
52
|
+
let npm = 'npm';
|
53
|
+
if (os.platform() === 'win32')
|
54
|
+
npm += '.cmd';
|
55
|
+
const cp = child_process.spawn(npm, ['--prefix', nodePrefix, 'install'], {
|
52
56
|
cwd: nodePrefix,
|
53
57
|
stdio: 'inherit',
|
54
58
|
});
|
@@ -9,7 +9,6 @@ import { BufferSerializer } from './buffer-serializer';
|
|
9
9
|
import { createWebSocketClass, WebSocketConnectCallbacks, WebSocketMethods } from './plugin-remote-websocket';
|
10
10
|
import fs from 'fs';
|
11
11
|
import { checkProperty } from './plugin-state-check';
|
12
|
-
import _ from 'lodash';
|
13
12
|
const { link } = require('linkfs');
|
14
13
|
|
15
14
|
class DeviceLogger implements Logger {
|
@@ -1,8 +1,9 @@
|
|
1
|
+
import os from 'os';
|
1
2
|
import path from 'path';
|
2
3
|
import mkdirp from 'mkdirp';
|
3
4
|
|
4
5
|
export function getScryptedVolume() {
|
5
|
-
const volumeDir = process.env.SCRYPTED_VOLUME || path.join(
|
6
|
+
const volumeDir = process.env.SCRYPTED_VOLUME || path.join(os.homedir(), '.scrypted', 'volume');
|
6
7
|
return volumeDir;
|
7
8
|
}
|
8
9
|
|
@@ -45,7 +45,9 @@ export class PythonRuntimeWorker extends ChildProcessWorker {
|
|
45
45
|
}
|
46
46
|
}
|
47
47
|
|
48
|
-
|
48
|
+
const pythonPath = os.platform() === 'win32' ? 'py.exe' : 'python3';
|
49
|
+
|
50
|
+
this.worker = child_process.spawn(pythonPath, args, {
|
49
51
|
// stdin, stdout, stderr, peer in, peer out
|
50
52
|
stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'pipe'],
|
51
53
|
env: Object.assign({
|