Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update SystemManager.listen and listenDevice logic #953

Closed
wants to merge 16 commits into from
24 changes: 14 additions & 10 deletions packages/python-client/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __init__(self, loop: asyncio.AbstractEventLoop):
def on_message(data):
self.read_queue.put_nowait(data)

asyncio.run_coroutine_threadsafe(self.send_loop(), self.loop)
asyncio.create_task(self.send_loop())

async def read(self):
return await self.read_queue.get()
Expand All @@ -50,7 +50,7 @@ async def send():
except Exception as e:
reject(e)

asyncio.run_coroutine_threadsafe(send(), self.loop)
asyncio.create_task(send())

def writeJSON(self, json, reject):
return self.writeBuffer(json, reject)
Expand Down Expand Up @@ -90,9 +90,7 @@ async def connect_scrypted_client(
)

ret = asyncio.Future[ScryptedStatic](loop=transport.loop)
peer, peerReadLoop = await rpc_reader.prepare_peer_readloop(
transport.loop, transport
)
peer, peerReadLoop = await rpc_reader.prepare_peer_readloop(transport)
peer.params["print"] = print

def callback(api, pluginId, hostInfo):
Expand All @@ -115,13 +113,13 @@ async def resolve():
sdk.mediaManager = MediaManager(await api.getMediaManager())
ret.set_result(sdk)

asyncio.run_coroutine_threadsafe(resolve(), transport.loop)
asyncio.create_task(resolve())

remote.setSystemState = remoteSetSystemState
return remote

peer.params["getRemote"] = callback
asyncio.run_coroutine_threadsafe(peerReadLoop(), transport.loop)
asyncio.create_task(peerReadLoop())

sdk = await ret
return sdk
Expand All @@ -131,14 +129,21 @@ async def main():
transport = EioRpcTransport(asyncio.get_event_loop())
sdk = await connect_scrypted_client(
transport,
"https://localhost:10443",
os.environ.get("SCRYPTED_URL", "https://localhost:10443"),
os.environ["SCRYPTED_USERNAME"],
os.environ["SCRYPTED_PASSWORD"],
)

for id in sdk.systemManager.getSystemState():
device = sdk.systemManager.getDeviceById(id)
if ScryptedInterface.Camera not in device.interfaces:
continue
print(device.name)
print(device.id)
print(device.interfaces)
# print(device.providedInterfaces)
stream = await device.getVideoStreamOptions()
print(stream)
if ScryptedInterface.OnOff.value in device.interfaces:
print(f"OnOff: device is {device.on}")

Expand All @@ -147,5 +152,4 @@ async def main():


loop = asyncio.new_event_loop()
asyncio.run_coroutine_threadsafe(main(), loop)
loop.run_forever()
loop.run_until_complete(main())
117 changes: 109 additions & 8 deletions sdk/types/scrypted_python/scrypted_sdk/other.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
from __future__ import annotations

from enum import Enum
from typing import AbstractSet, Any, Callable, Literal, Union
from typing import AbstractSet, Any, Callable, Literal, TYPE_CHECKING

try:
from typing import TypedDict
except:
except ImportError:
from typing_extensions import TypedDict


if TYPE_CHECKING:
from .types import (
DeviceManifest,
Device,
EventListenerOptions,
EventListenerRegister,
MediaManager,
ScryptedDevice,
ScryptedInterfaceProperty,
)

SettingValue = str
EventListener = Callable[[Any, Any, Any], None]
DeviceEventListener = Callable[[Any, Any], None]
VibratePattern = list[int]


Expand Down Expand Up @@ -42,21 +56,18 @@ class RTCSessionDescriptionInit(TypedDict):


class NotificationAction(TypedDict, total=False):

action: str
title: str
icon: str # optional


class NotificationDirection(str, Enum):

auto = "auto"
ltr = "ltr"
rtl = "rtl"


class WebSocket:

CLOSED: int
CLOSING: int
CONNECTING: int
Expand All @@ -73,7 +84,9 @@ class WebSocket:
readyState: int
url: str

def addEventListener(self, type: str, listener: Callable[[dict], None], options: dict = None) -> None:
def addEventListener(
self, type: str, listener: Callable[[dict], None], options: dict = None
) -> None:
pass

def close(self, code: int = None, reason: str = None) -> None:
Expand All @@ -82,8 +95,96 @@ def close(self, code: int = None, reason: str = None) -> None:
def dispatchEvent(self, event: dict) -> bool:
pass

def removeEventListener(self, type: str, listener: Callable[[dict], None], options: dict = None) -> None:
def removeEventListener(
self, type: str, listener: Callable[[dict], None], options: dict = None
) -> None:
pass

def send(self, data: str | bytes | bytearray | int | float | bool) -> None:
pass
pass


class ScryptedInterfaceDescriptor:
name: str
properties: list[str]
methods: list[str]


class PluginLogger:
async def log(self, level: str, message: str) -> None:
pass

async def clear(self) -> None:
pass

async def clearAlert(self, message: str) -> None:
pass

async def clearAlerts(self) -> None:
pass


class PluginAPI:
async def setState(self, nativeId: str | None, key: str, value: Any) -> None:
pass

async def onDevicesChanged(self, deviceManifest: "DeviceManifest") -> None:
pass

async def onDeviceDiscovered(self, device: "Device") -> None:
pass

async def onDeviceEvent(
self, nativeId: str | None, eventInterface: str, eventData: Any
) -> None:
pass

async def onMixinEvent(
self, id: str, nativeId: str | None, eventInterface: str, eventData: Any
) -> None:
pass

async def onDeviceRemoved(self, nativeId: str) -> None:
pass

async def setStorage(self, nativeId: str, storage: dict[str, Any]) -> None:
pass

async def getDeviceById(self, id: str) -> "ScryptedDevice":
pass

async def setDeviceProperty(
self, id: str, property: "ScryptedInterfaceProperty", value: Any
) -> None:
pass

async def removeDevice(self, id: str) -> None:
pass

async def listen(self, callback: EventListener) -> "EventListenerRegister":
pass

async def listenDevice(
self,
id: str,
event: str | "EventListenerOptions",
callback: DeviceEventListener,
) -> "EventListenerRegister":
pass

async def getLogger(self, nativeId: str | None) -> PluginLogger:
pass

async def getComponent(self, id: str) -> Any:
pass

async def getMediaManager(self) -> "MediaManager":
pass

async def requestRestart(self) -> None:
pass

async def setScryptedInterfaceDescriptors(
self, typesVersion: str, descriptors: dict[str, ScryptedInterfaceDescriptor]
) -> None:
pass
2 changes: 1 addition & 1 deletion sdk/types/scrypted_python/scrypted_sdk/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3060,7 +3060,7 @@ def applicationInfo(self, value: LauncherApplicationInfo):
class EventListenerRegister:
"""Returned when an event listener is attached to an EventEmitter. Call removeListener to unregister from events."""

def removeListener(self) -> None:
async def removeListener(self) -> None:
pass


Expand Down
2 changes: 1 addition & 1 deletion sdk/types/src/types.input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export interface EventDetails {
* @category Core Reference
*/
export interface EventListenerRegister {
removeListener(): void;
removeListener(): Promise<void>;

}

Expand Down
Loading