@camera.ui/server 2.0.22 → 2.0.24

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 (713) hide show
  1. package/dist/interface/assets/404-CRIhzt2J.js +1 -0
  2. package/dist/interface/assets/About-CvY4xvAU.js +1 -0
  3. package/dist/interface/assets/Adminpanel-4ilp8plp.js +1 -0
  4. package/dist/interface/assets/Automation-uaWWTeTZ.js +3 -0
  5. package/dist/interface/assets/AutomationImport-RNgRv6Uc.js +2 -0
  6. package/dist/interface/assets/AutomationStore-D8plMzVI.js +2 -0
  7. package/dist/interface/assets/AutomationStoreDetail-BO-9XCRn.js +2 -0
  8. package/dist/interface/assets/Automations-PHMVe6wG.js +2 -0
  9. package/dist/interface/assets/Camera-Akukeq4_.js +2 -0
  10. package/dist/interface/assets/CameraConsole-BnKiGukm.js +7 -0
  11. package/dist/interface/assets/Cameras-BuHNAHpD.js +652 -0
  12. package/dist/interface/assets/{Camview-CaEbdeQZ.css → Camview-Cj10uxGy.css} +1 -1
  13. package/dist/interface/assets/Camview-dF8o0iy2.js +1 -0
  14. package/dist/interface/assets/Config-iq-YI9Vg.js +2 -0
  15. package/dist/interface/assets/{ConfigActionCameraControl-DFdb4xzq.js → ConfigActionCameraControl-C2qva2mT.js} +1 -1
  16. package/dist/interface/assets/ConfigActionDelay-C02w0yBx.js +1 -0
  17. package/dist/interface/assets/ConfigActionHttp-DVf26mYG.js +1 -0
  18. package/dist/interface/assets/ConfigActionImageInput-BTlFV7kK.js +1 -0
  19. package/dist/interface/assets/ConfigActionMqtt-CD9RW5Lq.js +1 -0
  20. package/dist/interface/assets/ConfigActionNotification-CjbIPrEb.js +1 -0
  21. package/dist/interface/assets/ConfigActionNotificationControl-BCdKNvgC.js +1 -0
  22. package/dist/interface/assets/ConfigActionOutput-wV9RFDQO.js +1 -0
  23. package/dist/interface/assets/ConfigActionPlugin-DijuNALK.js +1 -0
  24. package/dist/interface/assets/ConfigActionSensor-C9q3sRuI.js +1 -0
  25. package/dist/interface/assets/ConfigActionSnapshot-B79IJLFV.js +1 -0
  26. package/dist/interface/assets/ConfigActionVariable-Do94c7oi.js +1 -0
  27. package/dist/interface/assets/ConfigConditionIfElse-BtbZhnCM.js +1 -0
  28. package/dist/interface/assets/ConfigConditionSensorState-D1V_FhNU.js +1 -0
  29. package/dist/interface/assets/ConfigConditionSwitch-C74dDt3R.js +1 -0
  30. package/dist/interface/assets/ConfigConditionTime-5IrJQgAV.js +1 -0
  31. package/dist/interface/assets/ConfigSensorValueInput-BcbzMf0g.js +1 -0
  32. package/dist/interface/assets/{ConfigTriggerDetection-Cjes6g7x.js → ConfigTriggerDetection-ld9Upgoc.js} +1 -1
  33. package/dist/interface/assets/ConfigTriggerGeofence-DbfBc1AM.js +1 -0
  34. package/dist/interface/assets/ConfigTriggerManual-t-J-HbqF.js +1 -0
  35. package/dist/interface/assets/ConfigTriggerMqtt-i57J8-Nq.js +1 -0
  36. package/dist/interface/assets/ConfigTriggerSchedule-Dv7wIG3G.js +1 -0
  37. package/dist/interface/assets/ConfigTriggerSensor-Ba2lCSGc.js +1 -0
  38. package/dist/interface/assets/{ConfigTriggerSystem-NaaBopYq.js → ConfigTriggerSystem-BWs3rP_W.js} +1 -1
  39. package/dist/interface/assets/ConfigTriggerWebhook-CpQakeYG.js +1 -0
  40. package/dist/interface/assets/Console-BTb5Yc32.js +1 -0
  41. package/dist/interface/assets/CuiAutomationRunsDialog-DX0xpNxx.js +1 -0
  42. package/dist/interface/assets/CuiBottomSheet-Bu0PtwX-.js +1 -0
  43. package/dist/interface/assets/CuiBottomSheet-DIg-nl0p.js +1 -0
  44. package/dist/interface/assets/CuiCameraPipCard-q3yeptLd.js +1 -0
  45. package/dist/interface/assets/CuiCameraRecordings-BWN8gBl4.js +1 -0
  46. package/dist/interface/assets/CuiCameraShares-BggG5Ic_.js +1 -0
  47. package/dist/interface/assets/CuiCameraTable-BCrE4TMJ.js +2 -0
  48. package/dist/interface/assets/CuiDataTable-Dk8LJl5S.js +1 -0
  49. package/dist/interface/assets/CuiLightControl-CaIl2eCO.js +1 -0
  50. package/dist/interface/assets/CuiLightControl-DFrZm_sv.css +1 -0
  51. package/dist/interface/assets/CuiList-Cjbxtb1E.js +1 -0
  52. package/dist/interface/assets/CuiMarkdownContent-Bjs3wRnq.js +1 -0
  53. package/dist/interface/assets/CuiMarkdownContent-Do8-vIl7.js +1 -0
  54. package/dist/interface/assets/CuiPluginCard-cvZkF8Cz.js +2 -0
  55. package/dist/interface/assets/{CuiPluginCategoryChip-D9Vi1SEP.js → CuiPluginCategoryChip-DsEuwQrw.js} +1 -1
  56. package/dist/interface/assets/CuiPluginOAuthButton-Bbwly_xJ.js +2 -0
  57. package/dist/interface/assets/{CuiPluginTrustBadge-D0rUX2i6.js → CuiPluginTrustBadge-BC6F9f-3.js} +1 -1
  58. package/dist/interface/assets/CuiQRCode-DKHFwuhr.js +1 -0
  59. package/dist/interface/assets/CuiRecordingsGrid-DSf7RXci.js +1 -0
  60. package/dist/interface/assets/CuiSchema-Dda4lNPz.js +1 -0
  61. package/dist/interface/assets/CuiTopNavbarItem-BZawroJz.js +1 -0
  62. package/dist/interface/assets/Faces-CvQCD53E.js +1 -0
  63. package/dist/interface/assets/FirstSteps-Dg0Bvjs2.js +1 -0
  64. package/dist/interface/assets/Instances-DisNu3zt.js +1 -0
  65. package/dist/interface/assets/Logs-DSSDjAY-.js +6 -0
  66. package/dist/interface/assets/Menu-CJ-MMxvd.js +1 -0
  67. package/dist/interface/assets/OAuthDeviceFlow-CKTokRaq.js +1 -0
  68. package/dist/interface/assets/Plugin-7daLGUVo.js +1 -0
  69. package/dist/interface/assets/PluginConsole-CcRMneFa.js +7 -0
  70. package/dist/interface/assets/PluginDetail-B1-NdurE.js +2 -0
  71. package/dist/interface/assets/PluginSchema-CP0JWUSD.js +1 -0
  72. package/dist/interface/assets/PluginSearch-BHN0J_JP.js +2 -0
  73. package/dist/interface/assets/PluginSearch-Cx_lzDqC.js +1 -0
  74. package/dist/interface/assets/Plugins-DnMPdcQF.js +1 -0
  75. package/dist/interface/assets/Recordings-Dxs3srmh.js +1 -0
  76. package/dist/interface/assets/SensorEdit-Dq2nV1Wf.js +1 -0
  77. package/dist/interface/assets/SensorHistory-BeCbNWJh.js +1 -0
  78. package/dist/interface/assets/Sensors-BA9P_Ray.css +1 -0
  79. package/dist/interface/assets/Sensors-D9DLdMaD.js +2 -0
  80. package/dist/interface/assets/Settings-DCHoD7r8.js +1 -0
  81. package/dist/interface/assets/SettingsAccount-BrhnlNuF.js +1 -0
  82. package/dist/interface/assets/SettingsAccount-djLxmQ9r.js +1 -0
  83. package/dist/interface/assets/{SettingsAccount-CyNJQSuV.css → SettingsAccount-si-6gWl5.css} +1 -1
  84. package/dist/interface/assets/SettingsAppearance-Bq-xM16S.js +1 -0
  85. package/dist/interface/assets/SettingsAppearance-JKbe5xiH.js +1 -0
  86. package/dist/interface/assets/SettingsBackup-CjlVk3hF.js +1 -0
  87. package/dist/interface/assets/SettingsList-C4mMOKJh.js +1 -0
  88. package/dist/interface/assets/SettingsMqtt-DoYFVHoD.js +1 -0
  89. package/dist/interface/assets/SettingsNotifications-Cmr9Bvy0.js +2 -0
  90. package/dist/interface/assets/SettingsPermissions-D33G-1kM.js +1 -0
  91. package/dist/interface/assets/SettingsRecordings-DYiuW0rA.js +1 -0
  92. package/dist/interface/assets/SettingsRemote-CROA1Oa7.js +1 -0
  93. package/dist/interface/assets/SettingsSystem-rgucO68X.js +2 -0
  94. package/dist/interface/assets/SettingsUsers-2uMPOpyC.js +1 -0
  95. package/dist/interface/assets/Terminal-BMFWoJ_k.js +4 -0
  96. package/dist/interface/assets/VariableInput-Cx9tgiM4.js +1 -0
  97. package/dist/interface/assets/VariableSuggestions-DV_QjTtU.js +1 -0
  98. package/dist/interface/assets/VersionsHandler-v4hH23M_.js +7 -0
  99. package/dist/interface/assets/VirtualSensorCreate-DhuGE1Mf.js +1 -0
  100. package/dist/interface/assets/Workers-DyJXudfY.js +2 -0
  101. package/dist/interface/assets/{account-sFoKqEOV.js → account-C5mHt2Ep.js} +1 -1
  102. package/dist/interface/assets/ace-BqKKexH4.js +1 -0
  103. package/dist/interface/assets/{ace.config-C_wgqTLD.js → ace.config-BNjBs7Fe.js} +1 -1
  104. package/dist/interface/assets/alarm-light-outline-jCTfmz5t.js +1 -0
  105. package/dist/interface/assets/{alert-circle-BQZQ417w.js → alert-circle-Cu_kjPlA.js} +1 -1
  106. package/dist/interface/assets/alert-outline-DXHNnhoP.js +1 -0
  107. package/dist/interface/assets/api-3va2gyB0.css +2 -0
  108. package/dist/interface/assets/{api-DEaXK1Kq.js → api-BKU9IS3U.js} +1 -1
  109. package/dist/interface/assets/api-Cc-rMHwl.js +2 -0
  110. package/dist/interface/assets/arrow-left-DPtWmM6S.js +1 -0
  111. package/dist/interface/assets/arrow-right-outline-BY1ggGA1.js +1 -0
  112. package/dist/interface/assets/{auth-XA5zkqwW.js → auth-B4latCDR.js} +1 -1
  113. package/dist/interface/assets/automationBlueprint-D0F9AHk9.js +1 -0
  114. package/dist/interface/assets/automations-BFkAMu3Y.js +1 -0
  115. package/dist/interface/assets/{back-filled-BdHG6uUx.js → back-filled-r7bN5ObT.js} +1 -1
  116. package/dist/interface/assets/{bell-ring-Dua4zXf_.js → bell-ring-C470qCAb.js} +1 -1
  117. package/dist/interface/assets/{cameras.schema-1a2URPGd.js → cameras.schema-BtaT3B32.js} +1 -1
  118. package/dist/interface/assets/{cctv-DEiPL3U8.js → cctv-BKVOVZCR.js} +1 -1
  119. package/dist/interface/assets/check-circle-Ce_sbfPZ.js +1 -0
  120. package/dist/interface/assets/chevron-down-CjSTp091.js +1 -0
  121. package/dist/interface/assets/chevron-right-B4vB0gm4.js +1 -0
  122. package/dist/interface/assets/{clock-outline-C_f3Ed8x.js → clock-outline-BgcDXoyp.js} +1 -1
  123. package/dist/interface/assets/{close-DNgGJYHi.js → close-CQoGQHOF.js} +1 -1
  124. package/dist/interface/assets/{close-circle-L5juejMg.js → close-circle-DYhkXsRj.js} +1 -1
  125. package/dist/interface/assets/{cloud-check-DD7oRzmo.js → cloud-check-CVx221dJ.js} +1 -1
  126. package/dist/interface/assets/cloudHandoff-CPrXpD0L.js +1 -0
  127. package/dist/interface/assets/{config-C2hgXHyj.js → config-B_lj3Myj.js} +1 -1
  128. package/dist/interface/assets/copy-yhHCVVOa.js +1 -0
  129. package/dist/interface/assets/cube-scan-Ccxismvr.js +1 -0
  130. package/dist/interface/assets/delete-xWUQUP2x.js +1 -0
  131. package/dist/interface/assets/dist-DVb-CALh.js +1 -0
  132. package/dist/interface/assets/download-PLxvyB7s.js +1 -0
  133. package/dist/interface/assets/esm-B4MXP42m.js +1 -0
  134. package/dist/interface/assets/esm-BW9m3dy4.js +1 -0
  135. package/dist/interface/assets/esm-BZ3gh7Fj.js +1 -0
  136. package/dist/interface/assets/esm-Blvz9SsB.js +1 -0
  137. package/dist/interface/assets/esm-CJXU9jaA.js +1 -0
  138. package/dist/interface/assets/esm-Cqqu_mer.js +1 -0
  139. package/dist/interface/assets/esm-CtKbLoV_.js +1 -0
  140. package/dist/interface/assets/esm-CwzNi2iW.js +1 -0
  141. package/dist/interface/assets/esm-KnO8wJyB.js +1 -0
  142. package/dist/interface/assets/esm-Lt6R0RFn.js +1 -0
  143. package/dist/interface/assets/esm-MvRctfDP.js +1 -0
  144. package/dist/interface/assets/esm-W4LX4Rpq.js +1 -0
  145. package/dist/interface/assets/esm-l57LNUWu.js +1 -0
  146. package/dist/interface/assets/esm-xofhyA8r.js +1 -0
  147. package/dist/interface/assets/eye-off-C8kzsdYU.js +1 -0
  148. package/dist/interface/assets/flowSchema-CyZseAPD.js +1 -0
  149. package/dist/interface/assets/{history-iAZcYg3f.js → history-QBEPNc4X.js} +1 -1
  150. package/dist/interface/assets/home-af3W_y8U.js +1 -0
  151. package/dist/interface/assets/{information-outline-CVsB1bl-.js → information-outline-BPCsozSU.js} +1 -1
  152. package/dist/interface/assets/{lightbulb-outline-nNLyXAIp.js → lightbulb-outline-ccTlGyvW.js} +1 -1
  153. package/dist/interface/assets/main-C4qjk6s5.js +3 -0
  154. package/dist/interface/assets/main-aZt-Pooz.css +1 -0
  155. package/dist/interface/assets/{microphone-CU0mFDMh.js → microphone-5exHwwyq.js} +1 -1
  156. package/dist/interface/assets/mqtt-CFw_CCq8.js +1 -0
  157. package/dist/interface/assets/native-Cpj7zrLp.js +1 -0
  158. package/dist/interface/assets/native-D--k2WN1.js +1 -0
  159. package/dist/interface/assets/nodeDefinitions-CRrkU6zR.js +1 -0
  160. package/dist/interface/assets/{notifications-BHQN6WD4.js → notifications-0_glcRlR.js} +1 -1
  161. package/dist/interface/assets/{pencil-outline-BQxLTlZx.js → pencil-outline-M9I4mCJO.js} +1 -1
  162. package/dist/interface/assets/plugin-D3FpjfF8.js +1 -0
  163. package/dist/interface/assets/{plugins-C0RtyBHQ.js → plugins-ICpmsguj.js} +1 -1
  164. package/dist/interface/assets/plus-CGIx-WV8.js +1 -0
  165. package/dist/interface/assets/{plus-Ct6WQfM1.js → plus-CrfQUUEC.js} +1 -1
  166. package/dist/interface/assets/power-VnZM2-0c.js +1 -0
  167. package/dist/interface/assets/{ring-resize-CZBThoQC.js → ring-resize-CodGa6wQ.js} +1 -1
  168. package/dist/interface/assets/rolldown-runtime-C0FnF6B9.js +1 -0
  169. package/dist/interface/assets/{round-alt-arrow-left-bold-BlpNMBxm.js → round-alt-arrow-left-bold-DTrlW4yx.js} +1 -1
  170. package/dist/interface/assets/round-restart-alt-CxUkNgtt.js +1 -0
  171. package/dist/interface/assets/{search-M4Rt52Co.js → search-miJXZGQz.js} +1 -1
  172. package/dist/interface/assets/sensors-Bh5GuQ78.js +1 -0
  173. package/dist/interface/assets/{server-CVSOthzT.js → server-DbpDC3pc.js} +1 -1
  174. package/dist/interface/assets/{settings-CgToKrFd.js → settings-DY0TJSAM.js} +1 -1
  175. package/dist/interface/assets/{source-branch-CoHKTGxb.js → source-branch-nw9fwXin.js} +1 -1
  176. package/dist/interface/assets/{theme-BZi7VV10.js → theme-DlMdsvGC.js} +1 -1
  177. package/dist/interface/assets/{trash-2-BKWfq15D.js → trash-2-B-di2M48.js} +1 -1
  178. package/dist/interface/assets/trash-can-outline-BbZkHoW7.js +1 -0
  179. package/dist/interface/assets/{trash-fill-yNQsFs0Y.js → trash-fill-Bgen5QTD.js} +1 -1
  180. package/dist/interface/assets/{trash2-DjTG9rG-.js → trash2-BP__fHgN.js} +1 -1
  181. package/dist/interface/assets/types-C1VwkReu.js +1 -0
  182. package/dist/interface/assets/{types-Bw8H-UB4.js → types-CggzoTPX.js} +1 -1
  183. package/dist/interface/assets/upload-CNYrnwuV.js +1 -0
  184. package/dist/interface/assets/{useAppVersion-CDTrwxkp.js → useAppVersion-CCxZnwIP.js} +1 -1
  185. package/dist/interface/assets/useBackupRestore-DQQc_D6D.js +1 -0
  186. package/dist/interface/assets/useCameraOptions-DVlhUpbE.js +1 -0
  187. package/dist/interface/assets/{useCardSelection-CgZ7QTaA.js → useCardSelection-B3B2qPHO.js} +1 -1
  188. package/dist/interface/assets/{useElectron-CgLWOhcS.js → useElectron-KnqvZz0q.js} +1 -1
  189. package/dist/interface/assets/useLogsSocket-CUQwZ6wm.js +5 -0
  190. package/dist/interface/assets/{usePermissions-tzi2t12h.js → usePermissions-C3D3JcPH.js} +1 -1
  191. package/dist/interface/assets/useServerRestart-CqZRPCpR.js +1 -0
  192. package/dist/interface/assets/{useStreamStatus-BV_L7pxB.js → useStreamStatus-CVJFHRLZ.js} +1 -1
  193. package/dist/interface/assets/useUserOptions-drl3-JUC.js +1 -0
  194. package/dist/interface/assets/{variable-Y3IAPnsB.js → variable-CbNySf4s.js} +1 -1
  195. package/dist/interface/assets/vendor-CSg6_Jfu.js +22 -0
  196. package/dist/interface/assets/vendor-ace-DIEVbs6L.js +1085 -0
  197. package/dist/interface/assets/vendor-cameraui-Cgb5z6NJ.js +2040 -0
  198. package/dist/interface/assets/vendor-capacitor-C-8IYzpJ.js +2 -0
  199. package/dist/interface/assets/vendor-chart-CoQ9HTE3.js +3 -0
  200. package/dist/interface/assets/vendor-core-BJsSXMFQ.js +1 -0
  201. package/dist/interface/assets/{vendor-dnd-hwiZJHjo.js → vendor-dnd-DQF7Aoap.js} +2 -2
  202. package/dist/interface/assets/vendor-draggabilly-Cghb3aIb.js +1 -0
  203. package/dist/interface/assets/vendor-gridstack-qw2ro2uB.js +3 -0
  204. package/dist/interface/assets/{vendor-leaflet-BMMJO5Nd.js → vendor-leaflet-Bcgd-fkG.js} +1 -1
  205. package/dist/interface/assets/vendor-markdown-DWwrEE67.js +14 -0
  206. package/dist/interface/assets/{vendor-primevue-C6wcTjtT.js → vendor-primevue-CyD8V_Ft.js} +85 -85
  207. package/dist/interface/assets/vendor-vueflow-crUU2mAI.js +26 -0
  208. package/dist/interface/assets/vendor-xterm-BafMBqaV.js +91 -0
  209. package/dist/interface/assets/vendor-zod-Dbq0fBXY.js +127 -0
  210. package/dist/interface/assets/web-BX3axHeB.js +1 -0
  211. package/dist/interface/assets/web-BcHmbPny.js +1 -0
  212. package/dist/interface/assets/web-BjKL51lK-BQjyRtns.js +1 -0
  213. package/dist/interface/assets/web-C8w-z-xR.js +1 -0
  214. package/dist/interface/assets/web-CHdniv8I.js +1 -0
  215. package/dist/interface/assets/web-CWBhY0Av.js +1 -0
  216. package/dist/interface/assets/web-Cf1yYy4u.js +1 -0
  217. package/dist/interface/assets/web-Ct6Vkr6F.js +1 -0
  218. package/dist/interface/assets/web-DARDw7d8.js +1 -0
  219. package/dist/interface/assets/web-DKBMdBSA.js +1 -0
  220. package/dist/interface/assets/web-Ddzvp-fv.js +1 -0
  221. package/dist/interface/assets/web-Dymr_MpD.js +1 -0
  222. package/dist/interface/assets/web-XIuTPdFc.js +1 -0
  223. package/dist/interface/assets/web-lrnXIJTz.js +1 -0
  224. package/dist/interface/assets/{webhook-yCryYojY.js → webhook-B7YgiSrF.js} +1 -1
  225. package/dist/interface/assets/workbox-window.prod.es5-BkFwsIPp.js +1 -0
  226. package/dist/interface/assets/{zoom-in-Da5uRiQq.js → zoom-in-D7BJNotF.js} +1 -1
  227. package/dist/interface/index.html +44 -40
  228. package/dist/interface/sw.js +1 -1
  229. package/dist/server/package.json +11 -11
  230. package/dist/server/requirements.txt +4 -6
  231. package/dist/server/src/_camera_ui_tools/camera_ui_rpc/client.py +3 -0
  232. package/dist/server/src/_camera_ui_tools/camera_ui_rpc/types.py +4 -0
  233. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/__init__.py +9 -14
  234. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/__init__.py +0 -4
  235. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/config.py +5 -12
  236. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/detection.py +6 -23
  237. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/device.py +60 -100
  238. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/events.py +3 -2
  239. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/frames.py +2 -0
  240. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/internal/__init__.py +2 -20
  241. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/internal/camera_config_internal.py +1 -1
  242. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/internal/camera_enums.py +3 -3
  243. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/internal/event_emitter.py +13 -26
  244. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/internal/manager_rpc.py +2 -5
  245. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/internal/sensor_rpc.py +21 -6
  246. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/internal/shared_utils.py +7 -18
  247. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/manager/__init__.py +91 -29
  248. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/observable/__init__.py +145 -37
  249. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/__init__.py +10 -1
  250. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/api.py +21 -68
  251. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/contract.py +31 -58
  252. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/helper.py +3 -12
  253. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/interfaces.py +137 -99
  254. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/notifier.py +34 -52
  255. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/oauth.py +4 -4
  256. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/__init__.py +3 -4
  257. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/audio.py +45 -39
  258. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/base.py +329 -256
  259. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/battery.py +17 -16
  260. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/classifier.py +31 -27
  261. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/clip.py +14 -12
  262. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/contact.py +11 -10
  263. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/detection.py +34 -22
  264. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/doorbell.py +19 -19
  265. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/face.py +34 -28
  266. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/garage.py +29 -20
  267. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/humidity.py +22 -12
  268. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/leak.py +12 -11
  269. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/license_plate.py +35 -31
  270. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/light.py +22 -18
  271. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/lock.py +26 -19
  272. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/motion.py +28 -27
  273. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/object.py +37 -33
  274. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/occupancy.py +11 -10
  275. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/ptz.py +20 -24
  276. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/security_system.py +22 -22
  277. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/siren.py +17 -16
  278. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/smoke.py +11 -10
  279. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/spec.py +26 -22
  280. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/switch.py +13 -12
  281. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/temperature.py +22 -12
  282. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/storage/__init__.py +56 -38
  283. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/types.py +15 -18
  284. package/dist/server/src/api/controllers/auth.controller.js +2 -1
  285. package/dist/server/src/api/controllers/auth.controller.js.map +1 -1
  286. package/dist/server/src/api/controllers/cameras.controller.d.ts +6 -0
  287. package/dist/server/src/api/controllers/cameras.controller.js +21 -11
  288. package/dist/server/src/api/controllers/cameras.controller.js.map +1 -1
  289. package/dist/server/src/api/controllers/cast.controller.d.ts +11 -0
  290. package/dist/server/src/api/controllers/cast.controller.js +29 -0
  291. package/dist/server/src/api/controllers/cast.controller.js.map +1 -0
  292. package/dist/server/src/api/controllers/notifications.controller.d.ts +12 -0
  293. package/dist/server/src/api/controllers/notifications.controller.js +41 -0
  294. package/dist/server/src/api/controllers/notifications.controller.js.map +1 -1
  295. package/dist/server/src/api/controllers/nvr.controller.d.ts +14 -0
  296. package/dist/server/src/api/controllers/nvr.controller.js +61 -0
  297. package/dist/server/src/api/controllers/nvr.controller.js.map +1 -0
  298. package/dist/server/src/api/controllers/sensors.controller.d.ts +13 -0
  299. package/dist/server/src/api/controllers/sensors.controller.js +94 -0
  300. package/dist/server/src/api/controllers/sensors.controller.js.map +1 -0
  301. package/dist/server/src/api/controllers/server.controller.d.ts +1 -0
  302. package/dist/server/src/api/controllers/server.controller.js +11 -0
  303. package/dist/server/src/api/controllers/server.controller.js.map +1 -1
  304. package/dist/server/src/api/controllers/tunnel.controller.d.ts +0 -3
  305. package/dist/server/src/api/controllers/tunnel.controller.js +1 -21
  306. package/dist/server/src/api/controllers/tunnel.controller.js.map +1 -1
  307. package/dist/server/src/api/database/constants.d.ts +2 -0
  308. package/dist/server/src/api/database/constants.js +2 -0
  309. package/dist/server/src/api/database/constants.js.map +1 -1
  310. package/dist/server/src/api/database/index.d.ts +5 -2
  311. package/dist/server/src/api/database/index.js +7 -4
  312. package/dist/server/src/api/database/index.js.map +1 -1
  313. package/dist/server/src/api/database/migrations/v2-1-0.d.ts +3 -0
  314. package/dist/server/src/api/database/migrations/v2-1-0.js +72 -0
  315. package/dist/server/src/api/database/migrations/v2-1-0.js.map +1 -0
  316. package/dist/server/src/api/database/record-schemas.d.ts +2 -3
  317. package/dist/server/src/api/database/record-schemas.js +3 -3
  318. package/dist/server/src/api/database/record-schemas.js.map +1 -1
  319. package/dist/server/src/api/database/types.d.ts +27 -3
  320. package/dist/server/src/api/index.js +3 -0
  321. package/dist/server/src/api/index.js.map +1 -1
  322. package/dist/server/src/api/plugins/natsSubFirewall.d.ts +1 -1
  323. package/dist/server/src/api/plugins/natsSubFirewall.js +5 -2
  324. package/dist/server/src/api/plugins/natsSubFirewall.js.map +1 -1
  325. package/dist/server/src/api/plugins/proxy.plugin.js +5 -3
  326. package/dist/server/src/api/plugins/proxy.plugin.js.map +1 -1
  327. package/dist/server/src/api/routes/cameras.routes.js +14 -7
  328. package/dist/server/src/api/routes/cameras.routes.js.map +1 -1
  329. package/dist/server/src/api/routes/cast.routes.d.ts +2 -0
  330. package/dist/server/src/api/routes/cast.routes.js +29 -0
  331. package/dist/server/src/api/routes/cast.routes.js.map +1 -0
  332. package/dist/server/src/api/routes/index.js +6 -2
  333. package/dist/server/src/api/routes/index.js.map +1 -1
  334. package/dist/server/src/api/routes/notifications.routes.js +32 -0
  335. package/dist/server/src/api/routes/notifications.routes.js.map +1 -1
  336. package/dist/server/src/api/routes/nvr.routes.d.ts +2 -0
  337. package/dist/server/src/api/routes/nvr.routes.js +19 -0
  338. package/dist/server/src/api/routes/nvr.routes.js.map +1 -0
  339. package/dist/server/src/api/routes/sensors.routes.d.ts +2 -0
  340. package/dist/server/src/api/routes/sensors.routes.js +89 -0
  341. package/dist/server/src/api/routes/sensors.routes.js.map +1 -0
  342. package/dist/server/src/api/routes/server.routes.js +10 -0
  343. package/dist/server/src/api/routes/server.routes.js.map +1 -1
  344. package/dist/server/src/api/schemas/cameras.schema.d.ts +103 -45
  345. package/dist/server/src/api/schemas/cameras.schema.js +7 -10
  346. package/dist/server/src/api/schemas/cameras.schema.js.map +1 -1
  347. package/dist/server/src/api/schemas/cast.schema.d.ts +7 -0
  348. package/dist/server/src/api/schemas/cast.schema.js +7 -0
  349. package/dist/server/src/api/schemas/cast.schema.js.map +1 -0
  350. package/dist/server/src/api/schemas/nvr.schema.d.ts +10 -0
  351. package/dist/server/src/api/schemas/nvr.schema.js +13 -0
  352. package/dist/server/src/api/schemas/nvr.schema.js.map +1 -0
  353. package/dist/server/src/api/schemas/{virtualsensors.schema.d.ts → sensors.schema.d.ts} +15 -8
  354. package/dist/server/src/api/schemas/sensors.schema.js +25 -0
  355. package/dist/server/src/api/schemas/sensors.schema.js.map +1 -0
  356. package/dist/server/src/api/schemas/users.schema.d.ts +7 -18
  357. package/dist/server/src/api/schemas/users.schema.js +3 -7
  358. package/dist/server/src/api/schemas/users.schema.js.map +1 -1
  359. package/dist/server/src/api/services/cameras.service.js +1 -1
  360. package/dist/server/src/api/services/cameras.service.js.map +1 -1
  361. package/dist/server/src/api/services/cast.service.d.ts +7 -0
  362. package/dist/server/src/api/services/cast.service.js +14 -0
  363. package/dist/server/src/api/services/cast.service.js.map +1 -0
  364. package/dist/server/src/api/services/instances.service.js +1 -1
  365. package/dist/server/src/api/services/notifications.service.d.ts +3 -0
  366. package/dist/server/src/api/services/notifications.service.js +9 -0
  367. package/dist/server/src/api/services/notifications.service.js.map +1 -1
  368. package/dist/server/src/api/services/plugins.service.js +18 -3
  369. package/dist/server/src/api/services/plugins.service.js.map +1 -1
  370. package/dist/server/src/api/services/sensors.service.d.ts +41 -0
  371. package/dist/server/src/api/services/sensors.service.js +106 -0
  372. package/dist/server/src/api/services/sensors.service.js.map +1 -0
  373. package/dist/server/src/api/services/server.service.d.ts +4 -0
  374. package/dist/server/src/api/services/server.service.js +14 -0
  375. package/dist/server/src/api/services/server.service.js.map +1 -1
  376. package/dist/server/src/api/services/users.service.js +6 -9
  377. package/dist/server/src/api/services/users.service.js.map +1 -1
  378. package/dist/server/src/api/types/index.d.ts +19 -6
  379. package/dist/server/src/api/websocket/nsp/events.js +38 -15
  380. package/dist/server/src/api/websocket/nsp/events.js.map +1 -1
  381. package/dist/server/src/api.d.ts +0 -2
  382. package/dist/server/src/api.js +0 -12
  383. package/dist/server/src/api.js.map +1 -1
  384. package/dist/server/src/automations/actions/sensor.js +4 -7
  385. package/dist/server/src/automations/actions/sensor.js.map +1 -1
  386. package/dist/server/src/automations/conditions/sensorState.js +4 -4
  387. package/dist/server/src/automations/conditions/sensorState.js.map +1 -1
  388. package/dist/server/src/automations/context.d.ts +2 -1
  389. package/dist/server/src/automations/context.js +2 -1
  390. package/dist/server/src/automations/context.js.map +1 -1
  391. package/dist/server/src/automations/pluginMethodRegistry.d.ts +2 -0
  392. package/dist/server/src/automations/pluginMethodRegistry.js +14 -0
  393. package/dist/server/src/automations/pluginMethodRegistry.js.map +1 -1
  394. package/dist/server/src/automations/triggers/sensor.js +12 -23
  395. package/dist/server/src/automations/triggers/sensor.js.map +1 -1
  396. package/dist/server/src/camera/controller.d.ts +0 -1
  397. package/dist/server/src/camera/controller.js +9 -46
  398. package/dist/server/src/camera/controller.js.map +1 -1
  399. package/dist/server/src/camera/decoder/detection-coordinator.js +13 -11
  400. package/dist/server/src/camera/decoder/detection-coordinator.js.map +1 -1
  401. package/dist/server/src/camera/decoder/plugin-registry.d.ts +1 -0
  402. package/dist/server/src/camera/decoder/plugin-registry.js +13 -1
  403. package/dist/server/src/camera/decoder/plugin-registry.js.map +1 -1
  404. package/dist/server/src/camera/decoder/ptz/autotracker.js +2 -2
  405. package/dist/server/src/camera/decoder/ptz/autotracker.js.map +1 -1
  406. package/dist/server/src/camera/decoder/secondary-stage.js +6 -6
  407. package/dist/server/src/camera/decoder/secondary-stage.js.map +1 -1
  408. package/dist/server/src/camera/decoder/types.d.ts +7 -1
  409. package/dist/server/src/camera/decoder/types.js +4 -0
  410. package/dist/server/src/camera/decoder/types.js.map +1 -1
  411. package/dist/server/src/camera/decoder/worker.d.ts +2 -0
  412. package/dist/server/src/camera/decoder/worker.js +14 -3
  413. package/dist/server/src/camera/decoder/worker.js.map +1 -1
  414. package/dist/server/src/camera/index.d.ts +2 -14
  415. package/dist/server/src/camera/index.js +1 -32
  416. package/dist/server/src/camera/index.js.map +1 -1
  417. package/dist/server/src/camera/sensors/controller.d.ts +17 -77
  418. package/dist/server/src/camera/sensors/controller.js +60 -445
  419. package/dist/server/src/camera/sensors/controller.js.map +1 -1
  420. package/dist/server/src/internal-bus.d.ts +7 -13
  421. package/dist/server/src/internal-bus.js.map +1 -1
  422. package/dist/server/src/main.d.ts +1 -0
  423. package/dist/server/src/main.js +7 -0
  424. package/dist/server/src/main.js.map +1 -1
  425. package/dist/server/src/manager/castManager.d.ts +24 -0
  426. package/dist/server/src/manager/castManager.js +79 -0
  427. package/dist/server/src/manager/castManager.js.map +1 -0
  428. package/dist/server/src/manager/downloadManager.d.ts +1 -0
  429. package/dist/server/src/manager/downloadManager.js +6 -0
  430. package/dist/server/src/manager/downloadManager.js.map +1 -1
  431. package/dist/server/src/manager/notificationManager.d.ts +6 -0
  432. package/dist/server/src/manager/notificationManager.js +70 -3
  433. package/dist/server/src/manager/notificationManager.js.map +1 -1
  434. package/dist/server/src/mqtt/bridge.d.ts +7 -0
  435. package/dist/server/src/mqtt/bridge.js +92 -32
  436. package/dist/server/src/mqtt/bridge.js.map +1 -1
  437. package/dist/server/src/mqtt/ha-discovery.d.ts +1 -1
  438. package/dist/server/src/mqtt/ha-discovery.js +53 -8
  439. package/dist/server/src/mqtt/ha-discovery.js.map +1 -1
  440. package/dist/server/src/mqtt/manager.js +1 -1
  441. package/dist/server/src/mqtt/manager.js.map +1 -1
  442. package/dist/server/src/mqtt/topics.d.ts +3 -3
  443. package/dist/server/src/mqtt/topics.js +11 -10
  444. package/dist/server/src/mqtt/topics.js.map +1 -1
  445. package/dist/server/src/plugins/config-store.js +1 -1
  446. package/dist/server/src/plugins/config-store.js.map +1 -1
  447. package/dist/server/src/plugins/runtime/base.d.ts +1 -0
  448. package/dist/server/src/plugins/runtime/base.js +29 -6
  449. package/dist/server/src/plugins/runtime/base.js.map +1 -1
  450. package/dist/server/src/plugins/runtime/node/child.js +5 -2
  451. package/dist/server/src/plugins/runtime/node/child.js.map +1 -1
  452. package/dist/server/src/plugins/runtime/node/pluginApi.d.ts +2 -0
  453. package/dist/server/src/plugins/runtime/node/pluginApi.js +4 -1
  454. package/dist/server/src/plugins/runtime/node/pluginApi.js.map +1 -1
  455. package/dist/server/src/plugins/runtime/node/proxy/cameraDevice.d.ts +5 -13
  456. package/dist/server/src/plugins/runtime/node/proxy/cameraDevice.js +97 -179
  457. package/dist/server/src/plugins/runtime/node/proxy/cameraDevice.js.map +1 -1
  458. package/dist/server/src/plugins/runtime/node/proxy/deviceManager.d.ts +2 -1
  459. package/dist/server/src/plugins/runtime/node/proxy/deviceManager.js +26 -7
  460. package/dist/server/src/plugins/runtime/node/proxy/deviceManager.js.map +1 -1
  461. package/dist/server/src/plugins/runtime/node/proxy/reconnect.d.ts +2 -0
  462. package/dist/server/src/plugins/runtime/node/proxy/reconnect.js +27 -0
  463. package/dist/server/src/plugins/runtime/node/proxy/reconnect.js.map +1 -0
  464. package/dist/server/src/plugins/runtime/node/proxy/sensor.d.ts +17 -3
  465. package/dist/server/src/plugins/runtime/node/proxy/sensor.js +61 -20
  466. package/dist/server/src/plugins/runtime/node/proxy/sensor.js.map +1 -1
  467. package/dist/server/src/plugins/runtime/node/proxy/sensorManager.d.ts +18 -0
  468. package/dist/server/src/plugins/runtime/node/proxy/sensorManager.js +269 -0
  469. package/dist/server/src/plugins/runtime/node/proxy/sensorManager.js.map +1 -0
  470. package/dist/server/src/plugins/runtime/node/storage.d.ts +1 -1
  471. package/dist/server/src/plugins/runtime/node/storage.js +10 -7
  472. package/dist/server/src/plugins/runtime/node/storage.js.map +1 -1
  473. package/dist/server/src/plugins/runtime/node/storageController.d.ts +5 -7
  474. package/dist/server/src/plugins/runtime/node/storageController.js +18 -43
  475. package/dist/server/src/plugins/runtime/node/storageController.js.map +1 -1
  476. package/dist/server/src/plugins/runtime/python/child.py +13 -7
  477. package/dist/server/src/plugins/runtime/python/namespaces.py +13 -19
  478. package/dist/server/src/plugins/runtime/python/plugin_api.py +10 -1
  479. package/dist/server/src/plugins/runtime/python/proxy/camera_device.py +130 -280
  480. package/dist/server/src/plugins/runtime/python/proxy/device_manager.py +26 -5
  481. package/dist/server/src/plugins/runtime/python/proxy/sensor.py +88 -21
  482. package/dist/server/src/plugins/runtime/python/proxy/sensor_manager.py +386 -0
  483. package/dist/server/src/plugins/runtime/python/storage.py +12 -9
  484. package/dist/server/src/plugins/runtime/python/storage_controller.py +18 -80
  485. package/dist/server/src/plugins/runtime/python/store.py +19 -95
  486. package/dist/server/src/plugins/runtime/python/typings.py +32 -9
  487. package/dist/server/src/plugins/store/layout.d.ts +1 -2
  488. package/dist/server/src/plugins/store/layout.js +9 -56
  489. package/dist/server/src/plugins/store/layout.js.map +1 -1
  490. package/dist/server/src/plugins/store/location.d.ts +2 -3
  491. package/dist/server/src/plugins/store/location.js +5 -13
  492. package/dist/server/src/plugins/store/location.js.map +1 -1
  493. package/dist/server/src/plugins/store/pluginStoreFile.d.ts +1 -2
  494. package/dist/server/src/plugins/store/pluginStoreFile.js +8 -15
  495. package/dist/server/src/plugins/store/pluginStoreFile.js.map +1 -1
  496. package/dist/server/src/plugins/worker.d.ts +2 -0
  497. package/dist/server/src/plugins/worker.js +26 -7
  498. package/dist/server/src/plugins/worker.js.map +1 -1
  499. package/dist/server/src/rpc/index.d.ts +2 -0
  500. package/dist/server/src/rpc/index.js +5 -0
  501. package/dist/server/src/rpc/index.js.map +1 -1
  502. package/dist/server/src/rpc/interfaces/sensor.d.ts +33 -16
  503. package/dist/server/src/rpc/namespaces.d.ts +17 -8
  504. package/dist/server/src/rpc/namespaces.js +20 -12
  505. package/dist/server/src/rpc/namespaces.js.map +1 -1
  506. package/dist/server/src/rpc/server.js +1 -0
  507. package/dist/server/src/rpc/server.js.map +1 -1
  508. package/dist/server/src/sensors/registry.d.ts +96 -0
  509. package/dist/server/src/sensors/registry.js +814 -0
  510. package/dist/server/src/sensors/registry.js.map +1 -0
  511. package/dist/server/src/{camera/sensors → sensors}/semantics.d.ts +1 -1
  512. package/dist/server/src/{camera/sensors → sensors}/semantics.js +4 -1
  513. package/dist/server/src/sensors/semantics.js.map +1 -0
  514. package/dist/server/src/sensors/sensor.d.ts +58 -0
  515. package/dist/server/src/{camera/sensors → sensors}/sensor.js +43 -32
  516. package/dist/server/src/sensors/sensor.js.map +1 -0
  517. package/dist/server/src/{camera/sensors → sensors}/types.d.ts +2 -0
  518. package/dist/server/src/{camera/sensors → sensors}/types.js +9 -0
  519. package/dist/server/src/sensors/types.js.map +1 -0
  520. package/dist/server/src/{camera/sensors → sensors}/virtual.d.ts +4 -6
  521. package/dist/server/src/{camera/sensors → sensors}/virtual.js +10 -56
  522. package/dist/server/src/sensors/virtual.js.map +1 -0
  523. package/dist/server/src/services/mdns/index.js +4 -0
  524. package/dist/server/src/services/mdns/index.js.map +1 -1
  525. package/package.json +11 -11
  526. package/dist/interface/assets/404-0d936klL.js +0 -1
  527. package/dist/interface/assets/About-BMwYrGrl.js +0 -1
  528. package/dist/interface/assets/Adminpanel-DBsOmAuo.js +0 -1
  529. package/dist/interface/assets/Automation-BLndVfqR.js +0 -3
  530. package/dist/interface/assets/AutomationImport-Ba33juY0.js +0 -2
  531. package/dist/interface/assets/AutomationStore-Bjf1x7go.js +0 -2
  532. package/dist/interface/assets/AutomationStoreDetail-Ko3n3U1U.js +0 -2
  533. package/dist/interface/assets/Automations-BfC8bvkT.js +0 -2
  534. package/dist/interface/assets/Camera-BYDPeH6d.js +0 -2
  535. package/dist/interface/assets/CameraConsole-pVCj1xXI.js +0 -7
  536. package/dist/interface/assets/Cameras-DdokAe_Q.js +0 -652
  537. package/dist/interface/assets/Camview-DmuGSzal.js +0 -1
  538. package/dist/interface/assets/Config-DvVqB0_Y.js +0 -2
  539. package/dist/interface/assets/ConfigActionDelay-B1JjI6bg.js +0 -1
  540. package/dist/interface/assets/ConfigActionHttp-BzGIbeVo.js +0 -1
  541. package/dist/interface/assets/ConfigActionImageInput-C6m2-s8z.js +0 -1
  542. package/dist/interface/assets/ConfigActionMqtt-ByZNQKsg.js +0 -1
  543. package/dist/interface/assets/ConfigActionNotification-YmdMddoN.js +0 -1
  544. package/dist/interface/assets/ConfigActionNotificationControl-2hWDRBpq.js +0 -1
  545. package/dist/interface/assets/ConfigActionOutput-D9k1-jfI.js +0 -1
  546. package/dist/interface/assets/ConfigActionPlugin-DjD_94EX.js +0 -1
  547. package/dist/interface/assets/ConfigActionSensor-fak8jYSC.js +0 -1
  548. package/dist/interface/assets/ConfigActionSnapshot-mwEHXqyk.js +0 -1
  549. package/dist/interface/assets/ConfigActionVariable-kBxNfyOV.js +0 -1
  550. package/dist/interface/assets/ConfigConditionIfElse-CkjmImTD.js +0 -1
  551. package/dist/interface/assets/ConfigConditionSensorState-FE3mFjRe.js +0 -1
  552. package/dist/interface/assets/ConfigConditionSwitch-msqWizIt.js +0 -1
  553. package/dist/interface/assets/ConfigConditionTime-ifPV135b.js +0 -1
  554. package/dist/interface/assets/ConfigSensorValueInput-Bg3SEbSh.js +0 -1
  555. package/dist/interface/assets/ConfigTriggerGeofence-CemaUwl5.js +0 -1
  556. package/dist/interface/assets/ConfigTriggerManual-DWuiq7PC.js +0 -1
  557. package/dist/interface/assets/ConfigTriggerMqtt-DxAoDh2Z.js +0 -1
  558. package/dist/interface/assets/ConfigTriggerSchedule-DDqgMGvp.js +0 -1
  559. package/dist/interface/assets/ConfigTriggerSensor-M6bXqz4k.js +0 -1
  560. package/dist/interface/assets/ConfigTriggerWebhook-CxOXgcJi.js +0 -1
  561. package/dist/interface/assets/Console-CMuW2_8s.js +0 -1
  562. package/dist/interface/assets/CuiAutomationRunsDialog-yh1qHzmS.js +0 -1
  563. package/dist/interface/assets/CuiBottomSheet-BshiVWqw.js +0 -1
  564. package/dist/interface/assets/CuiBottomSheet-DSNyVg5P.js +0 -1
  565. package/dist/interface/assets/CuiCameraPipCard-Cmk0jl6M.js +0 -1
  566. package/dist/interface/assets/CuiCameraRecordings-KU1wIai4.js +0 -1
  567. package/dist/interface/assets/CuiCameraShares-BoR3YQWj.js +0 -1
  568. package/dist/interface/assets/CuiCameraTable-BRPBqU8V.js +0 -2
  569. package/dist/interface/assets/CuiDataTable-BGY4VBtv.js +0 -1
  570. package/dist/interface/assets/CuiList-BSOMR296.js +0 -1
  571. package/dist/interface/assets/CuiMarkdownContent-DEMo42iT.js +0 -1
  572. package/dist/interface/assets/CuiMarkdownContent-Xn_VHwym.js +0 -1
  573. package/dist/interface/assets/CuiPluginCard-CgJb8B1W.js +0 -2
  574. package/dist/interface/assets/CuiPluginOAuthButton-XpEyqoRm.js +0 -2
  575. package/dist/interface/assets/CuiQRCode-QBkbmvRA.js +0 -1
  576. package/dist/interface/assets/CuiRecordingsGrid-CuEl_hhu.js +0 -1
  577. package/dist/interface/assets/CuiSchema-D_cg-H5i.js +0 -1
  578. package/dist/interface/assets/CuiTopNavbarItem-CXijnkK9.js +0 -1
  579. package/dist/interface/assets/Faces-C95mlWaW.js +0 -1
  580. package/dist/interface/assets/FirstSteps-Cpbg7fng.js +0 -1
  581. package/dist/interface/assets/Instances-BgJtM1Xl.js +0 -1
  582. package/dist/interface/assets/Logs-BWXYqm5T.js +0 -6
  583. package/dist/interface/assets/Menu-BO9Zjy1w.js +0 -1
  584. package/dist/interface/assets/OAuthDeviceFlow-NnwqdmBM.js +0 -1
  585. package/dist/interface/assets/Plugin-DQq3xjhe.js +0 -1
  586. package/dist/interface/assets/PluginConsole-BTsVAsKf.js +0 -7
  587. package/dist/interface/assets/PluginDetail-CTyzzZVU.js +0 -2
  588. package/dist/interface/assets/PluginSchema-Bn3pHjQA.js +0 -1
  589. package/dist/interface/assets/PluginSearch-DbXCyUF0.js +0 -1
  590. package/dist/interface/assets/PluginSearch-z0z8Z1gP.js +0 -2
  591. package/dist/interface/assets/Plugins-Cy7e-ty2.js +0 -1
  592. package/dist/interface/assets/Recordings-CWBpGEUf.js +0 -1
  593. package/dist/interface/assets/Settings-CUIORSmm.js +0 -1
  594. package/dist/interface/assets/SettingsAccount-CeJBKpzp.js +0 -1
  595. package/dist/interface/assets/SettingsAccount-CnwVrQx1.js +0 -1
  596. package/dist/interface/assets/SettingsAppearance-BraaC0WF.js +0 -1
  597. package/dist/interface/assets/SettingsAppearance-CZrOTBki.js +0 -1
  598. package/dist/interface/assets/SettingsBackup-y9mb8XZZ.js +0 -1
  599. package/dist/interface/assets/SettingsList-DsKncveQ.js +0 -1
  600. package/dist/interface/assets/SettingsMqtt-DTyyctmQ.js +0 -1
  601. package/dist/interface/assets/SettingsNotifications-SFMt4Yuj.js +0 -2
  602. package/dist/interface/assets/SettingsPermissions-CktJaQzL.js +0 -1
  603. package/dist/interface/assets/SettingsRecordings-Bqguyt6u.js +0 -1
  604. package/dist/interface/assets/SettingsRemote-CTv7bb4g.js +0 -1
  605. package/dist/interface/assets/SettingsSystem-CkCnB34r.js +0 -2
  606. package/dist/interface/assets/SettingsUsers-D8LAGd6F.js +0 -1
  607. package/dist/interface/assets/Terminal-DaR9Ur0_.js +0 -4
  608. package/dist/interface/assets/VariableInput-D0TP_Lmo.js +0 -1
  609. package/dist/interface/assets/VariableSuggestions--vq7928F.js +0 -1
  610. package/dist/interface/assets/VersionsHandler-D9GDdcXr.js +0 -7
  611. package/dist/interface/assets/Workers-CUyRzwJG.js +0 -2
  612. package/dist/interface/assets/ace-DYqf8ZN7.js +0 -1
  613. package/dist/interface/assets/alert-outline-BUvdNY2J.js +0 -1
  614. package/dist/interface/assets/api-DxrxNyIH.js +0 -2
  615. package/dist/interface/assets/api-VZ_wVUpU.css +0 -2
  616. package/dist/interface/assets/arrow-left-LdfKbcre.js +0 -1
  617. package/dist/interface/assets/arrow-right-outline-BbTEhBJq.js +0 -1
  618. package/dist/interface/assets/automationBlueprint-DMjszOs4.js +0 -1
  619. package/dist/interface/assets/automations-51-JMUWD.js +0 -1
  620. package/dist/interface/assets/check-circle-D-utE_P9.js +0 -1
  621. package/dist/interface/assets/chevron-down-OEjMpuec.js +0 -1
  622. package/dist/interface/assets/chevron-right-B3nxd9UE.js +0 -1
  623. package/dist/interface/assets/cloudHandoff-BktPB9rt.js +0 -1
  624. package/dist/interface/assets/copy-BvSzmsFs.js +0 -1
  625. package/dist/interface/assets/delete-B9BZTgya.js +0 -1
  626. package/dist/interface/assets/dist-qdWlJrr0.js +0 -1
  627. package/dist/interface/assets/download-Dp_ssGIE.js +0 -1
  628. package/dist/interface/assets/esm-9VMgxuPI.js +0 -1
  629. package/dist/interface/assets/esm-B69zS8aI.js +0 -1
  630. package/dist/interface/assets/esm-BF94InGP.js +0 -1
  631. package/dist/interface/assets/esm-BHdK6hkk.js +0 -1
  632. package/dist/interface/assets/esm-BYm8JT8N.js +0 -1
  633. package/dist/interface/assets/esm-BwCmHX2G.js +0 -1
  634. package/dist/interface/assets/esm-CL6t-XYT.js +0 -1
  635. package/dist/interface/assets/esm-CXstRMXa.js +0 -1
  636. package/dist/interface/assets/esm-Ckb9rjlL.js +0 -1
  637. package/dist/interface/assets/esm-D4insKbc.js +0 -1
  638. package/dist/interface/assets/esm-DiReJ8YS.js +0 -1
  639. package/dist/interface/assets/esm-Dt_Neag0.js +0 -1
  640. package/dist/interface/assets/esm-GspmWlKf.js +0 -1
  641. package/dist/interface/assets/esm-eezqpB2a.js +0 -1
  642. package/dist/interface/assets/flowSchema-Ckr7CEbZ.js +0 -1
  643. package/dist/interface/assets/home-DL94781-.js +0 -1
  644. package/dist/interface/assets/main-BxM81wMi.css +0 -1
  645. package/dist/interface/assets/main-DOjghmGX.js +0 -3
  646. package/dist/interface/assets/mqtt-COazyb4A.js +0 -1
  647. package/dist/interface/assets/native-WiRjRKUS.js +0 -1
  648. package/dist/interface/assets/native-hhip9y-E.js +0 -1
  649. package/dist/interface/assets/nodeDefinitions-CPyyuw1P.js +0 -1
  650. package/dist/interface/assets/plugin-DIVM640y.js +0 -1
  651. package/dist/interface/assets/plus-CTzaBaTz.js +0 -1
  652. package/dist/interface/assets/power-CvKGepBP.js +0 -1
  653. package/dist/interface/assets/rolldown-runtime-DAXXjFlN.js +0 -1
  654. package/dist/interface/assets/round-restart-alt-D3iswthu.js +0 -1
  655. package/dist/interface/assets/trash-can-outline-HvqPHpF7.js +0 -1
  656. package/dist/interface/assets/types-CDJiWcQ7.js +0 -1
  657. package/dist/interface/assets/upload-B6yqOWqz.js +0 -1
  658. package/dist/interface/assets/useBackupRestore-QuXkc5ZG.js +0 -1
  659. package/dist/interface/assets/useCameraOptions-D5-bI-e6.js +0 -1
  660. package/dist/interface/assets/useLogsSocket-BlAo-xcw.js +0 -5
  661. package/dist/interface/assets/useServerRestart-DctcFWWh.js +0 -1
  662. package/dist/interface/assets/useUserOptions-nuBRgAEk.js +0 -1
  663. package/dist/interface/assets/vendor-ace-CrklN-bc.js +0 -1085
  664. package/dist/interface/assets/vendor-cameraui-B_OCKNGw.js +0 -2040
  665. package/dist/interface/assets/vendor-capacitor-D6T-f6Q_.js +0 -2
  666. package/dist/interface/assets/vendor-chart-DpsXMlB-.js +0 -3
  667. package/dist/interface/assets/vendor-core-zLmLhSHM.js +0 -1
  668. package/dist/interface/assets/vendor-draggabilly-OrLwQbim.js +0 -1
  669. package/dist/interface/assets/vendor-gridstack-C6VKsm_r.js +0 -3
  670. package/dist/interface/assets/vendor-markdown-_OBaDsnU.js +0 -15
  671. package/dist/interface/assets/vendor-nfBMzqgY.js +0 -22
  672. package/dist/interface/assets/vendor-vueflow-B1MUSE71.js +0 -26
  673. package/dist/interface/assets/vendor-xterm-IIYDrBG1.js +0 -142
  674. package/dist/interface/assets/vendor-zod-BaT-dXMv.js +0 -127
  675. package/dist/interface/assets/web-B-SlpbxK.js +0 -1
  676. package/dist/interface/assets/web-B6leYIzJ.js +0 -1
  677. package/dist/interface/assets/web-BLDe3Kn0.js +0 -1
  678. package/dist/interface/assets/web-BT-51W2W.js +0 -1
  679. package/dist/interface/assets/web-BjKL51lK-DHLvmMLr.js +0 -1
  680. package/dist/interface/assets/web-BpRU7MbT.js +0 -1
  681. package/dist/interface/assets/web-CiaJvmq8.js +0 -1
  682. package/dist/interface/assets/web-Cnkt61og.js +0 -1
  683. package/dist/interface/assets/web-CzhM-YH1.js +0 -1
  684. package/dist/interface/assets/web-Da5rcZ2Q.js +0 -1
  685. package/dist/interface/assets/web-DdZjFuTb.js +0 -1
  686. package/dist/interface/assets/web-DnHj9sl9.js +0 -1
  687. package/dist/interface/assets/web-E4Ew4Xhj.js +0 -1
  688. package/dist/interface/assets/web-q63OEDhG.js +0 -1
  689. package/dist/interface/assets/workbox-window.prod.es5-BMiTt6Ad.js +0 -1
  690. package/dist/server/src/_camera_ui_tools/camera_ui_sdk/internal/sensor_triggers.py +0 -4
  691. package/dist/server/src/api/controllers/virtualsensors.controller.d.ts +0 -11
  692. package/dist/server/src/api/controllers/virtualsensors.controller.js +0 -61
  693. package/dist/server/src/api/controllers/virtualsensors.controller.js.map +0 -1
  694. package/dist/server/src/api/routes/virtualsensors.routes.d.ts +0 -2
  695. package/dist/server/src/api/routes/virtualsensors.routes.js +0 -63
  696. package/dist/server/src/api/routes/virtualsensors.routes.js.map +0 -1
  697. package/dist/server/src/api/schemas/virtualsensors.schema.js +0 -14
  698. package/dist/server/src/api/schemas/virtualsensors.schema.js.map +0 -1
  699. package/dist/server/src/api/services/virtualsensors.service.d.ts +0 -20
  700. package/dist/server/src/api/services/virtualsensors.service.js +0 -151
  701. package/dist/server/src/api/services/virtualsensors.service.js.map +0 -1
  702. package/dist/server/src/camera/sensors/semantics.js.map +0 -1
  703. package/dist/server/src/camera/sensors/sensor.d.ts +0 -34
  704. package/dist/server/src/camera/sensors/sensor.js.map +0 -1
  705. package/dist/server/src/camera/sensors/stable-id.d.ts +0 -2
  706. package/dist/server/src/camera/sensors/stable-id.js +0 -17
  707. package/dist/server/src/camera/sensors/stable-id.js.map +0 -1
  708. package/dist/server/src/camera/sensors/types.js.map +0 -1
  709. package/dist/server/src/camera/sensors/virtual.js.map +0 -1
  710. package/dist/server/src/plugins/runtime/python/store_migrate.py +0 -59
  711. package/dist/server/src/plugins/store/migrate.d.ts +0 -1
  712. package/dist/server/src/plugins/store/migrate.js +0 -22
  713. package/dist/server/src/plugins/store/migrate.js.map +0 -1
@@ -1,10 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
+ import contextlib
4
5
  from typing import Any
5
6
 
6
7
  from _camera_ui_tools.camera_ui_common import (
7
8
  LoggerService,
9
+ TaskSet,
8
10
  )
9
11
  from _camera_ui_tools.camera_ui_rpc import CloseHandler, RPCClient
10
12
  from _camera_ui_tools.camera_ui_sdk import (
@@ -27,6 +29,7 @@ from plugins.runtime.python.storage_controller import StorageController
27
29
  from plugins.runtime.python.typings import PluginInfo
28
30
 
29
31
  from .camera_device import CameraDeviceProxy
32
+ from .sensor_manager import SensorManagerProxy
30
33
 
31
34
 
32
35
  class DeviceManagerProxy(DeviceManager):
@@ -34,6 +37,7 @@ class DeviceManagerProxy(DeviceManager):
34
37
  self,
35
38
  proxy: RPCClient,
36
39
  storage_controller: StorageController,
40
+ sensor_manager: SensorManagerProxy,
37
41
  logger: LoggerService,
38
42
  plugin: PluginInfo,
39
43
  ):
@@ -42,11 +46,14 @@ class DeviceManagerProxy(DeviceManager):
42
46
 
43
47
  self.__proxy = proxy
44
48
  self.__storage_controller = storage_controller
49
+ self.__sensor_manager = sensor_manager
45
50
  self.__logger = logger
46
51
  self.__plugin = plugin
47
52
  self.__close_request: CloseHandler | None = None
53
+ self.__event_lock = asyncio.Lock()
48
54
 
49
55
  self.__devices: dict[str, CameraDeviceProxy] = {}
56
+ self.__tasks = TaskSet(name=f"DeviceManager:{plugin['id']}")
50
57
  self.__namespaces: tuple[DeviceManagerNamespaces, PluginNamespaces, DiscoveryManagerNamespaces] = (
51
58
  NamespaceManager.device_manager_namespaces(),
52
59
  NamespaceManager.plugin_namespaces(self.__plugin["id"]),
@@ -72,7 +79,8 @@ class DeviceManagerProxy(DeviceManager):
72
79
 
73
80
  self.__initialized = True
74
81
  self.__close_request = await self.__proxy.on_request(
75
- self.__namespaces[1].plugin_device_manager_subject, self.__on_event_message
82
+ self.__namespaces[1].plugin_device_manager_subject,
83
+ self.__on_event_serialized,
76
84
  )
77
85
 
78
86
  async def getCamera(self, cameraIdOrName: str) -> CameraDeviceProxy | None:
@@ -92,9 +100,15 @@ class DeviceManagerProxy(DeviceManager):
92
100
  async def configureCameras(self, camera_devices: list[CameraDeviceProxy]) -> None:
93
101
  await asyncio.gather(*[self.__get_camera_device(camera_device) for camera_device in camera_devices])
94
102
 
103
+ def on_rpc_reconnected(self) -> None:
104
+ if not self.__initialized:
105
+ return
106
+ self.__tasks.add(self.__refresh_all_devices())
107
+
95
108
  async def close(self) -> None:
96
109
  """Internal method to close the device manager proxy and cleanup resources."""
97
110
  self.__initialized = False
111
+ self.__tasks.remove_all()
98
112
  if self.__close_request:
99
113
  await self.__close_request()
100
114
 
@@ -102,6 +116,15 @@ class DeviceManagerProxy(DeviceManager):
102
116
  await device.cleanup()
103
117
  self.__devices.clear()
104
118
 
119
+ async def __refresh_all_devices(self) -> None:
120
+ for device in list(self.__devices.values()):
121
+ with contextlib.suppress(Exception):
122
+ await device._refresh_states() # pyright: ignore[reportPrivateUsage]
123
+
124
+ async def __on_event_serialized(self, event: Any) -> None:
125
+ async with self.__event_lock:
126
+ await self.__on_event_message(event)
127
+
105
128
  async def __on_event_message(self, event: Any) -> None:
106
129
  if not self.__plugin_instance:
107
130
  self.__logger.warn("Plugin instance not set, cannot handle lifecycle event")
@@ -132,7 +155,7 @@ class DeviceManagerProxy(DeviceManager):
132
155
  if camera_device:
133
156
  await camera_device.cleanup()
134
157
 
135
- await self.__remove_camera_storage(camera_id)
158
+ await self.__storage_controller.releaseCameraStorage(camera_id)
136
159
 
137
160
  if camera_id in self.__devices:
138
161
  del self.__devices[camera_id]
@@ -170,6 +193,7 @@ class DeviceManagerProxy(DeviceManager):
170
193
  camera_device = CameraDeviceProxy(
171
194
  self.__proxy,
172
195
  self.__storage_controller,
196
+ self.__sensor_manager,
173
197
  camera,
174
198
  self.__plugin,
175
199
  camera_logger,
@@ -185,6 +209,3 @@ class DeviceManagerProxy(DeviceManager):
185
209
 
186
210
  async def __create_camera_storage(self, camera_id: str) -> None:
187
211
  await self.__storage_controller.createStorage("camera", camera_id)
188
-
189
- async def __remove_camera_storage(self, camera_id: str) -> None:
190
- await self.__storage_controller.removeStorage("camera", camera_id)
@@ -9,26 +9,36 @@ from _camera_ui_tools.camera_ui_sdk import (
9
9
  SensorType,
10
10
  Subject,
11
11
  )
12
+ from _camera_ui_tools.camera_ui_sdk.internal import SensorJSON
12
13
  from plugins.runtime.python.namespaces import NamespaceManager
13
- from plugins.runtime.python.typings import SensorRefreshedState, StoredSensorData
14
+ from plugins.runtime.python.typings import (
15
+ SensorRefreshedState,
16
+ SensorRegistration,
17
+ StoredSensorData,
18
+ )
14
19
 
15
20
 
21
+ # Cross-process consumer proxy: caches sensor state from broadcasts, forwards Control writes via RPC.
16
22
  class SensorProxy(SensorLike):
17
- def __init__(
18
- self, data: StoredSensorData, proxy: RPCClient, owner_namespace: str, camera_id: str
19
- ) -> None:
23
+ def __init__(self, data: StoredSensorData, proxy: RPCClient, owner_namespace: str) -> None:
20
24
  self._id = data["id"]
21
25
  self._type = data["type"]
22
26
  self._name = data["name"]
23
27
  self._display_name = data.get("displayName", data["name"])
28
+ self._native_id = data.get("nativeId")
24
29
  self._owner_id = data["pluginId"]
25
- self._camera_id = camera_id
30
+ self._assigned_camera_ids: list[str] = list(data.get("assignedCameraIds", []))
31
+ self._assignment_locked = data.get("boundCameraId") is not None
32
+ self._exposed = data.get("exposed", False)
33
+ self._connected = data.get("connected", False)
26
34
  self._proxy = proxy
27
35
  self._properties: dict[str, Any] = dict(data.get("properties", {}))
28
36
  self._capabilities: list[str] = list(data.get("capabilities", []))
29
37
  self._rpc_proxy = proxy.create_proxy(owner_namespace)
30
38
  self._property_changed_subject: Subject[SensorPropertyChangeData] = Subject()
31
39
  self._capabilities_changed_subject: Subject[list[str]] = Subject()
40
+ self._connected_changed_subject: Subject[bool] = Subject()
41
+ self._assignment_changed_subject: Subject[list[str]] = Subject()
32
42
  self._event_subscription: CloseHandler | None = None
33
43
 
34
44
  @property
@@ -51,10 +61,30 @@ class SensorProxy(SensorLike):
51
61
  def displayName(self, value: str) -> None:
52
62
  self._display_name = value
53
63
 
64
+ @property
65
+ def nativeId(self) -> str | None:
66
+ return self._native_id
67
+
54
68
  @property
55
69
  def pluginId(self) -> str:
56
70
  return self._owner_id
57
71
 
72
+ @property
73
+ def assignedCameraIds(self) -> list[str]:
74
+ return self._assigned_camera_ids.copy()
75
+
76
+ @property
77
+ def assignmentLocked(self) -> bool:
78
+ return self._assignment_locked
79
+
80
+ @property
81
+ def connected(self) -> bool:
82
+ return self._connected
83
+
84
+ @property
85
+ def exposed(self) -> bool:
86
+ return self._exposed
87
+
58
88
  @property
59
89
  def capabilities(self) -> list[str]:
60
90
  return self._capabilities.copy()
@@ -79,10 +109,24 @@ class SensorProxy(SensorLike):
79
109
  def onCapabilitiesChanged(self) -> Observable[list[str]]:
80
110
  return self._capabilities_changed_subject.as_observable()
81
111
 
112
+ @property
113
+ def onConnectedChanged(self) -> Observable[bool]:
114
+ return self._connected_changed_subject.as_observable()
115
+
116
+ @property
117
+ def onAssignmentChanged(self) -> Observable[list[str]]:
118
+ return self._assignment_changed_subject.as_observable()
119
+
82
120
  def _update_cached_value(self, property: str, value: Any, timestamp: int | None = None) -> None:
121
+ if self._properties.get(property) == value:
122
+ return
83
123
  self._properties[property] = value
84
124
  self._property_changed_subject.next(
85
- {"property": property, "value": value, "timestamp": timestamp or int(time.time() * 1000)}
125
+ {
126
+ "property": property,
127
+ "value": value,
128
+ "timestamp": timestamp or int(time.time() * 1000),
129
+ }
86
130
  )
87
131
 
88
132
  def _set_display_name(self, display_name: str) -> None:
@@ -92,18 +136,36 @@ class SensorProxy(SensorLike):
92
136
  self._capabilities = capabilities
93
137
  self._capabilities_changed_subject.next(capabilities)
94
138
 
139
+ def _set_connected(self, connected: bool) -> None:
140
+ if self._connected == connected:
141
+ return
142
+ self._connected = connected
143
+ self._connected_changed_subject.next(connected)
144
+
145
+ def _set_assigned_cameras(self, camera_ids: list[str]) -> None:
146
+ self._assigned_camera_ids = list(camera_ids)
147
+ self._assignment_changed_subject.next(self._assigned_camera_ids.copy())
148
+
149
+ def _set_exposed(self, exposed: bool) -> None:
150
+ self._exposed = exposed
151
+
95
152
  def _apply_refreshed_state(self, state: SensorRefreshedState) -> None:
96
- self._capabilities = list(state["capabilities"])
97
- if "displayName" in state:
98
- self._display_name = state["displayName"]
99
- for key, value in state.get("properties", {}).items():
100
- self._update_cached_value(key, value)
153
+ display_name = state.get("displayName")
154
+ if display_name:
155
+ self._set_display_name(display_name)
156
+
157
+ capabilities = list(state.get("capabilities", []))
158
+ if sorted(capabilities) != sorted(self._capabilities):
159
+ self._update_capabilities(capabilities)
160
+
161
+ for property, value in state.get("properties", {}).items():
162
+ self._update_cached_value(property, value)
101
163
 
102
164
  async def _subscribe_to_events(self) -> None:
103
165
  if self._event_subscription is not None:
104
166
  return # Already subscribed
105
167
 
106
- namespace = NamespaceManager.sensor_event_namespaces(self._camera_id, self._id)
168
+ namespace = NamespaceManager.sensor_event_namespaces(self._id)
107
169
  self._event_subscription = await self._proxy.subscribe(
108
170
  namespace.sensor_subject, self._handle_sensor_event
109
171
  )
@@ -133,9 +195,14 @@ class SensorProxy(SensorLike):
133
195
  "name": self._name,
134
196
  "displayName": self._display_name,
135
197
  "pluginId": self._owner_id,
198
+ "assignedCameraIds": self.assignedCameraIds,
199
+ "exposed": self._exposed,
200
+ "connected": self._connected,
136
201
  "properties": self.getValues(),
137
202
  "capabilities": self._capabilities,
138
203
  }
204
+ if self._native_id:
205
+ data["nativeId"] = self._native_id
139
206
 
140
207
  return data
141
208
 
@@ -144,20 +211,22 @@ class SensorProxy(SensorLike):
144
211
  return self._id != ""
145
212
 
146
213
 
147
- class SensorControllerInterface(Protocol):
148
- async def registerSensor(self, sensor: dict[str, Any], plugin_id: str) -> bool: ...
214
+ class SensorRegistryInterface(Protocol):
215
+ async def registerSensor(
216
+ self, sensor: SensorJSON, plugin_id: str, options: dict[str, Any] | None = None
217
+ ) -> SensorRegistration: ...
218
+ async def resolveSensor(
219
+ self, sensor: SensorJSON, plugin_id: str, options: dict[str, Any] | None = None
220
+ ) -> str: ...
149
221
  async def unregisterSensor(self, sensor_id: str) -> None: ...
150
222
  async def updatePropertyValues(self, sensor_id: str, properties: dict[str, Any]) -> None: ...
151
223
  async def updateCapabilities(self, sensor_id: str, capabilities: list[str]) -> None: ...
152
224
  async def getPropertyValue(self, sensor_id: str, property: str) -> Any: ...
153
225
  async def getAllPropertyValues(self, sensor_id: str) -> dict[str, Any]: ...
154
- async def getSensorState(self, sensor_id: str) -> SensorRefreshedState: ...
226
+ async def getSensorState(self, sensor_id: str) -> SensorRefreshedState | None: ...
155
227
  async def getSensorStates(self) -> dict[str, SensorRefreshedState]: ...
156
228
  async def getSensors(self, plugin_id: str | None = None) -> list[StoredSensorData]: ...
157
- async def getSensor(self, sensor_id: str, plugin_id: str | None = None) -> StoredSensorData | None: ...
158
- async def getSensorByType(
159
- self, sensor_type: SensorType, plugin_id: str | None = None
160
- ) -> StoredSensorData | None: ...
229
+ async def getSensorRpc(self, sensor_id: str, plugin_id: str | None = None) -> StoredSensorData | None: ...
161
230
  async def setDisplayName(self, sensor_id: str, display_name: str) -> None: ...
162
231
 
163
232
 
@@ -165,5 +234,3 @@ class DetectionCoordinatorRPC(Protocol):
165
234
  async def reportSensorWrite(
166
235
  self, sensor_id: str, sensor_type: SensorType, properties: dict[str, Any]
167
236
  ) -> None: ...
168
-
169
- async def unregisterSensor(self, sensor_id: str) -> None: ...
@@ -0,0 +1,386 @@
1
+ from __future__ import annotations
2
+
3
+ import contextlib
4
+ from typing import TYPE_CHECKING, Any, cast
5
+
6
+ from _camera_ui_tools.camera_ui_common import TaskSet
7
+ from _camera_ui_tools.camera_ui_sdk import BasePlugin, Sensor, SensorLike, SensorType
8
+ from plugins.runtime.python.namespaces import NamespaceManager
9
+ from plugins.runtime.python.proxy.sensor import (
10
+ DetectionCoordinatorRPC,
11
+ SensorProxy,
12
+ SensorRegistryInterface,
13
+ )
14
+
15
+ if TYPE_CHECKING:
16
+ from _camera_ui_tools.camera_ui_common import LoggerService
17
+ from _camera_ui_tools.camera_ui_rpc import CloseHandler, RPCClient
18
+ from plugins.runtime.python.storage_controller import StorageController
19
+ from plugins.runtime.python.typings import (
20
+ PluginInfo,
21
+ SensorAddedEvent,
22
+ SensorAssignmentChangedEvent,
23
+ SensorConnectedChangedEvent,
24
+ SensorDeletedEvent,
25
+ SensorEventMessage,
26
+ SensorExposedChangedEvent,
27
+ StoredSensorData,
28
+ )
29
+
30
+ DETECTION_SENSOR_TYPES: frozenset[SensorType] = frozenset(
31
+ {
32
+ SensorType.Motion,
33
+ SensorType.Audio,
34
+ SensorType.Object,
35
+ SensorType.ObjectAssist,
36
+ SensorType.Face,
37
+ SensorType.LicensePlate,
38
+ SensorType.Classifier,
39
+ SensorType.Clip,
40
+ }
41
+ )
42
+
43
+
44
+ class SensorManagerProxy:
45
+ def __init__(
46
+ self,
47
+ proxy: RPCClient,
48
+ storage_controller: StorageController,
49
+ plugin: PluginInfo,
50
+ logger: LoggerService,
51
+ ) -> None:
52
+ self._proxy = proxy
53
+ self._storage_controller = storage_controller
54
+ self._plugin = plugin
55
+ self._logger = logger
56
+ self._plugin_instance: BasePlugin | None = None
57
+
58
+ self._owned: dict[str, Sensor[Any, Any, Any]] = {}
59
+ self._cleanups: dict[str, CloseHandler] = {}
60
+ self._external: dict[str, Sensor[Any, Any, Any]] = {}
61
+ self._consumed: dict[str, SensorProxy] = {}
62
+ self._global_unsubscribe: CloseHandler | None = None
63
+ self._closed = False
64
+
65
+ self._tasks = TaskSet(name=f"SensorManager:{plugin['id']}")
66
+
67
+ def set_plugin(self, plugin: BasePlugin) -> None:
68
+ self._plugin_instance = plugin
69
+
70
+ @property
71
+ def _registry_proxy(self) -> SensorRegistryInterface:
72
+ ns = NamespaceManager.sensor_registry_namespaces()
73
+ return self._proxy.create_proxy(ns.sensors_rpc)
74
+
75
+ @property
76
+ def _consumes_something(self) -> bool:
77
+ return len(self._plugin["contract"].get("consumes", [])) > 0
78
+
79
+ async def init(self) -> None:
80
+ if not self._consumes_something:
81
+ return
82
+
83
+ await self._ensure_global_subscription()
84
+
85
+ try:
86
+ sensors = await self._registry_proxy.getSensors(self._plugin["id"])
87
+ for data in sensors:
88
+ if not self._is_consumable(data):
89
+ continue
90
+ self._add_consumed(data)
91
+ except Exception:
92
+ # registry not reachable yet, sensors arrive via events
93
+ pass
94
+
95
+ for sensor_proxy in self._consumed.values():
96
+ await sensor_proxy._subscribe_to_events() # pyright: ignore[reportPrivateUsage]
97
+
98
+ if self._plugin_instance:
99
+ await self._plugin_instance.configureSensors(
100
+ cast("list[SensorLike]", list(self._consumed.values()))
101
+ )
102
+
103
+ async def addSensor(self, sensor: Sensor[Any, Any, Any]) -> None:
104
+ # pre-standalone SDK: its toJSON reads the removed cameraId getter and throws, drop the guard with the stub window
105
+ if not callable(getattr(sensor, "_setId", None)):
106
+ self._logger.warn(
107
+ f'Plugin "{self._plugin["id"]}" uses a pre-standalone SDK, sensor "{sensor.name}" stays unavailable. Update the plugin.'
108
+ )
109
+ return
110
+
111
+ # producers need the global stream too: assignment changes must reach
112
+ # owned sensors, their detection fan-out reads assignedCameraIds
113
+ await self._ensure_global_subscription()
114
+
115
+ plugin_id = self._plugin["id"]
116
+ sensor._setPluginId(plugin_id) # pyright: ignore[reportPrivateUsage]
117
+
118
+ sensor_json = sensor.toJSON()
119
+ sensor_json["requiresFrames"] = getattr(sensor, "_requires_frames", False) is True
120
+
121
+ # resolve the durable id first and wire storage with it, so registration
122
+ # data (modelSpec) can read sensor storage
123
+ sensor_id = await self._registry_proxy.resolveSensor(sensor_json, plugin_id)
124
+ sensor._setId(sensor_id) # pyright: ignore[reportPrivateUsage]
125
+ sensor_json["id"] = sensor_id
126
+
127
+ storage = self._storage_controller.createSensorStorage(plugin_id, sensor.id, sensor.storage_schema)
128
+ await storage.register_storage()
129
+ sensor._setStorage(storage) # pyright: ignore[reportPrivateUsage]
130
+
131
+ model_spec = getattr(sensor, "modelSpec", None)
132
+ if model_spec:
133
+ sensor_json["modelSpec"] = model_spec
134
+
135
+ registration = await self._registry_proxy.registerSensor(sensor_json, plugin_id)
136
+ sensor._setAssignedCameras(registration["assignedCameraIds"]) # pyright: ignore[reportPrivateUsage]
137
+
138
+ sensor_namespace = NamespaceManager.sensor_provider_namespaces(plugin_id, sensor.id).sensor_rpc
139
+
140
+ sensor_type = sensor.type
141
+ sensor._init( # pyright: ignore[reportPrivateUsage]
142
+ lambda properties: self._on_sensor_state_write(sensor, sensor_type, properties)
143
+ )
144
+ sensor._initCapabilities(lambda caps: self._on_sensor_capabilities_changed(sensor.id, caps)) # pyright: ignore[reportPrivateUsage]
145
+
146
+ rpc_cleanup = await self._proxy.register_handler(sensor_namespace, sensor, without_decorators=True)
147
+
148
+ event_ns = NamespaceManager.sensor_event_namespaces(sensor.id)
149
+
150
+ async def handle_backend_event(event: dict[str, Any]) -> None:
151
+ if event.get("type") == "property:changed":
152
+ change_data = event.get("data", {})
153
+ prop = change_data.get("property")
154
+ if prop is not None:
155
+ sensor._onBackendPropertyChanged( # pyright: ignore[reportPrivateUsage]
156
+ prop, change_data.get("value"), change_data.get("timestamp")
157
+ )
158
+
159
+ unsubscribe_events = await self._proxy.subscribe(event_ns.sensor_subject, handle_backend_event)
160
+
161
+ async def cleanup() -> None:
162
+ await unsubscribe_events()
163
+ await rpc_cleanup()
164
+
165
+ self._owned[sensor.id] = sensor
166
+ self._cleanups[sensor.id] = cleanup
167
+
168
+ sensor._setActive(True) # pyright: ignore[reportPrivateUsage]
169
+
170
+ async def removeSensor(self, sensor: Sensor[Any, Any, Any]) -> None:
171
+ try:
172
+ await self._registry_proxy.unregisterSensor(sensor.id)
173
+ except Exception as e:
174
+ self._logger.warn(f"Failed to unregister sensor {sensor.id}: {e}")
175
+
176
+ cleanup = self._cleanups.pop(sensor.id, None)
177
+ if cleanup:
178
+ await cleanup()
179
+
180
+ self._owned.pop(sensor.id, None)
181
+ sensor._cleanup() # pyright: ignore[reportPrivateUsage]
182
+
183
+ def getSensors(self) -> list[Sensor[Any, Any, Any]]:
184
+ return list(self._owned.values())
185
+
186
+ # keeps a camera-registered sensor's assignedCameraIds in sync with the global stream
187
+ async def track_camera_sensor(self, sensor: Sensor[Any, Any, Any]) -> None:
188
+ await self._ensure_global_subscription()
189
+ self._external[sensor.id] = sensor
190
+
191
+ def untrack_camera_sensor(self, sensor_id: str) -> None:
192
+ self._external.pop(sensor_id, None)
193
+
194
+ def on_rpc_reconnected(self) -> None:
195
+ if self._closed:
196
+ return
197
+ self._tasks.add(self._resync_all_consumed())
198
+
199
+ async def close(self) -> None:
200
+ self._closed = True
201
+
202
+ if self._global_unsubscribe:
203
+ with contextlib.suppress(Exception):
204
+ await self._global_unsubscribe()
205
+ self._global_unsubscribe = None
206
+
207
+ for sensor_proxy in self._consumed.values():
208
+ with contextlib.suppress(Exception):
209
+ await sensor_proxy._unsubscribe_from_events() # pyright: ignore[reportPrivateUsage]
210
+ self._consumed.clear()
211
+ self._external.clear()
212
+
213
+ for cleanup in list(self._cleanups.values()):
214
+ with contextlib.suppress(Exception):
215
+ await cleanup()
216
+ self._cleanups.clear()
217
+
218
+ for sensor in self._owned.values():
219
+ sensor._cleanup() # pyright: ignore[reportPrivateUsage]
220
+ self._owned.clear()
221
+
222
+ self._tasks.remove_all()
223
+
224
+ async def _ensure_global_subscription(self) -> None:
225
+ if self._global_unsubscribe is not None:
226
+ return
227
+
228
+ ns = NamespaceManager.sensor_registry_namespaces()
229
+ self._global_unsubscribe = await self._proxy.subscribe(
230
+ ns.sensors_subject, self._on_global_sensor_event
231
+ )
232
+
233
+ async def _resync_all_consumed(self) -> None:
234
+ for sensor_id in list(self._consumed):
235
+ await self._resync_consumed(sensor_id)
236
+
237
+ async def _resync_consumed(self, sensor_id: str) -> None:
238
+ sensor_proxy = self._consumed.get(sensor_id)
239
+ if not sensor_proxy:
240
+ return
241
+
242
+ try:
243
+ state = await self._registry_proxy.getSensorState(sensor_id)
244
+ except Exception:
245
+ # owner or registry unreachable, the next re-announce carries the state
246
+ return
247
+
248
+ if state:
249
+ sensor_proxy._apply_refreshed_state(state) # pyright: ignore[reportPrivateUsage]
250
+
251
+ def _is_consumable(self, data: StoredSensorData) -> bool:
252
+ if data["id"] in self._owned or data["pluginId"] == self._plugin["id"]:
253
+ return False
254
+ if not data.get("exposed", False):
255
+ return False
256
+ return data["type"] in self._plugin["contract"].get("consumes", [])
257
+
258
+ def _add_consumed(self, data: StoredSensorData) -> SensorProxy:
259
+ owner_namespace = NamespaceManager.sensor_provider_namespaces(data["pluginId"], data["id"]).sensor_rpc
260
+ sensor_proxy = SensorProxy(data, self._proxy, owner_namespace)
261
+ self._consumed[data["id"]] = sensor_proxy
262
+ return sensor_proxy
263
+
264
+ async def _release_consumed(self, sensor_id: str) -> None:
265
+ sensor_proxy = self._consumed.pop(sensor_id, None)
266
+ if not sensor_proxy:
267
+ return
268
+
269
+ with contextlib.suppress(Exception):
270
+ await sensor_proxy._unsubscribe_from_events() # pyright: ignore[reportPrivateUsage]
271
+
272
+ if self._plugin_instance:
273
+ with contextlib.suppress(Exception):
274
+ await self._plugin_instance.onSensorReleased(sensor_id)
275
+
276
+ def _on_global_sensor_event(self, message: SensorEventMessage) -> None:
277
+ async def handle() -> None:
278
+ try:
279
+ await self._handle_global_sensor_event(message)
280
+ except Exception as e:
281
+ self._logger.warn(f"Sensor event handling failed: {e}")
282
+
283
+ self._tasks.add(handle())
284
+
285
+ async def _handle_global_sensor_event(self, message: SensorEventMessage) -> None:
286
+ event_type = message.get("type")
287
+
288
+ if event_type == "sensor:added":
289
+ added = cast("SensorAddedEvent", message.get("data"))
290
+ data = added["sensor"]
291
+ for owned in (self._owned.get(data["id"]), self._external.get(data["id"])):
292
+ if owned:
293
+ owned._setAssignedCameras(data["assignedCameraIds"]) # pyright: ignore[reportPrivateUsage]
294
+ consumed = self._consumed.get(data["id"])
295
+ if consumed is not None:
296
+ # re-announced while we already hold it: the payload is authoritative, our cache may be stale
297
+ consumed._apply_refreshed_state(added["state"]) # pyright: ignore[reportPrivateUsage]
298
+ return
299
+ if not self._is_consumable(data):
300
+ return
301
+ sensor_proxy = self._add_consumed(data)
302
+ await sensor_proxy._subscribe_to_events() # pyright: ignore[reportPrivateUsage]
303
+ if self._plugin_instance:
304
+ await self._plugin_instance.onSensorAdded(sensor_proxy)
305
+
306
+ elif event_type == "sensor:deleted":
307
+ deleted = cast("SensorDeletedEvent", message.get("data"))
308
+ await self._release_consumed(deleted["sensorId"])
309
+
310
+ elif event_type == "sensor:connected:changed":
311
+ connected = cast("SensorConnectedChangedEvent", message.get("data"))
312
+ consumed = self._consumed.get(connected["sensorId"])
313
+ if consumed:
314
+ consumed._set_connected(connected["connected"]) # pyright: ignore[reportPrivateUsage]
315
+ if connected["connected"]:
316
+ # the owner was away, whatever it published in the meantime never reached us
317
+ self._tasks.add(self._resync_consumed(connected["sensorId"]))
318
+
319
+ elif event_type == "sensor:exposed:changed":
320
+ exposed = cast("SensorExposedChangedEvent", message.get("data"))
321
+ if not exposed["exposed"]:
322
+ await self._release_consumed(exposed["sensorId"])
323
+ return
324
+ if exposed["sensorId"] in self._consumed:
325
+ return
326
+ fetched = await self._registry_proxy.getSensorRpc(exposed["sensorId"], self._plugin["id"])
327
+ if not fetched or not self._is_consumable(fetched):
328
+ return
329
+ sensor_proxy = self._add_consumed(fetched)
330
+ await sensor_proxy._subscribe_to_events() # pyright: ignore[reportPrivateUsage]
331
+ if self._plugin_instance:
332
+ await self._plugin_instance.onSensorAdded(sensor_proxy)
333
+
334
+ elif event_type == "sensor:assignment:changed":
335
+ assignment = cast("SensorAssignmentChangedEvent", message.get("data"))
336
+ targets: list[Sensor[Any, Any, Any] | SensorProxy] = []
337
+ for candidate in (
338
+ self._owned.get(assignment["sensorId"]),
339
+ self._external.get(assignment["sensorId"]),
340
+ self._consumed.get(assignment["sensorId"]),
341
+ ):
342
+ if candidate is not None:
343
+ targets.append(candidate)
344
+ for target in targets:
345
+ cameras = set(target.assignedCameraIds)
346
+ if assignment["assigned"]:
347
+ cameras.add(assignment["cameraId"])
348
+ else:
349
+ cameras.discard(assignment["cameraId"])
350
+ if isinstance(target, SensorProxy):
351
+ target._set_assigned_cameras(list(cameras)) # pyright: ignore[reportPrivateUsage]
352
+ else:
353
+ target._setAssignedCameras(list(cameras)) # pyright: ignore[reportPrivateUsage]
354
+
355
+ def _on_sensor_state_write(
356
+ self,
357
+ sensor: Sensor[Any, Any, Any],
358
+ sensor_type: SensorType,
359
+ properties: dict[str, Any],
360
+ ) -> None:
361
+ if sensor_type in DETECTION_SENSOR_TYPES:
362
+ # external detection provider: fan the write into every assigned camera's coordinator
363
+ async def notify_coordinators() -> None:
364
+ for camera_id in sensor.assignedCameraIds:
365
+ detection_ns = NamespaceManager.frame_worker_detection_namespaces(camera_id)
366
+ coordinator: DetectionCoordinatorRPC = self._proxy.create_proxy(
367
+ detection_ns.detection_rpc
368
+ )
369
+ with contextlib.suppress(Exception):
370
+ await coordinator.reportSensorWrite(sensor.id, sensor_type, properties)
371
+
372
+ self._tasks.add(notify_coordinators())
373
+ return
374
+
375
+ async def notify_registry() -> None:
376
+ with contextlib.suppress(Exception):
377
+ await self._registry_proxy.updatePropertyValues(sensor.id, properties)
378
+
379
+ self._tasks.add(notify_registry())
380
+
381
+ def _on_sensor_capabilities_changed(self, sensor_id: str, capabilities: list[str]) -> None:
382
+ async def notify() -> None:
383
+ with contextlib.suppress(Exception):
384
+ await self._registry_proxy.updateCapabilities(sensor_id, capabilities)
385
+
386
+ self._tasks.add(notify())