@camera.ui/server 0.0.6 → 0.0.8
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.
- package/dist/interface/assets/{@tanstack-BqH4GyO-.js → @tanstack-B-9PO-kT.js} +1 -1
- package/dist/interface/assets/{@vee-validate-DCBdnGo-.js → @vee-validate-D_G0ehOl.js} +1 -1
- package/dist/interface/assets/{@vue-C7-KaDG4.js → @vue-C10tA4b9.js} +6 -6
- package/dist/interface/assets/{@vueform-arggO0eF.js → @vueform-Bj73kRPS.js} +1 -1
- package/dist/interface/assets/{@vueuse-C3WMTDqL.js → @vueuse-BPeqNGoM.js} +1 -1
- package/dist/interface/assets/Account-MEaGtu1D.js +1 -0
- package/dist/interface/assets/Adminpanel-D1ycltxf.js +1 -0
- package/dist/interface/assets/Appearance-Jlzp_P21.js +1 -0
- package/dist/interface/assets/Backup-1-ju9NDo.js +1 -0
- package/dist/interface/assets/Camera-BOu5dUel.js +1 -0
- package/dist/interface/assets/Cameras-C7eUXdZk.js +1 -0
- package/dist/interface/assets/Cameras-tmTzi1M6.css +1 -0
- package/dist/interface/assets/Camview-CEgwGCGR.js +1 -0
- package/dist/interface/assets/{Camview-vUAs5YHU.css → Camview-CWTrsoY0.css} +1 -1
- package/dist/interface/assets/Config-Dt-etQ3h.js +1 -0
- package/dist/interface/assets/{Console-Caz7y-T0.js → Console-FCve5CKy.js} +2 -2
- package/dist/interface/assets/FirstSteps-DLkKDSe9.js +1 -0
- package/dist/interface/assets/{NewCamera-B9t-0NCc.js → NewCamera-Cc1X79Ns.js} +2 -2
- package/dist/interface/assets/Plugin-CnQjafMC.js +1 -0
- package/dist/interface/assets/{Plugin-BSHKKjrl.css → Plugin-DzKKCoqQ.css} +1 -1
- package/dist/interface/assets/Plugins-B8gCgxOx.css +1 -0
- package/dist/interface/assets/Plugins-CwyUdMlv.js +1 -0
- package/dist/interface/assets/Recordings-Boeev1lV.js +1 -0
- package/dist/interface/assets/Recordings-D5ta7AYS.js +1 -0
- package/dist/interface/assets/Settings-Cvm2jnBr.js +1 -0
- package/dist/interface/assets/System-fHQ7XKri.js +1 -0
- package/dist/interface/assets/User-5o1VKizc.js +1 -0
- package/dist/interface/assets/VConfigEditor.vue_vue_type_script_setup_true_lang-C_95ELTZ.js +2 -0
- package/dist/interface/assets/VConsole-BHy92Ws0.js +1 -0
- package/dist/interface/assets/VConsole-MV9pQtJj.css +1 -0
- package/dist/interface/assets/{VPlayer-YdRn97Bs.js → VPlayer-LX5HGLrY.js} +1 -1
- package/dist/interface/assets/{VPluginCard--3bx6UJb.js → VPluginCard-CFpg0LM4.js} +2 -2
- package/dist/interface/assets/VPluginCard-Fl0AYmnF.css +1 -0
- package/dist/interface/assets/main-BCWSiwnj.js +9 -0
- package/dist/interface/assets/{main-B3IVLctZ.css → main-CQNVVncO.css} +1 -1
- package/dist/interface/assets/{pinia-D8MtiGcH.js → pinia-CitQ5b66.js} +2 -2
- package/dist/interface/assets/{plugins-Bf03y242.js → plugins-D80RNVmI.js} +1 -1
- package/dist/interface/assets/qrcode-SHonoxyK.js +8 -0
- package/dist/interface/assets/{system-BONnDA4y.js → system-CS_ZOs3_.js} +1 -1
- package/dist/interface/assets/{ui-CNpIJotI.js → ui-CHKoHLl-.js} +1 -1
- package/dist/interface/assets/{v-calendar-uh0aTGqP.js → v-calendar-C-8W4FeM.js} +1 -1
- package/dist/interface/assets/{vee-validate-D3FqbChK.js → vee-validate-Ck3I2guh.js} +1 -1
- package/dist/interface/assets/{vue-i18n-1AU8MPys.js → vue-i18n-DuCDz9TJ.js} +1 -1
- package/dist/interface/assets/{vue-inline-svg-2DDwYW6V.js → vue-inline-svg-C2gR6nRD.js} +1 -1
- package/dist/interface/assets/{vue-router-DfeQ8s4I.js → vue-router-OPGDMnws.js} +1 -1
- package/dist/interface/assets/{vue3-dnd-BwxcSU9Z.js → vue3-dnd-Hf295yge.js} +1 -1
- package/dist/interface/assets/{vue3-toastify-Ul-rf53I.js → vue3-toastify-DQr2dOCx.js} +1 -1
- package/dist/interface/assets/vuetify-CrcT8VHB.js +5 -0
- package/dist/interface/index.html +14 -15
- package/dist/interface/sw.js +1 -1
- package/dist/server/bin/cui-service.d.ts +1 -0
- package/dist/server/bin/cui-service.js +41 -9
- package/dist/server/bin/cui-service.js.map +1 -1
- package/dist/server/package.json +8 -7
- package/dist/server/requirements.txt +2 -3
- package/dist/server/src/api/controllers/cameras.controller.js +2 -2
- package/dist/server/src/api/controllers/cameras.controller.js.map +1 -1
- package/dist/server/src/api/controllers/plugins.controller.js +7 -6
- package/dist/server/src/api/controllers/plugins.controller.js.map +1 -1
- package/dist/server/src/api/go2rtc/api/streams.d.ts +4 -4
- package/dist/server/src/api/go2rtc/api/streams.js +2 -24
- package/dist/server/src/api/go2rtc/api/streams.js.map +1 -1
- package/dist/server/src/api/go2rtc/types.d.ts +6 -2
- package/dist/server/src/api/schemas/go2rtc.schema.d.ts +5 -5
- package/dist/server/src/api/services/cameras.service.d.ts +6 -5
- package/dist/server/src/api/services/cameras.service.js +72 -59
- package/dist/server/src/api/services/cameras.service.js.map +1 -1
- package/dist/server/src/api/services/plugins.service.js +11 -13
- package/dist/server/src/api/services/plugins.service.js.map +1 -1
- package/dist/server/src/api.d.ts +2 -2
- package/dist/server/src/camera/controller.d.ts +9 -4
- package/dist/server/src/camera/controller.js +21 -7
- package/dist/server/src/camera/controller.js.map +1 -1
- package/dist/server/src/camera/device.d.ts +15 -3
- package/dist/server/src/camera/device.js.map +1 -1
- package/dist/server/src/camera/index.d.ts +18 -39
- package/dist/server/src/camera/index.js +137 -165
- package/dist/server/src/camera/index.js.map +1 -1
- package/dist/server/src/camera/interfaces/camera.d.ts +0 -1
- package/dist/server/src/camera/interfaces/camera.js +0 -8
- package/dist/server/src/camera/interfaces/camera.js.map +1 -1
- package/dist/server/src/camera/streaming/werift-session.d.ts +10 -1
- package/dist/server/src/camera/streaming/werift-session.js +16 -1
- package/dist/server/src/camera/streaming/werift-session.js.map +1 -1
- package/dist/server/src/camera/types.d.ts +0 -1
- package/dist/server/src/camera/types.js.map +1 -1
- package/dist/server/src/camera/videoFrame.d.ts +3 -3
- package/dist/server/src/camera/videoFrame.js +6 -7
- package/dist/server/src/camera/videoFrame.js.map +1 -1
- package/dist/server/src/decoder/types.d.ts +4 -9
- package/dist/server/src/decoder/worker.d.ts +3 -5
- package/dist/server/src/decoder/worker.js +40 -64
- package/dist/server/src/decoder/worker.js.map +1 -1
- package/dist/server/src/go2rtc/index.js +1 -1
- package/dist/server/src/go2rtc/index.js.map +1 -1
- package/dist/server/src/index.d.ts +3 -3
- package/dist/server/src/main.js +1 -2
- package/dist/server/src/main.js.map +1 -1
- package/dist/server/src/nats/connection.d.ts +17 -0
- package/dist/server/src/nats/connection.js +66 -0
- package/dist/server/src/nats/connection.js.map +1 -0
- package/dist/server/src/nats/error.d.ts +9 -0
- package/dist/server/src/nats/error.js +11 -0
- package/dist/server/src/nats/error.js.map +1 -0
- package/dist/server/src/nats/index.d.ts +6 -4
- package/dist/server/src/nats/index.js +22 -17
- package/dist/server/src/nats/index.js.map +1 -1
- package/dist/server/src/nats/messageQueue.d.ts +7 -4
- package/dist/server/src/nats/messageQueue.js +43 -59
- package/dist/server/src/nats/messageQueue.js.map +1 -1
- package/dist/server/src/nats/proxy/cameraDevice.js +19 -24
- package/dist/server/src/nats/proxy/cameraDevice.js.map +1 -1
- package/dist/server/src/nats/proxy/deviceManager.d.ts +2 -2
- package/dist/server/src/nats/proxy/deviceManager.js +4 -14
- package/dist/server/src/nats/proxy/deviceManager.js.map +1 -1
- package/dist/server/src/nats/server.js +4 -10
- package/dist/server/src/nats/server.js.map +1 -1
- package/dist/server/src/nats/subscription.d.ts +12 -0
- package/dist/server/src/nats/subscription.js +21 -0
- package/dist/server/src/nats/subscription.js.map +1 -0
- package/dist/server/src/nats/types.d.ts +25 -40
- package/dist/server/src/nats/types.js +1 -10
- package/dist/server/src/nats/types.js.map +1 -1
- package/dist/server/src/nats/utils.d.ts +2 -4
- package/dist/server/src/nats/utils.js +3 -3
- package/dist/server/src/nats/utils.js.map +1 -1
- package/dist/server/src/plugins/index.d.ts +3 -5
- package/dist/server/src/plugins/index.js +54 -141
- package/dist/server/src/plugins/index.js.map +1 -1
- package/dist/server/src/plugins/plugin.d.ts +4 -13
- package/dist/server/src/plugins/plugin.js +40 -90
- package/dist/server/src/plugins/plugin.js.map +1 -1
- package/dist/server/src/plugins/types.d.ts +4 -0
- package/dist/server/src/plugins/types.js.map +1 -1
- package/dist/server/src/plugins/worker.d.ts +1 -1
- package/dist/server/src/plugins/worker.js +52 -66
- package/dist/server/src/plugins/worker.js.map +1 -1
- package/dist/server/src/polyglot/node/decoder/child.js +87 -159
- package/dist/server/src/polyglot/node/decoder/child.js.map +1 -1
- package/dist/server/src/polyglot/node/decoder/imageUtils.d.ts +1 -1
- package/dist/server/src/polyglot/node/plugins/cameraStorage.d.ts +2 -2
- package/dist/server/src/polyglot/node/plugins/cameraStorage.js.map +1 -1
- package/dist/server/src/polyglot/node/plugins/child.d.ts +1 -1
- package/dist/server/src/polyglot/node/plugins/child.js +34 -60
- package/dist/server/src/polyglot/node/plugins/child.js.map +1 -1
- package/dist/server/src/polyglot/node/plugins/{config.js → configService.js} +1 -1
- package/dist/server/src/polyglot/node/plugins/configService.js.map +1 -0
- package/dist/server/src/polyglot/node/plugins/{api.d.ts → pluginApi.d.ts} +9 -12
- package/dist/server/src/polyglot/node/plugins/pluginApi.js +34 -0
- package/dist/server/src/polyglot/node/plugins/pluginApi.js.map +1 -0
- package/dist/server/src/polyglot/node/plugins/{logger.d.ts → pluginLogger.d.ts} +2 -0
- package/dist/server/src/polyglot/node/plugins/pluginLogger.js +89 -0
- package/dist/server/src/polyglot/node/plugins/pluginLogger.js.map +1 -0
- package/dist/server/src/polyglot/node/plugins/proxy/cameraDevice.d.ts +8 -11
- package/dist/server/src/polyglot/node/plugins/proxy/cameraDevice.js +67 -129
- package/dist/server/src/polyglot/node/plugins/proxy/cameraDevice.js.map +1 -1
- package/dist/server/src/polyglot/node/plugins/proxy/deviceManager.d.ts +6 -8
- package/dist/server/src/polyglot/node/plugins/proxy/deviceManager.js +15 -43
- package/dist/server/src/polyglot/node/plugins/proxy/deviceManager.js.map +1 -1
- package/dist/server/src/polyglot/node/plugins/storageController.d.ts +2 -2
- package/dist/server/src/polyglot/node/plugins/storageController.js.map +1 -1
- package/dist/server/src/polyglot/python/camera/interfaces/camera.py +0 -6
- package/dist/server/src/polyglot/python/camera/video_frame.py +10 -18
- package/dist/server/src/polyglot/python/camera_ui_types/__init__.py +1 -5
- package/dist/server/src/polyglot/python/decoder/child.py +102 -161
- package/dist/server/src/polyglot/python/plugins/camera_storage.py +10 -23
- package/dist/server/src/polyglot/python/plugins/child.py +35 -60
- package/dist/server/src/polyglot/python/plugins/{proxy/message_queue.py → message_queue.py} +50 -81
- package/dist/server/src/polyglot/python/plugins/plugin_api.py +13 -21
- package/dist/server/src/polyglot/python/plugins/proxy/camera_device.py +90 -173
- package/dist/server/src/polyglot/python/plugins/proxy/device_manager.py +25 -64
- package/dist/server/src/polyglot/python/plugins/storage_controller.py +3 -4
- package/dist/server/src/polyglot/python/utilities/connection.py +86 -0
- package/dist/server/src/polyglot/python/utilities/object_path.py +12 -4
- package/dist/server/src/polyglot/python/utilities/subscriptions.py +20 -0
- package/dist/server/src/polyglot/python/utilities/task.py +11 -1
- package/dist/server/src/services/config/index.js +4 -2
- package/dist/server/src/services/config/index.js.map +1 -1
- package/dist/server/src/services/logger/index.js +11 -8
- package/dist/server/src/services/logger/index.js.map +1 -1
- package/dist/server/src/utils/ffmpeg.d.ts +2 -0
- package/dist/server/src/{decoder → utils}/ffmpeg.js +2 -2
- package/dist/server/src/utils/ffmpeg.js.map +1 -0
- package/dist/server/src/utils/pythonInstaller.d.ts +1 -1
- package/dist/server/src/utils/pythonInstaller.js +10 -4
- package/dist/server/src/utils/pythonInstaller.js.map +1 -1
- package/dist/server/src/utils/reader.js.map +1 -0
- package/dist/server/src/utils/subscribed.d.ts +4 -4
- package/dist/server/src/utils/subscribed.js.map +1 -1
- package/package.json +8 -7
- package/dist/interface/assets/@camera.ui-2NVnv26v.js +0 -8
- package/dist/interface/assets/Account-gJpkf0nE.js +0 -1
- package/dist/interface/assets/Adminpanel-Bge9nu5N.js +0 -1
- package/dist/interface/assets/Appearance-D22q-X_I.js +0 -1
- package/dist/interface/assets/Backup-pJm6s10G.js +0 -1
- package/dist/interface/assets/Camera-BgO2yRjb.js +0 -1
- package/dist/interface/assets/Cameras-BM3vSM_R.css +0 -1
- package/dist/interface/assets/Cameras-DjeKruR_.js +0 -1
- package/dist/interface/assets/Camview-DfzlprzN.js +0 -1
- package/dist/interface/assets/Config-BKIOIkjC.js +0 -1
- package/dist/interface/assets/FirstSteps-mQK4XFTs.js +0 -1
- package/dist/interface/assets/Plugin-Di_bBsg-.js +0 -1
- package/dist/interface/assets/Plugins-BsMITags.css +0 -1
- package/dist/interface/assets/Plugins-DhmzMNuO.js +0 -1
- package/dist/interface/assets/Recordings-Bu53bSBp.js +0 -1
- package/dist/interface/assets/Recordings-XY20w8yp.js +0 -1
- package/dist/interface/assets/Settings-gGRBRVST.js +0 -1
- package/dist/interface/assets/System-ZDrcLNk0.js +0 -1
- package/dist/interface/assets/User-D4vEhhzi.js +0 -1
- package/dist/interface/assets/VConfigEditor.vue_vue_type_script_setup_true_lang-CXFI-IeE.js +0 -2
- package/dist/interface/assets/VConsole-BHo3xprq.js +0 -1
- package/dist/interface/assets/VConsole-f-nUkOuD.css +0 -1
- package/dist/interface/assets/VPluginCard-BJYMuCLk.css +0 -1
- package/dist/interface/assets/encode-utf8-Cn5aGd7v.js +0 -1
- package/dist/interface/assets/main-C4rYiRNz.js +0 -2
- package/dist/interface/assets/qrcode-CGiDONbL.js +0 -8
- package/dist/interface/assets/vuetify-_-Oqac3B.js +0 -5
- package/dist/server/src/decoder/ffmpeg.d.ts +0 -2
- package/dist/server/src/decoder/ffmpeg.js.map +0 -1
- package/dist/server/src/nats/proxy/index.d.ts +0 -2
- package/dist/server/src/nats/proxy/index.js +0 -3
- package/dist/server/src/nats/proxy/index.js.map +0 -1
- package/dist/server/src/polyglot/node/decoder/reader.js.map +0 -1
- package/dist/server/src/polyglot/node/plugins/api.js +0 -34
- package/dist/server/src/polyglot/node/plugins/api.js.map +0 -1
- package/dist/server/src/polyglot/node/plugins/config.js.map +0 -1
- package/dist/server/src/polyglot/node/plugins/logger.js +0 -128
- package/dist/server/src/polyglot/node/plugins/logger.js.map +0 -1
- package/dist/server/src/polyglot/node/plugins/proxy/index.d.ts +0 -2
- package/dist/server/src/polyglot/node/plugins/proxy/index.js +0 -3
- package/dist/server/src/polyglot/node/plugins/proxy/index.js.map +0 -1
- package/dist/server/src/polyglot/node/plugins/proxy/messageQueue.d.ts +0 -20
- package/dist/server/src/polyglot/node/plugins/proxy/messageQueue.js +0 -152
- package/dist/server/src/polyglot/node/plugins/proxy/messageQueue.js.map +0 -1
- /package/dist/server/src/polyglot/node/plugins/{config.d.ts → configService.d.ts} +0 -0
- /package/dist/server/src/polyglot/python/plugins/{logger.py → plugin_logger.py} +0 -0
- /package/dist/server/src/{polyglot/node/decoder → utils}/reader.d.ts +0 -0
- /package/dist/server/src/{polyglot/node/decoder → utils}/reader.js +0 -0
|
@@ -9,7 +9,6 @@ from typing import Any, Optional, Union, cast
|
|
|
9
9
|
from uuid import uuid4
|
|
10
10
|
|
|
11
11
|
import aiohttp
|
|
12
|
-
import nats
|
|
13
12
|
from cachetools import LRUCache, cached
|
|
14
13
|
from camera.polygon import are_motion_detections_valid, are_object_detections_valid
|
|
15
14
|
from camera.video_frame import MotionFrame, VideoFrame
|
|
@@ -55,13 +54,12 @@ from camera_ui_types import (
|
|
|
55
54
|
StateNames,
|
|
56
55
|
StateValue,
|
|
57
56
|
)
|
|
58
|
-
from decoder.typings import PingMessage, PongMessage, SignalingRequest, SignalingResponse
|
|
57
|
+
from decoder.typings import AuthConfig, PingMessage, PongMessage, SignalingRequest, SignalingResponse
|
|
59
58
|
from deepdiff import DeepDiff
|
|
60
|
-
from
|
|
61
|
-
from nats.aio.client import Client as NatsConnection
|
|
59
|
+
from message_queue import MessageQueue
|
|
62
60
|
from nats.aio.msg import Msg
|
|
63
|
-
from nats.aio.subscription import Subscription
|
|
64
61
|
from plugin_api import PluginAPI
|
|
62
|
+
from plugin_logger import PluginLogger
|
|
65
63
|
from reactivex import Observable
|
|
66
64
|
from reactivex import operators as ops
|
|
67
65
|
from reactivex.subject.behaviorsubject import BehaviorSubject
|
|
@@ -74,11 +72,11 @@ from typings import (
|
|
|
74
72
|
PluginInfo,
|
|
75
73
|
ProxyMessageStructure,
|
|
76
74
|
)
|
|
75
|
+
from utilities.connection import ProxyConnection
|
|
77
76
|
from utilities.packer import pack, unpack
|
|
77
|
+
from utilities.subscriptions import ProxySubscription
|
|
78
78
|
from utilities.task import TaskSet
|
|
79
79
|
|
|
80
|
-
from .message_queue import ClientMessageQueue
|
|
81
|
-
|
|
82
80
|
|
|
83
81
|
class CameraSource:
|
|
84
82
|
def __init__(self, source: CameraInput, parent: Any):
|
|
@@ -110,7 +108,7 @@ class CameraDeviceProxy:
|
|
|
110
108
|
camera: Camera,
|
|
111
109
|
plugin: PluginInfo,
|
|
112
110
|
proxy_endpoints: list[str],
|
|
113
|
-
auth:
|
|
111
|
+
auth: AuthConfig,
|
|
114
112
|
):
|
|
115
113
|
self.snapshot_cache = LRUCache(maxsize=100)
|
|
116
114
|
self.camera_subject = BehaviorSubject(camera)
|
|
@@ -172,8 +170,8 @@ class CameraDeviceProxy:
|
|
|
172
170
|
from camera.interfaces.ptz import CameraPTZInterface
|
|
173
171
|
|
|
174
172
|
self.cameraDelegate = CameraInterface(self, logger)
|
|
175
|
-
self.prebufferDelegate = CameraPrebufferInterface(self, logger)
|
|
176
173
|
self.ptzDelegate = CameraPTZInterface(self, logger)
|
|
174
|
+
self.prebufferDelegate = CameraPrebufferInterface(self, logger)
|
|
177
175
|
|
|
178
176
|
self.subject = f"{self.plugin['id']}.camera.{self.id}"
|
|
179
177
|
self.camera_subscriber_subject = f"{self.id}.camera"
|
|
@@ -183,21 +181,21 @@ class CameraDeviceProxy:
|
|
|
183
181
|
self.signaling_subject = f"{self.plugin['id']}.camera.{self.id}.signaling"
|
|
184
182
|
self.signaling_target_subject = f"{self.id}.frameGenerator.signaling"
|
|
185
183
|
|
|
186
|
-
self.publisher: Optional[
|
|
187
|
-
self.camera_publisher: Optional[
|
|
188
|
-
self.frame_publisher: Optional[
|
|
189
|
-
self.motion_frame_publisher: Optional[
|
|
190
|
-
self.signaling_publisher: Optional[
|
|
184
|
+
self.publisher: Optional[ProxyConnection] = None
|
|
185
|
+
self.camera_publisher: Optional[ProxyConnection] = None
|
|
186
|
+
self.frame_publisher: Optional[ProxyConnection] = None
|
|
187
|
+
self.motion_frame_publisher: Optional[ProxyConnection] = None
|
|
188
|
+
self.signaling_publisher: Optional[ProxyConnection] = None
|
|
191
189
|
|
|
192
|
-
self.subscriber: Optional[
|
|
193
|
-
self.camera_subscriber: Optional[
|
|
194
|
-
self.camera_plugin_subscriber: Optional[
|
|
195
|
-
self.signaling_subscriber: Optional[
|
|
196
|
-
self.frame_subscriber: Optional[
|
|
197
|
-
self.motion_frame_subscriber: Optional[
|
|
190
|
+
self.subscriber: Optional[ProxySubscription] = None
|
|
191
|
+
self.camera_subscriber: Optional[ProxySubscription] = None
|
|
192
|
+
self.camera_plugin_subscriber: Optional[ProxySubscription] = None
|
|
193
|
+
self.signaling_subscriber: Optional[ProxySubscription] = None
|
|
194
|
+
self.frame_subscriber: Optional[ProxySubscription] = None
|
|
195
|
+
self.motion_frame_subscriber: Optional[ProxySubscription] = None
|
|
198
196
|
|
|
199
197
|
self.tasks: TaskSet = TaskSet(f"{self.plugin['name']} - {self.name} - CameraDeviceProxy")
|
|
200
|
-
self.message_queue: Optional[
|
|
198
|
+
self.message_queue: Optional[MessageQueue] = None
|
|
201
199
|
self.active_requests: set[str] = set()
|
|
202
200
|
self.active_motion_requests = 0
|
|
203
201
|
|
|
@@ -321,98 +319,53 @@ class CameraDeviceProxy:
|
|
|
321
319
|
def low_resolution_source(self) -> Optional[CameraSource]:
|
|
322
320
|
return next(source for source in self.sources if "low-resolution" in source.roles)
|
|
323
321
|
|
|
322
|
+
@property
|
|
323
|
+
def ptz(self) -> CameraPTZDelegate:
|
|
324
|
+
return self.ptzDelegate
|
|
325
|
+
|
|
324
326
|
async def init(self):
|
|
325
327
|
if self.initialized:
|
|
326
328
|
return
|
|
327
329
|
|
|
328
330
|
self.initialized = True
|
|
329
331
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
+
self.publisher = ProxyConnection(self.subject, self.proxy_endpoints, self.auth)
|
|
333
|
+
await self.publisher.connect()
|
|
332
334
|
|
|
333
|
-
self.
|
|
334
|
-
|
|
335
|
-
name=self.subject,
|
|
336
|
-
user=self.auth["user"],
|
|
337
|
-
password=self.auth["pass"],
|
|
338
|
-
max_reconnect_attempts=-1,
|
|
339
|
-
error_cb=ignore_cb,
|
|
340
|
-
disconnected_cb=ignore_cb,
|
|
341
|
-
closed_cb=ignore_cb,
|
|
342
|
-
reconnected_cb=ignore_cb,
|
|
343
|
-
discovered_server_cb=ignore_cb,
|
|
335
|
+
self.camera_publisher = ProxyConnection(
|
|
336
|
+
self.camera_subscriber_subject, self.proxy_endpoints, self.auth
|
|
344
337
|
)
|
|
338
|
+
await self.camera_publisher.connect()
|
|
345
339
|
|
|
346
|
-
self.
|
|
347
|
-
|
|
348
|
-
name=self.camera_subscriber_subject,
|
|
349
|
-
user=self.auth["user"],
|
|
350
|
-
password=self.auth["pass"],
|
|
351
|
-
max_reconnect_attempts=-1,
|
|
352
|
-
error_cb=ignore_cb,
|
|
353
|
-
disconnected_cb=ignore_cb,
|
|
354
|
-
closed_cb=ignore_cb,
|
|
355
|
-
reconnected_cb=ignore_cb,
|
|
356
|
-
discovered_server_cb=ignore_cb,
|
|
357
|
-
)
|
|
340
|
+
self.signaling_publisher = ProxyConnection(self.signaling_subject, self.proxy_endpoints, self.auth)
|
|
341
|
+
await self.signaling_publisher.connect()
|
|
358
342
|
|
|
359
|
-
self.
|
|
360
|
-
|
|
361
|
-
name=self.signaling_subject,
|
|
362
|
-
user=self.auth["user"],
|
|
363
|
-
password=self.auth["pass"],
|
|
364
|
-
max_reconnect_attempts=-1,
|
|
365
|
-
error_cb=ignore_cb,
|
|
366
|
-
disconnected_cb=ignore_cb,
|
|
367
|
-
closed_cb=ignore_cb,
|
|
368
|
-
reconnected_cb=ignore_cb,
|
|
369
|
-
discovered_server_cb=ignore_cb,
|
|
370
|
-
)
|
|
343
|
+
self.frame_publisher = ProxyConnection(self.frame_subject, self.proxy_endpoints, self.auth)
|
|
344
|
+
await self.frame_publisher.connect()
|
|
371
345
|
|
|
372
|
-
self.
|
|
373
|
-
|
|
374
|
-
name=self.frame_subject,
|
|
375
|
-
user=self.auth["user"],
|
|
376
|
-
password=self.auth["pass"],
|
|
377
|
-
max_reconnect_attempts=-1,
|
|
378
|
-
error_cb=ignore_cb,
|
|
379
|
-
disconnected_cb=ignore_cb,
|
|
380
|
-
closed_cb=ignore_cb,
|
|
381
|
-
reconnected_cb=ignore_cb,
|
|
382
|
-
discovered_server_cb=ignore_cb,
|
|
383
|
-
)
|
|
384
|
-
|
|
385
|
-
self.motion_frame_publisher = await nats.connect(
|
|
386
|
-
servers=[endpoint for endpoint in self.proxy_endpoints if endpoint.startswith("nats://")],
|
|
387
|
-
name=self.motion_frame_subject,
|
|
388
|
-
user=self.auth["user"],
|
|
389
|
-
password=self.auth["pass"],
|
|
390
|
-
max_reconnect_attempts=-1,
|
|
391
|
-
error_cb=ignore_cb,
|
|
392
|
-
disconnected_cb=ignore_cb,
|
|
393
|
-
closed_cb=ignore_cb,
|
|
394
|
-
reconnected_cb=ignore_cb,
|
|
395
|
-
discovered_server_cb=ignore_cb,
|
|
346
|
+
self.motion_frame_publisher = ProxyConnection(
|
|
347
|
+
self.motion_frame_subject, self.proxy_endpoints, self.auth
|
|
396
348
|
)
|
|
349
|
+
await self.motion_frame_publisher.connect()
|
|
397
350
|
|
|
398
351
|
self.subscriber = await self.publisher.subscribe(subject=self.subject)
|
|
399
|
-
self.
|
|
400
|
-
self.camera_subscriber = await self.camera_publisher.subscribe(subject=self.camera_subscriber_subject)
|
|
401
|
-
self.camera_plugin_subscriber = await self.camera_publisher.subscribe(
|
|
402
|
-
subject=self.camera_plugin_subscriber_subject
|
|
403
|
-
)
|
|
404
|
-
|
|
405
|
-
self.message_queue = ClientMessageQueue(
|
|
352
|
+
self.message_queue = MessageQueue(
|
|
406
353
|
self.logger,
|
|
407
354
|
self.publisher,
|
|
408
355
|
self.subscriber,
|
|
409
356
|
self.__request_handler,
|
|
410
357
|
)
|
|
411
358
|
|
|
412
|
-
self.
|
|
413
|
-
self.
|
|
414
|
-
|
|
415
|
-
self.
|
|
359
|
+
self.signaling_subscriber = await self.signaling_publisher.subscribe(subject=self.signaling_subject)
|
|
360
|
+
self.signaling_subscriber.on("message", self.__on_signaling_message)
|
|
361
|
+
|
|
362
|
+
self.camera_subscriber = await self.camera_publisher.subscribe(subject=self.camera_subscriber_subject)
|
|
363
|
+
self.camera_subscriber.on("message", self.__on_proxy_message)
|
|
364
|
+
|
|
365
|
+
self.camera_plugin_subscriber = await self.camera_publisher.subscribe(
|
|
366
|
+
subject=self.camera_plugin_subscriber_subject
|
|
367
|
+
)
|
|
368
|
+
self.camera_plugin_subscriber.on("message", self.__on_proxy_message)
|
|
416
369
|
|
|
417
370
|
await self.refresh_states()
|
|
418
371
|
|
|
@@ -483,7 +436,7 @@ class CameraDeviceProxy:
|
|
|
483
436
|
if not self.frame_subscriber:
|
|
484
437
|
self.frame_subscriber = await self.frame_publisher.subscribe(self.frame_subject)
|
|
485
438
|
|
|
486
|
-
async for msg in self.frame_subscriber.messages:
|
|
439
|
+
async for msg in self.frame_subscriber.subscriber.messages:
|
|
487
440
|
try:
|
|
488
441
|
if (
|
|
489
442
|
not self.initialized
|
|
@@ -524,7 +477,7 @@ class CameraDeviceProxy:
|
|
|
524
477
|
self.motion_frame_subject
|
|
525
478
|
)
|
|
526
479
|
|
|
527
|
-
async for msg in self.motion_frame_subscriber.messages:
|
|
480
|
+
async for msg in self.motion_frame_subscriber.subscriber.messages:
|
|
528
481
|
try:
|
|
529
482
|
if not self.initialized or self.active_motion_requests <= 0:
|
|
530
483
|
break
|
|
@@ -885,10 +838,7 @@ class CameraDeviceProxy:
|
|
|
885
838
|
if not self.frame_publisher:
|
|
886
839
|
return
|
|
887
840
|
|
|
888
|
-
await self.frame_publisher.publish(
|
|
889
|
-
self.motion_frame_subject,
|
|
890
|
-
pack(frame),
|
|
891
|
-
)
|
|
841
|
+
await self.frame_publisher.publish(self.motion_frame_subject, frame)
|
|
892
842
|
|
|
893
843
|
@overload
|
|
894
844
|
def __check_state_internal(
|
|
@@ -1454,10 +1404,7 @@ class CameraDeviceProxy:
|
|
|
1454
1404
|
"pluginId": self.plugin["id"],
|
|
1455
1405
|
}
|
|
1456
1406
|
|
|
1457
|
-
await self.signaling_publisher.publish(
|
|
1458
|
-
self.signaling_target_subject,
|
|
1459
|
-
pack(message),
|
|
1460
|
-
)
|
|
1407
|
+
await self.signaling_publisher.publish(self.signaling_target_subject, message)
|
|
1461
1408
|
|
|
1462
1409
|
self.active_requests.add(request_id)
|
|
1463
1410
|
|
|
@@ -1480,13 +1427,12 @@ class CameraDeviceProxy:
|
|
|
1480
1427
|
"pluginId": self.plugin["id"],
|
|
1481
1428
|
}
|
|
1482
1429
|
|
|
1483
|
-
|
|
1430
|
+
metadata_response: SignalingResponse = await self.signaling_publisher.request(
|
|
1484
1431
|
self.signaling_target_subject,
|
|
1485
|
-
|
|
1432
|
+
metadata_request,
|
|
1486
1433
|
timeout=timeout,
|
|
1487
1434
|
)
|
|
1488
1435
|
|
|
1489
|
-
metadata_response: SignalingResponse = unpack(metadata_msg.data)
|
|
1490
1436
|
metadata = metadata_response.get("metadata")
|
|
1491
1437
|
|
|
1492
1438
|
return metadata
|
|
@@ -1500,9 +1446,6 @@ class CameraDeviceProxy:
|
|
|
1500
1446
|
if not self.signaling_publisher:
|
|
1501
1447
|
raise Exception("Signaling Publisher not initialized")
|
|
1502
1448
|
|
|
1503
|
-
if self.signaling_publisher.is_closed:
|
|
1504
|
-
return
|
|
1505
|
-
|
|
1506
1449
|
message: SignalingRequest = {
|
|
1507
1450
|
"type": "disconnect",
|
|
1508
1451
|
"requestId": request_id,
|
|
@@ -1510,18 +1453,18 @@ class CameraDeviceProxy:
|
|
|
1510
1453
|
"pluginId": self.plugin["id"],
|
|
1511
1454
|
}
|
|
1512
1455
|
|
|
1513
|
-
await self.signaling_publisher.publish(self.signaling_target_subject,
|
|
1456
|
+
await self.signaling_publisher.publish(self.signaling_target_subject, message)
|
|
1514
1457
|
|
|
1515
1458
|
async def __close_frame_subscriber(self) -> None:
|
|
1516
1459
|
with suppress(Exception):
|
|
1517
1460
|
if self.frame_subscriber:
|
|
1518
|
-
await self.frame_subscriber.
|
|
1461
|
+
await self.frame_subscriber.close()
|
|
1519
1462
|
self.frame_subscriber = None
|
|
1520
1463
|
|
|
1521
1464
|
async def __close_motion_frame_subscriber(self) -> None:
|
|
1522
1465
|
if self.motion_frame_subscriber:
|
|
1523
1466
|
with suppress(Exception):
|
|
1524
|
-
await self.motion_frame_subscriber.
|
|
1467
|
+
await self.motion_frame_subscriber.close()
|
|
1525
1468
|
|
|
1526
1469
|
self.motion_frame_subscriber = None
|
|
1527
1470
|
|
|
@@ -1581,74 +1524,48 @@ class CameraDeviceProxy:
|
|
|
1581
1524
|
|
|
1582
1525
|
await self.message_queue.enqueue({**message, "type": "reply", "error": deserialized_error})
|
|
1583
1526
|
|
|
1584
|
-
async def
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
if not self.initialized:
|
|
1588
|
-
break
|
|
1589
|
-
|
|
1590
|
-
if len(msg.data) == 0:
|
|
1591
|
-
continue
|
|
1592
|
-
|
|
1593
|
-
message = unpack(msg.data)
|
|
1594
|
-
|
|
1595
|
-
if "type" in message:
|
|
1596
|
-
type = message["type"]
|
|
1597
|
-
if type == "removed":
|
|
1598
|
-
await self.cleanup()
|
|
1599
|
-
elif type == "updated":
|
|
1600
|
-
self.update_camera(message["data"])
|
|
1601
|
-
elif type == "cameraState":
|
|
1602
|
-
self.update_camera_state(message["data"])
|
|
1603
|
-
elif type == "prebufferState":
|
|
1604
|
-
self.update_prebuffer(
|
|
1605
|
-
message["data"]["sourceId"],
|
|
1606
|
-
message["data"]["container"],
|
|
1607
|
-
message["data"]["state"],
|
|
1608
|
-
)
|
|
1609
|
-
|
|
1610
|
-
continue
|
|
1611
|
-
|
|
1612
|
-
state_name = message["stateName"]
|
|
1613
|
-
new_data = message["data"]["newEvent"]
|
|
1614
|
-
|
|
1615
|
-
self.__update_state_internal(state_name, new_data, True)
|
|
1616
|
-
|
|
1617
|
-
except Exception as e:
|
|
1618
|
-
if self.initialized:
|
|
1619
|
-
self.logger.error("Error while processing camera device message:", e)
|
|
1620
|
-
else:
|
|
1621
|
-
break
|
|
1527
|
+
async def __on_proxy_message(self, msg: Msg) -> None:
|
|
1528
|
+
if not self.initialized:
|
|
1529
|
+
return
|
|
1622
1530
|
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1531
|
+
message = unpack(msg.data)
|
|
1532
|
+
|
|
1533
|
+
if "type" in message:
|
|
1534
|
+
type = message["type"]
|
|
1535
|
+
if type == "removed":
|
|
1536
|
+
await self.cleanup()
|
|
1537
|
+
elif type == "updated":
|
|
1538
|
+
self.update_camera(message["data"])
|
|
1539
|
+
elif type == "cameraState":
|
|
1540
|
+
self.update_camera_state(message["data"])
|
|
1541
|
+
elif type == "prebufferState":
|
|
1542
|
+
self.update_prebuffer(
|
|
1543
|
+
message["data"]["sourceId"],
|
|
1544
|
+
message["data"]["container"],
|
|
1545
|
+
message["data"]["state"],
|
|
1546
|
+
)
|
|
1547
|
+
else:
|
|
1548
|
+
state_name = message["stateName"]
|
|
1549
|
+
new_data = message["data"]["newEvent"]
|
|
1626
1550
|
|
|
1627
|
-
|
|
1628
|
-
try:
|
|
1629
|
-
if not self.initialized:
|
|
1630
|
-
break
|
|
1551
|
+
self.__update_state_internal(state_name, new_data, True)
|
|
1631
1552
|
|
|
1632
|
-
|
|
1633
|
-
|
|
1553
|
+
async def __on_signaling_message(self, msg: Msg) -> None:
|
|
1554
|
+
if not self.initialized:
|
|
1555
|
+
return
|
|
1634
1556
|
|
|
1635
|
-
|
|
1557
|
+
message: Union[SignalingResponse, PingMessage] = unpack(msg.data)
|
|
1636
1558
|
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1559
|
+
if message["type"] == "ping":
|
|
1560
|
+
if message["requestId"] in self.active_requests:
|
|
1561
|
+
self.tasks.add(self.__respond_to_signaling_message(msg, message))
|
|
1640
1562
|
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1563
|
+
elif message["type"] == "disconnect":
|
|
1564
|
+
if message["requestId"] in self.active_requests:
|
|
1565
|
+
self.active_requests.remove(message["requestId"])
|
|
1644
1566
|
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
except Exception as e:
|
|
1648
|
-
if self.initialized:
|
|
1649
|
-
self.logger.error("Error while processing ping/pong message:", e)
|
|
1650
|
-
else:
|
|
1651
|
-
break
|
|
1567
|
+
if len(self.active_requests) == 0:
|
|
1568
|
+
self.tasks.add(self.__close_frame_subscriber())
|
|
1652
1569
|
|
|
1653
1570
|
async def __respond_to_signaling_message(self, msg: Msg, message: PingMessage) -> None:
|
|
1654
1571
|
try:
|
|
@@ -3,20 +3,20 @@ from datetime import datetime
|
|
|
3
3
|
from typing import Any, Optional, Union, cast
|
|
4
4
|
from uuid import uuid4
|
|
5
5
|
|
|
6
|
-
import nats
|
|
7
6
|
from camera_ui_types import Camera, CameraConfig
|
|
8
|
-
from
|
|
9
|
-
from
|
|
7
|
+
from decoder.typings import AuthConfig
|
|
8
|
+
from message_queue import MessageQueue
|
|
10
9
|
from nats.aio.msg import Msg
|
|
11
|
-
from nats.aio.subscription import Subscription
|
|
12
10
|
from plugin_api import PluginAPI
|
|
11
|
+
from plugin_logger import PluginLogger
|
|
13
12
|
from pyeecui.asyncio import AsyncIOEventEmitter
|
|
14
13
|
from typings import PluginInfo, ProxyMessageStructure
|
|
14
|
+
from utilities.connection import ProxyConnection
|
|
15
15
|
from utilities.packer import unpack
|
|
16
|
+
from utilities.subscriptions import ProxySubscription
|
|
16
17
|
from utilities.task import TaskSet
|
|
17
18
|
|
|
18
19
|
from .camera_device import CameraDeviceProxy
|
|
19
|
-
from .message_queue import ClientMessageQueue
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class DeviceManager(AsyncIOEventEmitter):
|
|
@@ -26,7 +26,7 @@ class DeviceManager(AsyncIOEventEmitter):
|
|
|
26
26
|
logger: PluginLogger,
|
|
27
27
|
plugin: PluginInfo,
|
|
28
28
|
proxy_endpoints: list[str],
|
|
29
|
-
auth:
|
|
29
|
+
auth: AuthConfig,
|
|
30
30
|
):
|
|
31
31
|
super().__init__()
|
|
32
32
|
|
|
@@ -44,14 +44,14 @@ class DeviceManager(AsyncIOEventEmitter):
|
|
|
44
44
|
self.subject = f"{self.plugin['id']}.deviceManager"
|
|
45
45
|
self.dm_subject = f"{self.plugin['id']}.deviceManager.subscriber"
|
|
46
46
|
|
|
47
|
-
self.publisher: Optional[
|
|
48
|
-
self.dm_publisher: Optional[
|
|
47
|
+
self.publisher: Optional[ProxyConnection] = None
|
|
48
|
+
self.dm_publisher: Optional[ProxyConnection] = None
|
|
49
49
|
|
|
50
|
-
self.subscriber: Optional[
|
|
51
|
-
self.dm_subscriber: Optional[
|
|
50
|
+
self.subscriber: Optional[ProxySubscription] = None
|
|
51
|
+
self.dm_subscriber: Optional[ProxySubscription] = None
|
|
52
52
|
|
|
53
53
|
self.tasks: TaskSet = TaskSet(f"{self.plugin['name']} DeviceManager")
|
|
54
|
-
self.message_queue: Optional[
|
|
54
|
+
self.message_queue: Optional[MessageQueue] = None
|
|
55
55
|
|
|
56
56
|
# print("DeviceManager", self.plugin["name"], self.dealer_id, self.subscriber_ids)
|
|
57
57
|
|
|
@@ -63,47 +63,24 @@ class DeviceManager(AsyncIOEventEmitter):
|
|
|
63
63
|
|
|
64
64
|
self.initialized = True
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
pass
|
|
68
|
-
|
|
69
|
-
self.publisher = await nats.connect(
|
|
70
|
-
servers=[endpoint for endpoint in self.proxy_endpoints if endpoint.startswith("nats://")],
|
|
71
|
-
name=self.subject,
|
|
72
|
-
user=self.auth["user"],
|
|
73
|
-
password=self.auth["pass"],
|
|
74
|
-
max_reconnect_attempts=-1,
|
|
75
|
-
error_cb=ignore_cb,
|
|
76
|
-
disconnected_cb=ignore_cb,
|
|
77
|
-
closed_cb=ignore_cb,
|
|
78
|
-
reconnected_cb=ignore_cb,
|
|
79
|
-
discovered_server_cb=ignore_cb,
|
|
80
|
-
)
|
|
66
|
+
servers = [endpoint for endpoint in self.proxy_endpoints if endpoint.startswith("nats://")]
|
|
81
67
|
|
|
82
|
-
self.
|
|
83
|
-
|
|
84
|
-
name=self.dm_subject,
|
|
85
|
-
user=self.auth["user"],
|
|
86
|
-
password=self.auth["pass"],
|
|
87
|
-
max_reconnect_attempts=-1,
|
|
88
|
-
error_cb=ignore_cb,
|
|
89
|
-
disconnected_cb=ignore_cb,
|
|
90
|
-
closed_cb=ignore_cb,
|
|
91
|
-
reconnected_cb=ignore_cb,
|
|
92
|
-
discovered_server_cb=ignore_cb,
|
|
93
|
-
)
|
|
68
|
+
self.publisher = ProxyConnection(self.subject, servers, self.auth)
|
|
69
|
+
await self.publisher.connect()
|
|
94
70
|
|
|
95
|
-
self.
|
|
96
|
-
|
|
71
|
+
self.dm_publisher = ProxyConnection(self.dm_subject, servers, self.auth)
|
|
72
|
+
await self.dm_publisher.connect()
|
|
97
73
|
|
|
98
|
-
self.
|
|
74
|
+
self.subscriber = await self.publisher.subscribe(subject=self.subject)
|
|
75
|
+
self.message_queue = MessageQueue(
|
|
99
76
|
self.logger,
|
|
100
77
|
self.publisher,
|
|
101
78
|
self.subscriber,
|
|
102
79
|
self.__request_handler,
|
|
103
80
|
)
|
|
104
81
|
|
|
105
|
-
self.
|
|
106
|
-
self.
|
|
82
|
+
self.dm_subscriber = await self.dm_publisher.subscribe(subject=self.dm_subject)
|
|
83
|
+
self.dm_subscriber.on("message", self.__on_proxy_message)
|
|
107
84
|
|
|
108
85
|
async def get_camera_by_id(self, id: str) -> Optional[CameraDeviceProxy]:
|
|
109
86
|
camera_device = await self.__add_or_get_camera(id)
|
|
@@ -175,27 +152,11 @@ class DeviceManager(AsyncIOEventEmitter):
|
|
|
175
152
|
|
|
176
153
|
super().emit(type, camera["_id"], extension)
|
|
177
154
|
|
|
178
|
-
async def
|
|
179
|
-
if not self.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
try:
|
|
184
|
-
if not self.initialized:
|
|
185
|
-
break
|
|
186
|
-
|
|
187
|
-
if len(msg.data) == 0:
|
|
188
|
-
continue
|
|
189
|
-
|
|
190
|
-
self.tasks.add(self.__emit_event(msg))
|
|
191
|
-
except Exception as e:
|
|
192
|
-
if self.initialized:
|
|
193
|
-
self.logger.error(
|
|
194
|
-
"Error while listening to device manager messages from server:",
|
|
195
|
-
e,
|
|
196
|
-
)
|
|
197
|
-
else:
|
|
198
|
-
break
|
|
155
|
+
async def __on_proxy_message(self, msg: Msg) -> None:
|
|
156
|
+
if not self.initialized:
|
|
157
|
+
return
|
|
158
|
+
|
|
159
|
+
self.tasks.add(self.__emit_event(msg))
|
|
199
160
|
|
|
200
161
|
async def __on_request(self, fn: str, args: list[Any] = []) -> Any:
|
|
201
162
|
if not self.message_queue:
|
|
@@ -2,13 +2,11 @@ from typing import Any, Optional
|
|
|
2
2
|
|
|
3
3
|
from camera_storage import CameraStorage
|
|
4
4
|
from camera_ui_types import PluginJsonSchemaForm
|
|
5
|
-
from logger import PluginLogger
|
|
6
5
|
from plugin_api import PluginAPI
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
class StorageController:
|
|
10
|
-
def __init__(self, api: PluginAPI
|
|
11
|
-
self.__logger = logger
|
|
9
|
+
def __init__(self, api: PluginAPI) -> None:
|
|
12
10
|
self.__api = api
|
|
13
11
|
self.__camera_storages: dict[str, CameraStorage] = {}
|
|
14
12
|
|
|
@@ -28,8 +26,9 @@ class StorageController:
|
|
|
28
26
|
"""
|
|
29
27
|
if schema is None:
|
|
30
28
|
schema = {}
|
|
29
|
+
|
|
31
30
|
camera_storage = self.__camera_storages.get(camera_id) or CameraStorage(
|
|
32
|
-
self.__api,
|
|
31
|
+
self.__api, instance, camera_id, schema
|
|
33
32
|
)
|
|
34
33
|
|
|
35
34
|
camera_storage.initialize_storage()
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from typing import Any, Optional
|
|
2
|
+
|
|
3
|
+
import nats
|
|
4
|
+
from decoder.typings import AuthConfig
|
|
5
|
+
from nats.aio.client import Client as NatsConnection
|
|
6
|
+
|
|
7
|
+
from .packer import pack, unpack
|
|
8
|
+
from .subscriptions import ProxySubscription
|
|
9
|
+
from .task import TaskSet
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ProxyConnection:
|
|
13
|
+
def __init__(self, name: str, servers: list[str], auth: AuthConfig) -> None:
|
|
14
|
+
self.name = name
|
|
15
|
+
self.servers = servers
|
|
16
|
+
self.auth = auth
|
|
17
|
+
|
|
18
|
+
self.tasks: TaskSet = TaskSet(f"{self.name} NatsSubscriber")
|
|
19
|
+
self.publisher: Optional[NatsConnection] = None
|
|
20
|
+
self.subscribers: list[ProxySubscription] = []
|
|
21
|
+
|
|
22
|
+
self.closed = False
|
|
23
|
+
|
|
24
|
+
async def connect(self) -> NatsConnection:
|
|
25
|
+
async def ignore_cb(e: Optional[Any] = None):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
self.publisher = await nats.connect(
|
|
29
|
+
servers=self.servers,
|
|
30
|
+
name=self.name,
|
|
31
|
+
user=self.auth["user"],
|
|
32
|
+
password=self.auth["password"],
|
|
33
|
+
max_reconnect_attempts=-1,
|
|
34
|
+
error_cb=ignore_cb,
|
|
35
|
+
disconnected_cb=ignore_cb,
|
|
36
|
+
closed_cb=ignore_cb,
|
|
37
|
+
reconnected_cb=ignore_cb,
|
|
38
|
+
discovered_server_cb=ignore_cb,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
return self.publisher
|
|
42
|
+
|
|
43
|
+
async def subscribe(self, subject: str, skip_listening: bool = False) -> ProxySubscription:
|
|
44
|
+
if not self.publisher:
|
|
45
|
+
raise Exception("Connection not established")
|
|
46
|
+
|
|
47
|
+
subscriber = ProxySubscription(await self.publisher.subscribe(subject))
|
|
48
|
+
|
|
49
|
+
if not skip_listening:
|
|
50
|
+
self.tasks.add(subscriber.listen())
|
|
51
|
+
|
|
52
|
+
self.subscribers.append(subscriber)
|
|
53
|
+
|
|
54
|
+
return subscriber
|
|
55
|
+
|
|
56
|
+
async def publish(self, subject: str, message: Any) -> None:
|
|
57
|
+
if self.closed:
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
if not self.publisher:
|
|
61
|
+
raise Exception("Connection not established")
|
|
62
|
+
|
|
63
|
+
await self.publisher.publish(subject, pack(message))
|
|
64
|
+
|
|
65
|
+
async def request(self, subject: str, message: Any, timeout: float) -> Any:
|
|
66
|
+
if self.closed:
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
if not self.publisher:
|
|
70
|
+
raise Exception("Connection not established")
|
|
71
|
+
|
|
72
|
+
msg = await self.publisher.request(subject, pack(message), timeout)
|
|
73
|
+
response = unpack(msg.data)
|
|
74
|
+
|
|
75
|
+
return response
|
|
76
|
+
|
|
77
|
+
async def close(self) -> None:
|
|
78
|
+
self.closed = True
|
|
79
|
+
|
|
80
|
+
for subscriber in self.subscribers:
|
|
81
|
+
await subscriber.close()
|
|
82
|
+
|
|
83
|
+
if self.publisher:
|
|
84
|
+
await self.publisher.close()
|
|
85
|
+
|
|
86
|
+
self.tasks.remove_all()
|