mirror of
https://github.com/koush/scrypted.git
synced 2026-02-03 06:03:27 +00:00
sdk/server/plugin: python sample
This commit is contained in:
1
.npmignore
Normal file
1
.npmignore
Normal file
@@ -0,0 +1 @@
|
||||
__pycache__
|
||||
4
plugins/vscode-python/.gitignore
vendored
Normal file
4
plugins/vscode-python/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.DS_Store
|
||||
out/
|
||||
node_modules/
|
||||
dist/
|
||||
9
plugins/vscode-python/.npmignore
Normal file
9
plugins/vscode-python/.npmignore
Normal file
@@ -0,0 +1,9 @@
|
||||
.DS_Store
|
||||
out/
|
||||
node_modules/
|
||||
*.map
|
||||
fs
|
||||
src
|
||||
.vscode
|
||||
dist/*.js
|
||||
__pycache__
|
||||
30
plugins/vscode-python/.vscode/launch.json
vendored
Normal file
30
plugins/vscode-python/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Scrypted Debugger",
|
||||
"type": "python",
|
||||
"request": "attach",
|
||||
"connect": {
|
||||
"host": "localhost",
|
||||
"port": 10081
|
||||
},
|
||||
"justMyCode": false,
|
||||
"preLaunchTask": "scrypted: deploy+debug",
|
||||
"pathMappings": [
|
||||
{
|
||||
"localRoot": "/Volumes/Dev/scrypted/server/python/",
|
||||
"remoteRoot": "/Volumes/Dev/scrypted/server/python/",
|
||||
},
|
||||
{
|
||||
"localRoot": "${workspaceFolder}/src",
|
||||
"remoteRoot": "${config:scrypted.pythonRemoteRoot}"
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
9
plugins/vscode-python/.vscode/settings.json
vendored
Normal file
9
plugins/vscode-python/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
{
|
||||
"scrypted.debugHost": "127.0.0.1",
|
||||
"scrypted.serverRoot": "/Volumes/Dev/scrypted",
|
||||
"scrypted.pythonRemoteRoot": "${config:scrypted.serverRoot}/server/volume/plugin.zip",
|
||||
"python.analysis.extraPaths": [
|
||||
"./node_modules/@scrypted/sdk/scrypted_python"
|
||||
]
|
||||
}
|
||||
20
plugins/vscode-python/.vscode/tasks.json
vendored
Normal file
20
plugins/vscode-python/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "scrypted: deploy+debug",
|
||||
"type": "shell",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "silent",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"command": "npm run scrypted-vscode-launch ${config:scrypted.debugHost}",
|
||||
},
|
||||
]
|
||||
}
|
||||
15
plugins/vscode-python/README.md
Normal file
15
plugins/vscode-python/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# @scrypted/vscode-python
|
||||
|
||||
## npm commands
|
||||
* npm run scrypted-webpack
|
||||
* npm run scrypted-deploy <ipaddress>
|
||||
* npm run scrypted-debug <ipaddress>
|
||||
|
||||
## scrypted distribution via npm
|
||||
1. Ensure package.json is set up properly for publishing on npm.
|
||||
2. npm publish
|
||||
|
||||
## Visual Studio Code configuration
|
||||
|
||||
* If using a remote server, edit [.vscode/settings.json](blob/master/.vscode/settings.json) to specify the IP Address of the Scrypted server.
|
||||
* Launch Scrypted Debugger from the launch menu.
|
||||
207
plugins/vscode-python/package-lock.json
generated
Normal file
207
plugins/vscode-python/package-lock.json
generated
Normal file
@@ -0,0 +1,207 @@
|
||||
{
|
||||
"name": "@scrypted/vscode-typescript",
|
||||
"version": "0.0.15",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/vscode-typescript",
|
||||
"version": "0.0.15",
|
||||
"dependencies": {
|
||||
"@types/node": "^16.6.1",
|
||||
"axios": "^0.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
}
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.0.65",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.2.2",
|
||||
"@babel/plugin-proposal-class-properties": "^7.4.4",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.2.0",
|
||||
"@babel/plugin-transform-typescript": "^7.15.0",
|
||||
"@babel/polyfill": "^7.2.5",
|
||||
"@babel/preset-env": "^7.2.3",
|
||||
"@babel/preset-typescript": "^7.15.0",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.1",
|
||||
"babel-loader": "^8.0.4",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"babel-template": "^6.26.0",
|
||||
"browserify-buffertools": "^1.0.2",
|
||||
"bytebuffer": "^5.0.1",
|
||||
"chalk": "^2.4.2",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"engine.io-client": "^3.3.2",
|
||||
"event-target-shim": "^5.0.1",
|
||||
"events": "^3.0.0",
|
||||
"long": "^4.0.0",
|
||||
"node-cmd": "^3.0.0",
|
||||
"node-ip": "^0.1.2",
|
||||
"raw-loader": "^1.0.0",
|
||||
"terser": "^3.14.1",
|
||||
"ts-loader": "^5.4.5",
|
||||
"tsconfig-paths-webpack-plugin": "^3.2.0",
|
||||
"typescript": "^4.3.5",
|
||||
"webpack": "^4.28.1",
|
||||
"webpack-cli": "^3.1.2",
|
||||
"webpack-inject-plugin": "^1.0.2"
|
||||
},
|
||||
"bin": {
|
||||
"scrypted-debug": "bin/scrypted-debug.js",
|
||||
"scrypted-deploy": "bin/scrypted-deploy.js",
|
||||
"scrypted-deploy-debug": "bin/scrypted-deploy-debug.js",
|
||||
"scrypted-package-json": "bin/scrypted-package-json.js",
|
||||
"scrypted-readme": "bin/scrypted-readme.js",
|
||||
"scrypted-webpack": "bin/scrypted-webpack.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.13.12",
|
||||
"@types/node": "^16.6.1",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"babel-plugin-minify-dead-code-elimination": "^0.5.1"
|
||||
}
|
||||
},
|
||||
"../sdk": {
|
||||
"extraneous": true
|
||||
},
|
||||
"node_modules/@scrypted/sdk": {
|
||||
"resolved": "../../sdk",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "16.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.6.1.tgz",
|
||||
"integrity": "sha512-Sr7BhXEAer9xyGuCN3Ek9eg9xPviCF2gfu9kTfuU2HkTVAMYSDeX40fvpmo72n5nansg3nsBjuQBrsS28r+NUw=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.19.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz",
|
||||
"integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "1.5.10",
|
||||
"is-buffer": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"dependencies": {
|
||||
"debug": "=3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects/node_modules/debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"node_modules/is-buffer": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
|
||||
"integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": {
|
||||
"version": "file:../../sdk",
|
||||
"requires": {
|
||||
"@babel/core": "^7.2.2",
|
||||
"@babel/plugin-proposal-class-properties": "^7.4.4",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.13.12",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.2.0",
|
||||
"@babel/plugin-transform-typescript": "^7.15.0",
|
||||
"@babel/polyfill": "^7.2.5",
|
||||
"@babel/preset-env": "^7.2.3",
|
||||
"@babel/preset-typescript": "^7.15.0",
|
||||
"@types/node": "^16.6.1",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.1",
|
||||
"babel-loader": "^8.0.4",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"babel-plugin-minify-dead-code-elimination": "^0.5.1",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"babel-template": "^6.26.0",
|
||||
"browserify-buffertools": "^1.0.2",
|
||||
"bytebuffer": "^5.0.1",
|
||||
"chalk": "^2.4.2",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"engine.io-client": "^3.3.2",
|
||||
"event-target-shim": "^5.0.1",
|
||||
"events": "^3.0.0",
|
||||
"long": "^4.0.0",
|
||||
"node-cmd": "^3.0.0",
|
||||
"node-ip": "^0.1.2",
|
||||
"raw-loader": "^1.0.0",
|
||||
"terser": "^3.14.1",
|
||||
"ts-loader": "^5.4.5",
|
||||
"tsconfig-paths-webpack-plugin": "^3.2.0",
|
||||
"typescript": "^4.3.5",
|
||||
"webpack": "^4.28.1",
|
||||
"webpack-cli": "^3.1.2",
|
||||
"webpack-inject-plugin": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "16.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.6.1.tgz",
|
||||
"integrity": "sha512-Sr7BhXEAer9xyGuCN3Ek9eg9xPviCF2gfu9kTfuU2HkTVAMYSDeX40fvpmo72n5nansg3nsBjuQBrsS28r+NUw=="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.19.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz",
|
||||
"integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==",
|
||||
"requires": {
|
||||
"follow-redirects": "1.5.10",
|
||||
"is-buffer": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"requires": {
|
||||
"debug": "=3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
}
|
||||
}
|
||||
},
|
||||
"is-buffer": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
|
||||
"integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw=="
|
||||
}
|
||||
}
|
||||
}
|
||||
30
plugins/vscode-python/package.json
Normal file
30
plugins/vscode-python/package.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "@scrypted/vscode-python",
|
||||
"scripts": {
|
||||
"prepublishOnly": "NODE_ENV=production scrypted-webpack",
|
||||
"prescrypted-vscode-launch": "scrypted-webpack",
|
||||
"scrypted-vscode-launch": "scrypted-deploy-debug",
|
||||
"scrypted-deploy-debug": "scrypted-deploy-debug",
|
||||
"scrypted-debug": "scrypted-debug",
|
||||
"scrypted-deploy": "scrypted-deploy",
|
||||
"scrypted-readme": "scrypted-readme",
|
||||
"scrypted-package-json": "scrypted-package-json",
|
||||
"scrypted-webpack": "scrypted-webpack"
|
||||
},
|
||||
"scrypted": {
|
||||
"name": "Python Light",
|
||||
"runtime": "python",
|
||||
"type": "Light",
|
||||
"interfaces": [
|
||||
"OnOff"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "^16.6.1",
|
||||
"axios": "^0.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk"
|
||||
},
|
||||
"version": "0.0.15"
|
||||
}
|
||||
16
plugins/vscode-python/src/main.py
Normal file
16
plugins/vscode-python/src/main.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from __future__ import annotations
|
||||
import scrypted_sdk
|
||||
|
||||
from scrypted_sdk.types import OnOff
|
||||
|
||||
class PythonLight(scrypted_sdk.ScryptedDeviceBase, OnOff):
|
||||
async def turnOff(self) -> None:
|
||||
print("turned off!")
|
||||
self.on = False
|
||||
|
||||
async def turnOn(self) -> None:
|
||||
print("turned on!")
|
||||
self.on = True
|
||||
|
||||
def create_scrypted_plugin():
|
||||
return PythonLight()
|
||||
4
plugins/vscode-python/src/requirements.example.txt
Normal file
4
plugins/vscode-python/src/requirements.example.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
--extra-index-url https://google-coral.github.io/py-repo/
|
||||
Pillow==8.4.0
|
||||
pycoral==2.0.0
|
||||
tflite-runtime==2.5.0.post1
|
||||
1
sdk/.npmignore
Normal file
1
sdk/.npmignore
Normal file
@@ -0,0 +1 @@
|
||||
__pycache__
|
||||
4
sdk/package-lock.json
generated
4
sdk/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.0.113",
|
||||
"version": "0.0.116",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.0.113",
|
||||
"version": "0.0.116",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.14.5",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.0.113",
|
||||
"version": "0.0.116",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
const e = __non_webpack_require__('canvas');
|
||||
module.exports = e;
|
||||
@@ -1,2 +0,0 @@
|
||||
const e = __non_webpack_require__('@tensorflow-models/coco-ssd');
|
||||
module.exports = e;
|
||||
@@ -1,2 +0,0 @@
|
||||
const e = __non_webpack_require__('serialport');
|
||||
module.exports = e;
|
||||
@@ -1,2 +0,0 @@
|
||||
const e = __non_webpack_require__('@tensorflow/tfjs-core');
|
||||
module.exports = e;
|
||||
@@ -1,2 +0,0 @@
|
||||
const e = __non_webpack_require__('@tensorflow/tfjs-node-gpu');
|
||||
module.exports = e;
|
||||
@@ -1,2 +0,0 @@
|
||||
const e = __non_webpack_require__('@tensorflow/tfjs-node');
|
||||
module.exports = e;
|
||||
@@ -1,2 +0,0 @@
|
||||
const e = __non_webpack_require__('@tensorflow/tfjs');
|
||||
module.exports = e;
|
||||
@@ -1,2 +0,0 @@
|
||||
const e = __non_webpack_require__('zwave-js');
|
||||
module.exports = e;
|
||||
@@ -7,3 +7,4 @@ out
|
||||
scrypted.db.bak
|
||||
.exit
|
||||
.update
|
||||
__pycache__
|
||||
|
||||
3
server/.vscode/settings.json
vendored
3
server/.vscode/settings.json
vendored
@@ -1,2 +1,5 @@
|
||||
{
|
||||
"python.analysis.extraPaths": [
|
||||
"./node_modules/@scrypted/sdk"
|
||||
]
|
||||
}
|
||||
716
server/package-lock.json
generated
716
server/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
"version": "0.0.69",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": "^0.0.111",
|
||||
"@scrypted/sdk": "^0.0.116",
|
||||
"adm-zip": "^0.5.3",
|
||||
"axios": "^0.21.1",
|
||||
"body-parser": "^1.19.0",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
from collections.abc import Mapping
|
||||
from rpc import RpcPeer, readLoop, RpcSerializer
|
||||
from python.rpc import RpcPeer, readLoop, RpcSerializer
|
||||
import asyncio
|
||||
from asyncio.events import AbstractEventLoop
|
||||
import json
|
||||
@@ -8,8 +9,72 @@ import os
|
||||
from typing import TypedDict
|
||||
import base64
|
||||
from os import sys
|
||||
import time
|
||||
import zipfile
|
||||
import subprocess
|
||||
from typing import Any
|
||||
|
||||
more = os.path.join(os.getcwd(), 'node_modules/@scrypted/sdk')
|
||||
sys.path.insert(0, more)
|
||||
import scrypted_python.scrypted_sdk
|
||||
from scrypted_python.scrypted_sdk.types import ScryptedInterfaceProperty
|
||||
|
||||
|
||||
class SystemDeviceState(TypedDict):
|
||||
lastEventTime: int
|
||||
stateTime: int
|
||||
value: any
|
||||
|
||||
class SystemManager(scrypted_python.scrypted_sdk.SystemManager):
|
||||
def __init__(self, api: Any, systemState: Mapping[str, Mapping[str, SystemDeviceState]]) -> None:
|
||||
super().__init__()
|
||||
self.api = api
|
||||
self.systemState = systemState
|
||||
|
||||
class DeviceState(scrypted_python.scrypted_sdk.DeviceState):
|
||||
def __init__(self, id: str, nativeId: str, systemManager: SystemManager, deviceManager: scrypted_python.scrypted_sdk.DeviceManager) -> None:
|
||||
super().__init__()
|
||||
self._id = id
|
||||
self.nativeId = nativeId
|
||||
self.deviceManager = deviceManager
|
||||
self.systemManager = systemManager
|
||||
|
||||
def getScryptedProperty(self, property: str) -> Any:
|
||||
deviceState = getattr(self.systemManager.systemState, self.nativeId, None)
|
||||
if not deviceState:
|
||||
print("missing nativeId id %s" % self.nativeId)
|
||||
return None
|
||||
return getattr(deviceState, property, None)
|
||||
|
||||
def setScryptedProperty(self, property: str, value: Any):
|
||||
if property == ScryptedInterfaceProperty.id.value:
|
||||
raise Exception("id is read only");
|
||||
if property == ScryptedInterfaceProperty.mixins.value:
|
||||
raise Exception("mixins is read only");
|
||||
if property == ScryptedInterfaceProperty.interfaces.value:
|
||||
raise Exception("interfaces is a read only post-mixin computed property, use providedInterfaces");
|
||||
|
||||
now = int(time.time() * 1000)
|
||||
self.systemManager.systemState[self._id][property] = {
|
||||
"lastEventTime": now,
|
||||
"stateTime": now,
|
||||
"value": value
|
||||
}
|
||||
|
||||
self.systemManager.api.setState(self.nativeId, property, value)
|
||||
|
||||
|
||||
class DeviceManager(scrypted_python.scrypted_sdk.DeviceManager):
|
||||
def __init__(self, nativeIds: Mapping[str, DeviceStorage], systemManager: SystemManager) -> None:
|
||||
super().__init__()
|
||||
self.nativeIds = nativeIds
|
||||
self.systemManager = systemManager
|
||||
|
||||
|
||||
def getDeviceState(self, nativeId: str) -> DeviceState:
|
||||
id = self.nativeIds[nativeId].id
|
||||
return DeviceState(id, nativeId, self.systemManager, self)
|
||||
|
||||
|
||||
class BufferSerializer(RpcSerializer):
|
||||
def serialize(self, value):
|
||||
@@ -19,12 +84,6 @@ class BufferSerializer(RpcSerializer):
|
||||
return base64.b64decode(value)
|
||||
|
||||
|
||||
class SystemDeviceState(TypedDict):
|
||||
lastEventTime: int
|
||||
stateTime: int
|
||||
value: any
|
||||
|
||||
|
||||
class DeviceStorage:
|
||||
id: str
|
||||
nativeId: str
|
||||
@@ -48,31 +107,38 @@ class PluginRemote:
|
||||
f.close()
|
||||
|
||||
zip = zipfile.ZipFile(zipPath)
|
||||
requirements = zip.open('requirements.txt').read()
|
||||
|
||||
python_modules = os.path.join(os.environ.get('SCRYPTED_PLUGIN_VOLUME'), 'python', 'modules')
|
||||
if not os.path.exists(python_modules):
|
||||
os.makedirs(python_modules)
|
||||
requirementstxt = os.path.join(python_modules, 'requirements.txt')
|
||||
|
||||
f = open(requirementstxt, 'wb')
|
||||
f.write(requirements)
|
||||
f.close()
|
||||
if 'requirements.txt' in zip.namelist():
|
||||
requirements = zip.open('requirements.txt').read()
|
||||
|
||||
# os.system('pip install -r %s --target %s' % (requirementstxt, python_modules))
|
||||
result = subprocess.check_output(['pip', 'install', '-r', requirementstxt, '--target', python_modules], stderr=subprocess.STDOUT, text=True)
|
||||
print(result)
|
||||
requirementstxt = os.path.join(python_modules, 'requirements.txt')
|
||||
|
||||
f = open(requirementstxt, 'wb')
|
||||
f.write(requirements)
|
||||
f.close()
|
||||
|
||||
# os.system('pip install -r %s --target %s' % (requirementstxt, python_modules))
|
||||
result = subprocess.check_output(['pip', 'install', '-r', requirementstxt, '--target', python_modules], stderr=subprocess.STDOUT, text=True)
|
||||
print(result)
|
||||
|
||||
sys.path.insert(0, zipPath)
|
||||
sys.path.insert(0, python_modules)
|
||||
from main import plugin_main
|
||||
plugin_main()
|
||||
from scrypted_sdk import sdk_init # type: ignore
|
||||
self.systemManager = SystemManager(self.api, self.systemState)
|
||||
self.deviceManager = DeviceManager(self.nativeIds, self.systemManager)
|
||||
sdk_init(self.systemManager, self.deviceManager)
|
||||
from main import create_scrypted_plugin # type: ignore
|
||||
return create_scrypted_plugin()
|
||||
|
||||
async def setSystemState(self, state):
|
||||
self.systemState = state
|
||||
|
||||
async def setNativeId(self, nativeId, id, storage):
|
||||
if nativeId:
|
||||
if id:
|
||||
ds = DeviceStorage()
|
||||
ds.id = id
|
||||
ds.storage = storage
|
||||
|
||||
@@ -96,12 +96,6 @@ class EndpointManagerImpl implements EndpointManager {
|
||||
}
|
||||
}
|
||||
|
||||
const disallowedScryptedDeviceProperties = new Set<string>([
|
||||
ScryptedInterfaceProperty.id,
|
||||
ScryptedInterfaceProperty.interfaces,
|
||||
ScryptedInterfaceProperty.mixins,
|
||||
]);
|
||||
|
||||
class DeviceStateProxyHandler implements ProxyHandler<any> {
|
||||
constructor(public deviceManager: DeviceManagerImpl, public id: string,
|
||||
public setState: (property: string, value: any) => Promise<void>) {
|
||||
|
||||
Reference in New Issue
Block a user