mirror of
https://github.com/koush/scrypted.git
synced 2026-05-04 21:30:30 +01:00
sdk/server/plugin: python sample
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user