@camera.ui/server 0.0.10 → 0.0.11-alpha.2

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.
Files changed (187) hide show
  1. package/dist/interface/assets/@mdi-B8Roxr1z.js +1 -0
  2. package/dist/interface/assets/{@tanstack-B-9PO-kT.js → @tanstack-BvYNCsQh.js} +1 -1
  3. package/dist/interface/assets/{@vee-validate-D_G0ehOl.js → @vee-validate-BY5H7fGS.js} +1 -1
  4. package/dist/interface/assets/@vue-DMh6qW6s.js +17 -0
  5. package/dist/interface/assets/{@vueform-Bj73kRPS.js → @vueform-B62o9zLe.js} +1 -1
  6. package/dist/interface/assets/@vueuse-D76s02Ot.js +1 -0
  7. package/dist/interface/assets/Account-DfRAVlQX.js +1 -0
  8. package/dist/interface/assets/Account-DlOUWknb.css +1 -0
  9. package/dist/interface/assets/Adminpanel-CLrlTEb1.js +2 -0
  10. package/dist/interface/assets/Adminpanel-Cp92VRfz.css +1 -0
  11. package/dist/interface/assets/Appearance-CKhkKhrK.js +1 -0
  12. package/dist/interface/assets/Backup-Dqeqiulf.js +1 -0
  13. package/dist/interface/assets/{Camera-BOu5dUel.js → Camera-_bMRlyKl.js} +1 -1
  14. package/dist/interface/assets/{Cameras-C7eUXdZk.js → Cameras-0W-4S92q.js} +1 -1
  15. package/dist/interface/assets/Cameras-Du4Q1fbV.css +1 -0
  16. package/dist/interface/assets/{Camview-CEgwGCGR.js → Camview-Bv3STCHT.js} +1 -1
  17. package/dist/interface/assets/{Config-Dt-etQ3h.js → Config-pNcWHwGl.js} +1 -1
  18. package/dist/interface/assets/{Console-FCve5CKy.js → Console-D6eztjlH.js} +1 -1
  19. package/dist/interface/assets/FirstSteps-C-08k14n.js +1 -0
  20. package/dist/interface/assets/FirstSteps-CGEDVu4n.css +1 -0
  21. package/dist/interface/assets/{NewCamera-Cc1X79Ns.js → NewCamera-Dmj8qmGV.js} +2 -2
  22. package/dist/interface/assets/{Plugin-CnQjafMC.js → Plugin-0komMxsg.js} +1 -1
  23. package/dist/interface/assets/{Plugins-CwyUdMlv.js → Plugins-CpbWh_pN.js} +1 -1
  24. package/dist/interface/assets/Recordings-BBllGLr3.js +1 -0
  25. package/dist/interface/assets/Recordings-BHGIQ_1S.js +1 -0
  26. package/dist/interface/assets/Settings-DuUlAjQP.js +1 -0
  27. package/dist/interface/assets/System-CNh-XpD0.css +1 -0
  28. package/dist/interface/assets/System-Dp3-TN7J.js +4 -0
  29. package/dist/interface/assets/User-CmrrYaqq.js +1 -0
  30. package/dist/interface/assets/User-DBVny1Dv.css +1 -0
  31. package/dist/interface/assets/VConfigEditor.vue_vue_type_script_setup_true_lang-aMMzP49H.js +2 -0
  32. package/dist/interface/assets/{VConsole-BHy92Ws0.js → VConsole-WHOBQIsm.js} +1 -1
  33. package/dist/interface/assets/{VPlayer-D3KhRfx-.css → VPlayer-DJjwfULk.css} +1 -1
  34. package/dist/interface/assets/VPlayer-YzfFbh8e.js +1 -0
  35. package/dist/interface/assets/VPluginCard-BoeWmehD.css +1 -0
  36. package/dist/interface/assets/VPluginCard-CKMpjvL9.js +4 -0
  37. package/dist/interface/assets/compare-versions-DqEOhma6.js +1 -0
  38. package/dist/interface/assets/main-2jkpYOC_.css +1 -0
  39. package/dist/interface/assets/main-D1X9SzzX.js +9 -0
  40. package/dist/interface/assets/{pinia-CitQ5b66.js → pinia-BQbsPkIS.js} +1 -1
  41. package/dist/interface/assets/{plugins-D80RNVmI.js → plugins-BKEnSy-B.js} +1 -1
  42. package/dist/interface/assets/{rxjs-B53o3e_J.js → rxjs-CQrF441D.js} +1 -1
  43. package/dist/interface/assets/system-BTruCO3L.js +1 -0
  44. package/dist/interface/assets/{ui-CHKoHLl-.js → ui-CyEgSsGE.js} +1 -1
  45. package/dist/interface/assets/{v-calendar-C-8W4FeM.js → v-calendar-CVkp7hgG.js} +1 -1
  46. package/dist/interface/assets/{vee-validate-Ck3I2guh.js → vee-validate-9vrYaQFq.js} +1 -1
  47. package/dist/interface/assets/{vue-i18n-DuCDz9TJ.js → vue-i18n-DqKZtX1N.js} +1 -1
  48. package/dist/interface/assets/{vue-inline-svg-C2gR6nRD.js → vue-inline-svg-D1BV6A5r.js} +1 -1
  49. package/dist/interface/assets/{vue-router-OPGDMnws.js → vue-router-Bje-Muh5.js} +1 -1
  50. package/dist/interface/assets/vue3-apexcharts-B8Nznyy3.js +703 -0
  51. package/dist/interface/assets/{vue3-dnd-Hf295yge.js → vue3-dnd-CvPSCHQb.js} +1 -1
  52. package/dist/interface/assets/{vue3-toastify-DQr2dOCx.js → vue3-toastify-D8Ru9hkX.js} +1 -1
  53. package/dist/interface/assets/{vuetify-B__3Y-at.css → vuetify-CoMF_JkX.css} +2 -2
  54. package/dist/interface/assets/vuetify-DYU2dOLI.js +5 -0
  55. package/dist/interface/index.html +17 -17
  56. package/dist/interface/pwa/pwa-120x120.png +0 -0
  57. package/dist/interface/pwa/pwa-144x144.png +0 -0
  58. package/dist/interface/pwa/pwa-152x152.png +0 -0
  59. package/dist/interface/pwa/pwa-167x167.png +0 -0
  60. package/dist/interface/pwa/pwa-192x192.png +0 -0
  61. package/dist/interface/pwa/pwa-24x24.png +0 -0
  62. package/dist/interface/pwa/pwa-36x36.png +0 -0
  63. package/dist/interface/pwa/pwa-48x48.png +0 -0
  64. package/dist/interface/pwa/pwa-50x50.png +0 -0
  65. package/dist/interface/pwa/pwa-64x64.png +0 -0
  66. package/dist/interface/pwa/pwa-72x72.png +0 -0
  67. package/dist/interface/pwa/pwa-88x88.png +0 -0
  68. package/dist/interface/pwa/pwa-96x96.png +0 -0
  69. package/dist/interface/sw.js +1 -1
  70. package/dist/server/bin/cui-service.js +4 -8
  71. package/dist/server/bin/cui-service.js.map +1 -1
  72. package/dist/server/package.json +3 -3
  73. package/dist/server/requirements.txt +1 -1
  74. package/dist/server/src/api/controllers/api.controller.d.ts +1 -0
  75. package/dist/server/src/api/controllers/api.controller.js +3 -0
  76. package/dist/server/src/api/controllers/api.controller.js.map +1 -1
  77. package/dist/server/src/api/controllers/cameras.controller.d.ts +2 -1
  78. package/dist/server/src/api/controllers/cameras.controller.js +27 -0
  79. package/dist/server/src/api/controllers/cameras.controller.js.map +1 -1
  80. package/dist/server/src/api/controllers/plugins.controller.d.ts +1 -0
  81. package/dist/server/src/api/controllers/plugins.controller.js +41 -23
  82. package/dist/server/src/api/controllers/plugins.controller.js.map +1 -1
  83. package/dist/server/src/api/controllers/system.controller.d.ts +3 -0
  84. package/dist/server/src/api/controllers/system.controller.js +39 -0
  85. package/dist/server/src/api/controllers/system.controller.js.map +1 -1
  86. package/dist/server/src/api/controllers/users.controller.js +21 -2
  87. package/dist/server/src/api/controllers/users.controller.js.map +1 -1
  88. package/dist/server/src/api/database/types.d.ts +6 -6
  89. package/dist/server/src/api/index.js +8 -12
  90. package/dist/server/src/api/index.js.map +1 -1
  91. package/dist/server/src/api/routes/api.routes.js +1 -0
  92. package/dist/server/src/api/routes/api.routes.js.map +1 -1
  93. package/dist/server/src/api/routes/cameras.routes.js +19 -1
  94. package/dist/server/src/api/routes/cameras.routes.js.map +1 -1
  95. package/dist/server/src/api/routes/system.routes.js +24 -0
  96. package/dist/server/src/api/routes/system.routes.js.map +1 -1
  97. package/dist/server/src/api/schemas/cameras.schema.d.ts +61 -54
  98. package/dist/server/src/api/schemas/cameras.schema.js +7 -6
  99. package/dist/server/src/api/schemas/cameras.schema.js.map +1 -1
  100. package/dist/server/src/api/schemas/plugins.schema.js +1 -1
  101. package/dist/server/src/api/schemas/plugins.schema.js.map +1 -1
  102. package/dist/server/src/api/schemas/users.schema.d.ts +5 -0
  103. package/dist/server/src/api/schemas/users.schema.js +2 -1
  104. package/dist/server/src/api/schemas/users.schema.js.map +1 -1
  105. package/dist/server/src/api/types/index.d.ts +12 -2
  106. package/dist/server/src/api/types/index.js.map +1 -1
  107. package/dist/server/src/api/websocket/nsp/metrics.d.ts +4 -22
  108. package/dist/server/src/api/websocket/nsp/metrics.js +74 -214
  109. package/dist/server/src/api/websocket/nsp/metrics.js.map +1 -1
  110. package/dist/server/src/api/websocket/nsp/status.d.ts +4 -15
  111. package/dist/server/src/api/websocket/nsp/status.js +10 -16
  112. package/dist/server/src/api/websocket/nsp/status.js.map +1 -1
  113. package/dist/server/src/api/websocket/types.d.ts +25 -64
  114. package/dist/server/src/decoder/worker.d.ts +1 -2
  115. package/dist/server/src/decoder/worker.js +5 -11
  116. package/dist/server/src/decoder/worker.js.map +1 -1
  117. package/dist/server/src/go2rtc/index.js +4 -6
  118. package/dist/server/src/go2rtc/index.js.map +1 -1
  119. package/dist/server/src/index.d.ts +2 -2
  120. package/dist/server/src/index.js.map +1 -1
  121. package/dist/server/src/nats/index.d.ts +1 -1
  122. package/dist/server/src/nats/index.js +3 -3
  123. package/dist/server/src/nats/index.js.map +1 -1
  124. package/dist/server/src/nats/proxy/cameraDevice.d.ts +1 -1
  125. package/dist/server/src/nats/proxy/cameraDevice.js +1 -1
  126. package/dist/server/src/nats/proxy/cameraDevice.js.map +1 -1
  127. package/dist/server/src/nats/proxy/deviceManager.d.ts +1 -1
  128. package/dist/server/src/nats/proxy/deviceManager.js +1 -1
  129. package/dist/server/src/nats/proxy/deviceManager.js.map +1 -1
  130. package/dist/server/src/nats/server.js +4 -6
  131. package/dist/server/src/nats/server.js.map +1 -1
  132. package/dist/server/src/nats/websocket.js +2 -2
  133. package/dist/server/src/nats/websocket.js.map +1 -1
  134. package/dist/server/src/plugins/types.d.ts +10 -41
  135. package/dist/server/src/plugins/worker.js +4 -7
  136. package/dist/server/src/plugins/worker.js.map +1 -1
  137. package/dist/server/src/polyglot/node/plugins/cameraStorage.d.ts +9 -10
  138. package/dist/server/src/polyglot/node/plugins/cameraStorage.js +51 -55
  139. package/dist/server/src/polyglot/node/plugins/cameraStorage.js.map +1 -1
  140. package/dist/server/src/polyglot/node/plugins/child.js +18 -4
  141. package/dist/server/src/polyglot/node/plugins/child.js.map +1 -1
  142. package/dist/server/src/polyglot/node/plugins/proxy/cameraDevice.js +18 -4
  143. package/dist/server/src/polyglot/node/plugins/proxy/cameraDevice.js.map +1 -1
  144. package/dist/server/src/polyglot/node/plugins/schema.d.ts +22 -9
  145. package/dist/server/src/polyglot/node/plugins/schema.js +22 -2
  146. package/dist/server/src/polyglot/node/plugins/schema.js.map +1 -1
  147. package/dist/server/src/polyglot/node/plugins/storageController.d.ts +3 -3
  148. package/dist/server/src/polyglot/node/plugins/storageController.js.map +1 -1
  149. package/dist/server/src/polyglot/python/camera_ui_types/__init__.py +59 -93
  150. package/dist/server/src/polyglot/python/plugins/camera_storage.py +75 -80
  151. package/dist/server/src/polyglot/python/plugins/child.py +12 -4
  152. package/dist/server/src/polyglot/python/plugins/constants.py +0 -1
  153. package/dist/server/src/polyglot/python/plugins/proxy/camera_device.py +12 -4
  154. package/dist/server/src/polyglot/python/plugins/schema.py +19 -230
  155. package/dist/server/src/polyglot/python/plugins/storage_controller.py +2 -2
  156. package/dist/server/src/services/config/index.d.ts +3 -3
  157. package/dist/server/src/services/config/index.js +18 -4
  158. package/dist/server/src/services/config/index.js.map +1 -1
  159. package/dist/server/src/services/config/types.d.ts +1 -1
  160. package/package.json +3 -3
  161. package/dist/interface/assets/@mdi-C-QA1nE3.js +0 -1
  162. package/dist/interface/assets/@vue-C10tA4b9.js +0 -17
  163. package/dist/interface/assets/@vueuse-BPeqNGoM.js +0 -1
  164. package/dist/interface/assets/Account-B_tHnXoX.css +0 -1
  165. package/dist/interface/assets/Account-MEaGtu1D.js +0 -1
  166. package/dist/interface/assets/Adminpanel-B_SY1GJM.css +0 -0
  167. package/dist/interface/assets/Adminpanel-D1ycltxf.js +0 -1
  168. package/dist/interface/assets/Appearance-Jlzp_P21.js +0 -1
  169. package/dist/interface/assets/Backup-1-ju9NDo.js +0 -1
  170. package/dist/interface/assets/Cameras-tmTzi1M6.css +0 -1
  171. package/dist/interface/assets/FirstSteps-DLkKDSe9.js +0 -1
  172. package/dist/interface/assets/FirstSteps-DNHhyDSw.css +0 -1
  173. package/dist/interface/assets/Recordings-Boeev1lV.js +0 -1
  174. package/dist/interface/assets/Recordings-D5ta7AYS.js +0 -1
  175. package/dist/interface/assets/Settings-Cvm2jnBr.js +0 -1
  176. package/dist/interface/assets/System-fHQ7XKri.js +0 -1
  177. package/dist/interface/assets/User-5o1VKizc.js +0 -1
  178. package/dist/interface/assets/User-BXColIbU.css +0 -1
  179. package/dist/interface/assets/VConfigEditor.vue_vue_type_script_setup_true_lang-C_95ELTZ.js +0 -2
  180. package/dist/interface/assets/VPlayer-LX5HGLrY.js +0 -1
  181. package/dist/interface/assets/VPluginCard-CFpg0LM4.js +0 -4
  182. package/dist/interface/assets/VPluginCard-Fl0AYmnF.css +0 -1
  183. package/dist/interface/assets/main-BCWSiwnj.js +0 -9
  184. package/dist/interface/assets/main-CQNVVncO.css +0 -1
  185. package/dist/interface/assets/system-CS_ZOs3_.js +0 -1
  186. package/dist/interface/assets/vuetify-CrcT8VHB.js +0 -5
  187. package/dist/server/src/polyglot/node/decoder/wasm/test/imageUtils.py +0 -106
@@ -6,10 +6,10 @@ from pathlib import Path
6
6
  from typing import Any, Optional, TypeVar, Union, cast
7
7
 
8
8
  from camera_ui_types import (
9
- PluginJsonBaseSchema,
10
- PluginJsonSchema,
11
- PluginJsonSchemaForm,
12
- PluginRootSchema,
9
+ JsonBaseSchema,
10
+ JsonSchema,
11
+ JsonSchemaForm,
12
+ RootSchema,
13
13
  SchemaConfig,
14
14
  )
15
15
  from deepdiff import DeepDiff
@@ -62,15 +62,15 @@ class CameraStorage:
62
62
  api: PluginAPI,
63
63
  instance: Any,
64
64
  camera_id: str,
65
- schema: Optional[PluginJsonSchemaForm] = None,
65
+ schema: Optional[JsonSchemaForm] = None,
66
66
  ) -> None:
67
67
  if schema is None:
68
68
  schema = {}
69
69
  self.__api = api
70
70
  self.__instance = instance
71
71
  self.__camera_id = camera_id
72
- self.__schema: PluginJsonSchemaForm = schema or {}
73
- self.__values: dict[str, Any] = {}
72
+ self.schema: JsonSchemaForm = schema or {}
73
+ self.values: dict[str, Any] = {}
74
74
 
75
75
  db_path = Path(api.storage_path) / "volume"
76
76
  self.__db: Lmdb[Literal["config"], dict[str, Any]] = JsonLmdb.open(file=str(db_path), flag="c")
@@ -78,11 +78,7 @@ class CameraStorage:
78
78
  self.__api.device_manager.once("cameraDeselected", self.__deselected)
79
79
  self.__api.once("shutdown", self.__close)
80
80
 
81
- @property
82
- def values(self) -> dict[str, Any]:
83
- return self.__values
84
-
85
- def initialize_storage(self) -> None:
81
+ def initializeStorage(self) -> None:
86
82
  """
87
83
  Initialize the storage.
88
84
  This will load the configuration from the database.
@@ -96,17 +92,17 @@ class CameraStorage:
96
92
  except: # noqa: E722
97
93
  pass
98
94
 
99
- schema_config = generate_json_from_root_schema({"schema": self.__schema})
95
+ schema_config = generate_json_from_root_schema({"schema": self.schema})
100
96
 
101
- self.__values = merge_with(schema_config, camera_config, merge, [])
97
+ self.values = merge_with(schema_config, camera_config, merge, [])
102
98
 
103
99
  self.__save_db()
104
100
 
105
101
  @overload
106
- async def get_value(self, path: str) -> Union[Any, None]: ...
102
+ async def getValue(self, path: str) -> Union[Any, None]: ...
107
103
  @overload
108
- async def get_value(self, path: str, default_value: P) -> P: ...
109
- async def get_value(self, path: str, default_value: Optional[P] = None) -> Union[P, None]:
104
+ async def getValue(self, path: str, default_value: P) -> P: ...
105
+ async def getValue(self, path: str, default_value: Optional[P] = None) -> Union[P, None]:
110
106
  """
111
107
  Get a value from the configuration by its key/path.
112
108
  If the schema has an onGet function, the onGet function will be called.
@@ -119,8 +115,8 @@ class CameraStorage:
119
115
  """
120
116
 
121
117
  schema_path = config_path_to_schema_path(path)
122
- schema: PluginJsonBaseSchema = ObjectPath.get(self.__schema, schema_path)
123
- config_value = ObjectPath.get(self.__values, path)
118
+ schema: JsonBaseSchema = ObjectPath.get(self.schema, schema_path)
119
+ config_value = ObjectPath.get(self.values, path)
124
120
 
125
121
  if schema:
126
122
  on_get_function = schema.get("onGet", None)
@@ -136,7 +132,7 @@ class CameraStorage:
136
132
  else:
137
133
  return default_value
138
134
 
139
- async def set_value(self, path: str, new_value: Any) -> None:
135
+ async def setValue(self, path: str, new_value: Any) -> None:
140
136
  """
141
137
  Set a new value for a given key/path in the configuration.
142
138
  If the schema of the value has an onSet function, and the value has changed, the onSet function will be called.
@@ -147,18 +143,18 @@ class CameraStorage:
147
143
  """
148
144
 
149
145
  schema_path = config_path_to_schema_path(path)
150
- schema: PluginJsonSchema = ObjectPath.get(self.__schema, schema_path)
146
+ schema: JsonSchema = ObjectPath.get(self.schema, schema_path)
151
147
 
152
148
  if schema:
153
- old_config = deepcopy(self.__values)
154
- ObjectPath.set(self.__values, path, new_value)
149
+ old_config = deepcopy(self.values)
150
+ ObjectPath.set(self.values, path, new_value)
155
151
 
156
- await self.__trigger_on_set_for_changes(old_config, self.__values)
152
+ await self.__trigger_on_set_for_changes(old_config, self.values)
157
153
 
158
154
  if self.__contains_storable_schema(schema):
159
155
  self.__save_db()
160
156
 
161
- def has_value(self, path: str) -> bool:
157
+ def hasValue(self, path: str) -> bool:
162
158
  """
163
159
  Check if a value exists by its config path/key.
164
160
 
@@ -166,7 +162,7 @@ class CameraStorage:
166
162
  :return: True if the value exists, false otherwise.
167
163
  """
168
164
 
169
- config_value = ObjectPath.get(self.__values, path)
165
+ config_value = ObjectPath.get(self.values, path)
170
166
  return config_value is not None
171
167
 
172
168
  async def getConfig(self) -> SchemaConfig:
@@ -177,12 +173,12 @@ class CameraStorage:
177
173
  :return: The root schema and configuration.
178
174
  """
179
175
 
180
- filtered_schema = remove_functions_from_schema_form(self.__schema)
181
- root_schema: PluginRootSchema = {"schema": filtered_schema}
176
+ filtered_schema = remove_functions_from_schema_form(self.schema)
177
+ root_schema: RootSchema = {"schema": filtered_schema}
182
178
 
183
- await self.__resolve_on_get_functions(self.__schema)
179
+ await self.__resolve_on_get_functions(self.schema)
184
180
 
185
- return {"rootSchema": root_schema, "config": self.__values}
181
+ return {"rootSchema": root_schema, "config": self.values}
186
182
 
187
183
  async def setConfig(self, new_config: dict[str, Any]) -> None:
188
184
  """
@@ -192,20 +188,20 @@ class CameraStorage:
192
188
  :param new_config: The new configuration to set.
193
189
  """
194
190
 
195
- old_config = deepcopy(self.__values)
196
- self.__values = new_config
191
+ old_config = deepcopy(self.values)
192
+ self.values = new_config
197
193
 
198
- await self.__trigger_on_set_for_changes(old_config, self.__values)
194
+ await self.__trigger_on_set_for_changes(old_config, self.values)
199
195
  self.__save_db()
200
196
 
201
197
  @overload
202
- async def add_schema(self, schema_or_path: PluginJsonSchemaForm) -> None: ...
198
+ async def addSchema(self, schema_or_path: JsonSchemaForm) -> None: ...
203
199
  @overload
204
- async def add_schema(self, schema_or_path: str, schema: PluginJsonSchema) -> None: ...
205
- async def add_schema(
200
+ async def addSchema(self, schema_or_path: str, schema: JsonSchema) -> None: ...
201
+ async def addSchema(
206
202
  self,
207
- schema_or_path: Union[PluginJsonSchemaForm, str],
208
- schema: Optional[PluginJsonSchema] = None,
203
+ schema_or_path: Union[JsonSchemaForm, str],
204
+ schema: Optional[JsonSchema] = None,
209
205
  ) -> None:
210
206
  """
211
207
  Add a new schema to the existing schema.
@@ -222,7 +218,7 @@ class CameraStorage:
222
218
  path = schema_or_path
223
219
  schema_path = config_path_to_schema_path(path)
224
220
 
225
- ObjectPath.set(self.__schema, schema_path, schema)
221
+ ObjectPath.set(self.schema, schema_path, schema)
226
222
 
227
223
  await self.__resolve_on_get_functions(schema, schema_path)
228
224
 
@@ -232,7 +228,7 @@ class CameraStorage:
232
228
  elif isinstance(schema_or_path, dict) and schema is None:
233
229
  new_schema = schema_or_path
234
230
 
235
- self.__schema = merge_with(self.__schema, new_schema, merge, [])
231
+ self.schema = merge_with(self.schema, new_schema, merge, [])
236
232
 
237
233
  await self.__resolve_on_get_functions(new_schema)
238
234
 
@@ -240,12 +236,12 @@ class CameraStorage:
240
236
  should_save = True
241
237
 
242
238
  else:
243
- raise Exception("Invalid arguments for add_schema")
239
+ raise Exception("Invalid arguments for addSchema")
244
240
 
245
241
  if should_save:
246
242
  self.__save_db()
247
243
 
248
- def remove_schema(self, path: str) -> None:
244
+ def removeSchema(self, path: str) -> None:
249
245
  """
250
246
  Remove a schema by its config path/key from the existing schema.
251
247
  It will also remove the value from the configuration.
@@ -255,16 +251,16 @@ class CameraStorage:
255
251
  """
256
252
 
257
253
  schema_path = config_path_to_schema_path(path)
258
- schema: Optional[PluginJsonSchema] = ObjectPath.get(self.__schema, schema_path) or None
254
+ schema: Optional[JsonSchema] = ObjectPath.get(self.schema, schema_path) or None
259
255
 
260
256
  if schema:
261
- ObjectPath.delete(self.__schema, schema_path)
262
- ObjectPath.delete(self.__values, path)
257
+ ObjectPath.delete(self.schema, schema_path)
258
+ ObjectPath.delete(self.values, path)
263
259
 
264
260
  if self.__contains_storable_schema(schema):
265
261
  self.__remove_db()
266
262
 
267
- async def change_schema(self, path: str, new_schema: dict[str, Any]) -> None:
263
+ async def changeSchema(self, path: str, new_schema: dict[str, Any]) -> None:
268
264
  """
269
265
  Change a schema by its config path/key from the existing schema.
270
266
  It will also change the value from the configuration.
@@ -275,18 +271,18 @@ class CameraStorage:
275
271
  """
276
272
 
277
273
  schema_path = config_path_to_schema_path(path)
278
- schema: Optional[PluginJsonSchema] = ObjectPath.get(self.__schema, schema_path) or None
274
+ schema: Optional[JsonSchema] = ObjectPath.get(self.schema, schema_path) or None
279
275
 
280
276
  if schema:
281
277
  merge_with(schema, new_schema, merge, [])
282
- ObjectPath.set(self.__schema, schema_path, schema)
278
+ ObjectPath.set(self.schema, schema_path, schema)
283
279
 
284
280
  await self.__resolve_on_get_functions(schema, schema_path)
285
281
 
286
282
  if self.__contains_storable_schema(schema):
287
283
  self.__save_db()
288
284
 
289
- def get_schema(self, path: str) -> Optional[PluginJsonSchema]:
285
+ def getSchema(self, path: str) -> Optional[JsonSchema]:
290
286
  """
291
287
  Get a schema by its config path/key.
292
288
 
@@ -295,11 +291,11 @@ class CameraStorage:
295
291
  """
296
292
 
297
293
  schema_path = config_path_to_schema_path(path)
298
- schema: Optional[PluginJsonSchema] = ObjectPath.get(self.__schema, schema_path) or None
294
+ schema: Optional[JsonSchema] = ObjectPath.get(self.schema, schema_path) or None
299
295
 
300
296
  return schema
301
297
 
302
- def has_schema(self, path: str) -> bool:
298
+ def hasSchema(self, path: str) -> bool:
303
299
  """
304
300
  Check if a schema exists by its config path/key.
305
301
 
@@ -308,13 +304,13 @@ class CameraStorage:
308
304
  """
309
305
 
310
306
  schema_path = config_path_to_schema_path(path)
311
- schema: Optional[PluginJsonSchema] = ObjectPath.get(self.__schema, schema_path) or None
307
+ schema: Optional[JsonSchema] = ObjectPath.get(self.schema, schema_path) or None
312
308
 
313
309
  return schema is not None
314
310
 
315
311
  async def __resolve_on_get_functions(
316
312
  self,
317
- schema: Union[PluginJsonSchemaForm, PluginJsonSchema],
313
+ schema: Union[JsonSchemaForm, JsonSchema],
318
314
  base_schema_path: str = "",
319
315
  ) -> None:
320
316
  if "onGet" in schema or "onSet" in schema:
@@ -326,7 +322,7 @@ class CameraStorage:
326
322
  base_schema_path,
327
323
  )
328
324
  else:
329
- _schema = cast(PluginJsonSchemaForm, schema)
325
+ _schema = cast(JsonSchemaForm, schema)
330
326
 
331
327
  for key, value in _schema.items():
332
328
  schema_path = f"{base_schema_path}.{key}" if base_schema_path else key
@@ -340,7 +336,7 @@ class CameraStorage:
340
336
 
341
337
  async def ___resolve_on_get_functions_for_object(
342
338
  self,
343
- schema: PluginJsonSchemaForm,
339
+ schema: JsonSchemaForm,
344
340
  base_schema_path: str,
345
341
  ) -> None:
346
342
  for key, _ in schema.items():
@@ -349,10 +345,10 @@ class CameraStorage:
349
345
 
350
346
  async def __resolve_on_get_functions_for_schema(self, schema_path: str) -> None:
351
347
  config_path = schema_path_to_config_path(schema_path)
352
- schema_value = await self.get_value(config_path)
348
+ schema_value = await self.getValue(config_path)
353
349
 
354
350
  if schema_value is not None:
355
- ObjectPath.set(self.__values, config_path, schema_value)
351
+ ObjectPath.set(self.values, config_path, schema_value)
356
352
 
357
353
  async def __trigger_on_set_for_changes(
358
354
  self, old_config: dict[str, Any], new_config: dict[str, Any], path: str = ""
@@ -364,7 +360,7 @@ class CameraStorage:
364
360
 
365
361
  if DeepDiff(old_value, new_value, ignore_order=True) != {}:
366
362
  schema_path = config_path_to_schema_path(new_path)
367
- schema_item: Optional[PluginJsonBaseSchema] = get_value_by_path(self.__schema, schema_path)
363
+ schema_item: Optional[JsonBaseSchema] = get_value_by_path(self.schema, schema_path)
368
364
 
369
365
  if schema_item:
370
366
  on_set_function = schema_item.get("onSet", None)
@@ -380,12 +376,15 @@ class CameraStorage:
380
376
 
381
377
  def __filter_storable_values(
382
378
  self,
383
- schema: PluginJsonSchemaForm,
379
+ schema: JsonSchemaForm,
384
380
  base_schema_path: str = "",
385
381
  result: dict[str, Any] = {},
386
382
  ) -> dict[str, Any]:
387
383
  for key, value in schema.items():
388
- if "type" in value and value["type"] == "object":
384
+ if value["type"] == "button":
385
+ continue
386
+
387
+ if value["type"] == "object":
389
388
  if "properties" in value:
390
389
  s: Any = value["properties"]
391
390
  path = f"{base_schema_path}.{key}" if base_schema_path else key
@@ -393,7 +392,7 @@ class CameraStorage:
393
392
  elif "store" in value and value["store"]:
394
393
  schema_path = f"{base_schema_path}.{key}" if base_schema_path else key
395
394
  config_path = schema_path_to_config_path(schema_path)
396
- config_value = get_value_by_path(self.__values, config_path)
395
+ config_value = get_value_by_path(self.values, config_path)
397
396
 
398
397
  ObjectPath.set(result, config_path, config_value)
399
398
 
@@ -401,30 +400,25 @@ class CameraStorage:
401
400
 
402
401
  def __contains_storable_schema(
403
402
  self,
404
- schema: Union[PluginJsonSchemaForm, PluginJsonSchema],
403
+ schema: Union[JsonSchemaForm, JsonSchema],
405
404
  ) -> bool:
406
- if "type" in schema and schema["type"] == "object":
407
- if "type" in schema and schema["type"] == "object":
408
- if "store" in schema and schema["store"]:
409
- return True
410
- if "properties" in schema and schema["properties"]:
411
- for sub_schema in schema["properties"].values():
412
- sub: Any = sub_schema
413
- if self.__contains_storable_schema(sub):
414
- return True
415
-
416
- return False
417
-
405
+ if schema["type"] == "boolean":
418
406
  return False
419
- else:
420
- return any(
421
- self.__contains_storable_schema(sub_schema) # type: ignore
422
- for sub_schema in schema.values()
423
- )
407
+
408
+ if "store" in schema and schema["store"]:
409
+ return True
410
+
411
+ if schema["type"] == "object" and "properties" in schema:
412
+ schema_values: Any = schema["properties"].values()
413
+ return any(self.__contains_storable_schema(sub_schema) for sub_schema in schema_values)
414
+ elif schema["type"] == "array" and "items" in schema:
415
+ return self.__contains_storable_schema(schema["items"])
416
+
417
+ return False
424
418
 
425
419
  def __save_db(self) -> None:
426
420
  config: Any = self.__db.get("config") or {}
427
- storable_config = self.__filter_storable_values(self.__schema)
421
+ storable_config = self.__filter_storable_values(self.schema)
428
422
 
429
423
  config[self.__camera_id] = storable_config
430
424
 
@@ -443,4 +437,5 @@ class CameraStorage:
443
437
 
444
438
  def __close(self) -> None:
445
439
  with suppress(Exception):
440
+ self.__save_db()
446
441
  self.__db.close()
@@ -143,6 +143,9 @@ class PluginChild:
143
143
  if not self.message_queue:
144
144
  raise Exception("Message queue not initialized")
145
145
 
146
+ reply = message.copy()
147
+ reply["type"] = "reply"
148
+
146
149
  try:
147
150
  plugin = None
148
151
 
@@ -165,7 +168,7 @@ class PluginChild:
165
168
  else:
166
169
  response = method_to_call(*args)
167
170
 
168
- await self.message_queue.enqueue({**message, "type": "reply", "response": response})
171
+ reply["response"] = response or {}
169
172
  elif camera_storage and hasattr(camera_storage, fn) and callable(getattr(camera_storage, fn)):
170
173
  method_to_call = getattr(camera_storage, fn)
171
174
 
@@ -174,9 +177,9 @@ class PluginChild:
174
177
  else:
175
178
  response = method_to_call(*args)
176
179
 
177
- await self.message_queue.enqueue({**message, "type": "reply", "response": response})
180
+ reply["response"] = response or {}
178
181
  else:
179
- await self.message_queue.enqueue({**message, "type": "reply"})
182
+ raise Exception(f"Unknown function: {fn}")
180
183
  except Exception as e:
181
184
  deserialized_error: DeserializedError = {
182
185
  "name": type(e).__name__,
@@ -184,7 +187,12 @@ class PluginChild:
184
187
  "stack": traceback.format_exc(),
185
188
  }
186
189
 
187
- await self.message_queue.enqueue({**message, "type": "reply", "error": deserialized_error})
190
+ reply["error"] = deserialized_error
191
+
192
+ if message["timeout"] == 0:
193
+ return
194
+ else:
195
+ await self.message_queue.enqueue(reply)
188
196
 
189
197
  async def on_worker_message(self, msg: Msg) -> None:
190
198
  if self.stopped:
@@ -1,2 +1 @@
1
1
  NATS_SERVER_SUBJECT = "camera.ui-server"
2
- NATS_SIGNALING_SUBJECT = "camera.ui-signaling"
@@ -1472,6 +1472,9 @@ class CameraDeviceProxy:
1472
1472
  if not self.message_queue:
1473
1473
  raise Exception("Message queue not initialized")
1474
1474
 
1475
+ reply = message.copy()
1476
+ reply["type"] = "reply"
1477
+
1475
1478
  try:
1476
1479
  if (
1477
1480
  message["client"] == "cameraDelegate"
@@ -1496,7 +1499,7 @@ class CameraDeviceProxy:
1496
1499
  else:
1497
1500
  response = method_to_call(*args)
1498
1501
 
1499
- await self.message_queue.enqueue({**message, "type": "reply", "response": response})
1502
+ reply["response"] = response or {}
1500
1503
  elif message.get("client") == "cameraFn":
1501
1504
  fn: Any = message.get("fn")
1502
1505
  args = message.get("args", [])
@@ -1511,9 +1514,9 @@ class CameraDeviceProxy:
1511
1514
  else:
1512
1515
  response = method_to_call(*args)
1513
1516
 
1514
- await self.message_queue.enqueue({**message, "type": "reply", "response": response})
1517
+ reply["response"] = response or {}
1515
1518
  else:
1516
- await self.message_queue.enqueue({**message, "type": "reply"})
1519
+ raise Exception(f"Unknown client: {message['client']}")
1517
1520
 
1518
1521
  except Exception as e:
1519
1522
  deserialized_error: DeserializedError = {
@@ -1522,7 +1525,12 @@ class CameraDeviceProxy:
1522
1525
  "stack": traceback.format_exc(),
1523
1526
  }
1524
1527
 
1525
- await self.message_queue.enqueue({**message, "type": "reply", "error": deserialized_error})
1528
+ reply["error"] = deserialized_error
1529
+
1530
+ if reply["timeout"] == 0:
1531
+ return
1532
+ else:
1533
+ await self.message_queue.enqueue(reply)
1526
1534
 
1527
1535
  async def __on_proxy_message(self, msg: Msg) -> None:
1528
1536
  if not self.initialized: