@camera.ui/server 2.0.22 → 2.0.23

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-junY0N5P.js +1 -0
  2. package/dist/interface/assets/About-Dwc0TTLa.js +1 -0
  3. package/dist/interface/assets/Adminpanel-wZGtsPD-.js +1 -0
  4. package/dist/interface/assets/Automation-Dj6xmGae.js +3 -0
  5. package/dist/interface/assets/AutomationImport-Ccnxyslc.js +2 -0
  6. package/dist/interface/assets/AutomationStore-DmbxA0ml.js +2 -0
  7. package/dist/interface/assets/AutomationStoreDetail-DcbvD8g5.js +2 -0
  8. package/dist/interface/assets/Automations-C9JJO6dy.js +2 -0
  9. package/dist/interface/assets/Camera-D_j0J3kB.js +2 -0
  10. package/dist/interface/assets/CameraConsole--hGg9Ye6.js +7 -0
  11. package/dist/interface/assets/Cameras-B2Tizr4Q.js +652 -0
  12. package/dist/interface/assets/Camview-Bh2UCnGC.js +1 -0
  13. package/dist/interface/assets/{Camview-CaEbdeQZ.css → Camview-Cj10uxGy.css} +1 -1
  14. package/dist/interface/assets/Config-Dn_s2M7r.js +2 -0
  15. package/dist/interface/assets/{ConfigActionCameraControl-DFdb4xzq.js → ConfigActionCameraControl-DQEYHVN5.js} +1 -1
  16. package/dist/interface/assets/ConfigActionDelay-C0mbjCCj.js +1 -0
  17. package/dist/interface/assets/ConfigActionHttp-Bf58WHcw.js +1 -0
  18. package/dist/interface/assets/ConfigActionImageInput-CDXVFrOz.js +1 -0
  19. package/dist/interface/assets/ConfigActionMqtt-lH7MQqWr.js +1 -0
  20. package/dist/interface/assets/ConfigActionNotification-CAkr6NJX.js +1 -0
  21. package/dist/interface/assets/ConfigActionNotificationControl-CiL-4Ytw.js +1 -0
  22. package/dist/interface/assets/ConfigActionOutput-ILAxBT-r.js +1 -0
  23. package/dist/interface/assets/ConfigActionPlugin-B2d4mZiK.js +1 -0
  24. package/dist/interface/assets/ConfigActionSensor-BxMdsmRa.js +1 -0
  25. package/dist/interface/assets/ConfigActionSnapshot-CXVQBSzv.js +1 -0
  26. package/dist/interface/assets/ConfigActionVariable-CABnlnMv.js +1 -0
  27. package/dist/interface/assets/ConfigConditionIfElse-Cxu7TSdJ.js +1 -0
  28. package/dist/interface/assets/ConfigConditionSensorState-rB7I04Gb.js +1 -0
  29. package/dist/interface/assets/ConfigConditionSwitch-CU0hLo1h.js +1 -0
  30. package/dist/interface/assets/ConfigConditionTime-DfeEvxIU.js +1 -0
  31. package/dist/interface/assets/ConfigSensorValueInput-wXiyU3Sc.js +1 -0
  32. package/dist/interface/assets/{ConfigTriggerDetection-Cjes6g7x.js → ConfigTriggerDetection-DFJpuWrs.js} +1 -1
  33. package/dist/interface/assets/ConfigTriggerGeofence-CZwesOD8.js +1 -0
  34. package/dist/interface/assets/ConfigTriggerManual-aibwYUtf.js +1 -0
  35. package/dist/interface/assets/ConfigTriggerMqtt-CUNgifGb.js +1 -0
  36. package/dist/interface/assets/ConfigTriggerSchedule-8Y_OBcB1.js +1 -0
  37. package/dist/interface/assets/ConfigTriggerSensor-Bu-YtGnX.js +1 -0
  38. package/dist/interface/assets/{ConfigTriggerSystem-NaaBopYq.js → ConfigTriggerSystem-CXNvmC4S.js} +1 -1
  39. package/dist/interface/assets/ConfigTriggerWebhook-CkZ-_ABi.js +1 -0
  40. package/dist/interface/assets/Console-CG8eRDA4.js +1 -0
  41. package/dist/interface/assets/CuiAutomationRunsDialog-Ux0g-E3w.js +1 -0
  42. package/dist/interface/assets/CuiBottomSheet-C-ZN_uXE.js +1 -0
  43. package/dist/interface/assets/CuiBottomSheet-RUyuBxJZ.js +1 -0
  44. package/dist/interface/assets/CuiCameraPipCard-B-B6Ppsd.js +1 -0
  45. package/dist/interface/assets/CuiCameraRecordings-DqVdR9uS.js +1 -0
  46. package/dist/interface/assets/CuiCameraShares-DstoVjf9.js +1 -0
  47. package/dist/interface/assets/CuiCameraTable-BHaCRB65.js +2 -0
  48. package/dist/interface/assets/CuiDataTable-CTT9IFeR.js +1 -0
  49. package/dist/interface/assets/CuiLightControl-B_JIzm9t.js +1 -0
  50. package/dist/interface/assets/CuiLightControl-DFrZm_sv.css +1 -0
  51. package/dist/interface/assets/CuiList-CDed3qXV.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-7aXQznrX.js +2 -0
  55. package/dist/interface/assets/{CuiPluginCategoryChip-D9Vi1SEP.js → CuiPluginCategoryChip-C2Y8x73q.js} +1 -1
  56. package/dist/interface/assets/CuiPluginOAuthButton-CCzRlZP6.js +2 -0
  57. package/dist/interface/assets/{CuiPluginTrustBadge-D0rUX2i6.js → CuiPluginTrustBadge-C8qBdLCg.js} +1 -1
  58. package/dist/interface/assets/CuiQRCode-D52Fcu61.js +1 -0
  59. package/dist/interface/assets/CuiRecordingsGrid-CfuihmlY.js +1 -0
  60. package/dist/interface/assets/CuiSchema-DTIuxROi.js +1 -0
  61. package/dist/interface/assets/CuiTopNavbarItem-CoTQmfY7.js +1 -0
  62. package/dist/interface/assets/Faces-EtBPS1Ve.js +1 -0
  63. package/dist/interface/assets/FirstSteps-CC0BPH40.js +1 -0
  64. package/dist/interface/assets/Instances-dSYERqIc.js +1 -0
  65. package/dist/interface/assets/Logs-B8d6dEt7.js +6 -0
  66. package/dist/interface/assets/Menu-CejIVz_7.js +1 -0
  67. package/dist/interface/assets/OAuthDeviceFlow-YhwV_FSL.js +1 -0
  68. package/dist/interface/assets/Plugin-Brb6wfq-.js +1 -0
  69. package/dist/interface/assets/PluginConsole-CfyZQVq5.js +7 -0
  70. package/dist/interface/assets/PluginDetail-DVRnnauk.js +2 -0
  71. package/dist/interface/assets/PluginSchema-i6UJfMnh.js +1 -0
  72. package/dist/interface/assets/PluginSearch-C1YL9q00.js +1 -0
  73. package/dist/interface/assets/PluginSearch-PDx47aUx.js +2 -0
  74. package/dist/interface/assets/Plugins-CukJohcb.js +1 -0
  75. package/dist/interface/assets/Recordings-m6jxYvRI.js +1 -0
  76. package/dist/interface/assets/SensorEdit-BJAijbmc.js +1 -0
  77. package/dist/interface/assets/SensorHistory-DW00ZuHR.js +1 -0
  78. package/dist/interface/assets/Sensors-BA9P_Ray.css +1 -0
  79. package/dist/interface/assets/Sensors-Lfafn19i.js +2 -0
  80. package/dist/interface/assets/Settings-DHT8KXi2.js +1 -0
  81. package/dist/interface/assets/SettingsAccount-DOd4JeGd.js +1 -0
  82. package/dist/interface/assets/{SettingsAccount-CyNJQSuV.css → SettingsAccount-si-6gWl5.css} +1 -1
  83. package/dist/interface/assets/SettingsAccount-vrwV9rtP.js +1 -0
  84. package/dist/interface/assets/SettingsAppearance-11UFhRDY.js +1 -0
  85. package/dist/interface/assets/SettingsAppearance-BaDwC_h_.js +1 -0
  86. package/dist/interface/assets/SettingsBackup-CBBZV_nU.js +1 -0
  87. package/dist/interface/assets/SettingsList-Dx9DHGq9.js +1 -0
  88. package/dist/interface/assets/SettingsMqtt-BglQ_GeN.js +1 -0
  89. package/dist/interface/assets/SettingsNotifications-96czeGDD.js +2 -0
  90. package/dist/interface/assets/SettingsPermissions-CU4OVllA.js +1 -0
  91. package/dist/interface/assets/SettingsRecordings-BrnU9hrb.js +1 -0
  92. package/dist/interface/assets/SettingsRemote-CwJw_9HX.js +1 -0
  93. package/dist/interface/assets/SettingsSystem-B3nne5fS.js +2 -0
  94. package/dist/interface/assets/SettingsUsers-CoYyAxxn.js +1 -0
  95. package/dist/interface/assets/Terminal-DMAHgufw.js +4 -0
  96. package/dist/interface/assets/VariableInput-BzWLKBgd.js +1 -0
  97. package/dist/interface/assets/VariableSuggestions-BdxcP_dn.js +1 -0
  98. package/dist/interface/assets/VersionsHandler-Dvy5Lv-E.js +7 -0
  99. package/dist/interface/assets/VirtualSensorCreate-BXz0lWNm.js +1 -0
  100. package/dist/interface/assets/Workers-DqeKkdpa.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-DmxTF6VE.js} +1 -1
  109. package/dist/interface/assets/api-milc5VEE.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-DwSrX8QL.js} +1 -1
  113. package/dist/interface/assets/automationBlueprint-D0F9AHk9.js +1 -0
  114. package/dist/interface/assets/automations-yVPQAmFo.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-JAiaenSf.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-QtPEpiS4.js +1 -0
  127. package/dist/interface/assets/{config-C2hgXHyj.js → config-BE0DnCXx.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-BQp77LdP.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-CqhwDjRG.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-D_shY0Ks.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-BuSNpaOJ.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-7pWXkYgo.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-DKWwojYm.js +1 -0
  171. package/dist/interface/assets/{search-M4Rt52Co.js → search-miJXZGQz.js} +1 -1
  172. package/dist/interface/assets/sensors-CLQG1mQt.js +1 -0
  173. package/dist/interface/assets/{server-CVSOthzT.js → server-Bv5NVJ0G.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-DsxRUmCC.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-Bw8H-UB4.js → types-BazOcNe_.js} +1 -1
  182. package/dist/interface/assets/types-CoXm85So.js +1 -0
  183. package/dist/interface/assets/upload-CNYrnwuV.js +1 -0
  184. package/dist/interface/assets/{useAppVersion-CDTrwxkp.js → useAppVersion-oPpW7jcN.js} +1 -1
  185. package/dist/interface/assets/useBackupRestore-b0Niqql7.js +1 -0
  186. package/dist/interface/assets/useCameraOptions-uf9Kog6z.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-Dg8tFzam.js} +1 -1
  189. package/dist/interface/assets/useLogsSocket-9jJ-oJIm.js +5 -0
  190. package/dist/interface/assets/{usePermissions-tzi2t12h.js → usePermissions-xL0VlbyD.js} +1 -1
  191. package/dist/interface/assets/useServerRestart-3AZOTz7i.js +1 -0
  192. package/dist/interface/assets/{useStreamStatus-BV_L7pxB.js → useStreamStatus-Dg-Djura.js} +1 -1
  193. package/dist/interface/assets/useUserOptions-BQnM3gdi.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-BqkrW4Bb.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-BQegq2Q6.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-DYzLjOFZ.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 +19 -2
  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 +2 -2
  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 -5
  474. package/dist/server/src/plugins/runtime/node/storageController.js +20 -28
  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 +18 -0
  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 +1 -3
  484. package/dist/server/src/plugins/runtime/python/storage_controller.py +19 -50
  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 +808 -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,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
- import contextlib
5
4
  import time
6
5
  from abc import ABC, abstractmethod
7
6
  from collections.abc import Callable, Mapping
@@ -19,8 +18,6 @@ from uuid import uuid4
19
18
 
20
19
  from ..internal.sensor_rpc import (
21
20
  CapabilityUpdateFn,
22
- PropertyChangedEvent,
23
- PropertyChangeListener,
24
21
  PropertyUpdateFn,
25
22
  SensorJSON,
26
23
  )
@@ -32,75 +29,143 @@ if TYPE_CHECKING:
32
29
 
33
30
 
34
31
  class SensorType(StrEnum):
35
- """Type of sensor. Each maps to a smart-home concept (HomeKit service)."""
36
-
37
- Motion = "motion" # Video-based motion detection
38
- Object = "object" # Object detection (person, vehicle, animal, etc.)
39
- Audio = "audio" # Audio event detection (glass break, scream, etc.)
40
- Face = "face" # Face detection and recognition
41
- LicensePlate = "licensePlate" # License plate detection and OCR
42
- Classifier = "classifier" # General-purpose image classifier
43
- Clip = "clip" # CLIP embedding sensor
44
- ObjectAssist = "objectAssist" # Object assist that locates objects in a frame so secondaries get real crops from camera-side detections
45
- Contact = "contact" # Contact/open-close sensor (door, window)
46
- Humidity = "humidity" # Humidity level sensor
47
- Leak = "leak" # Water leak detection sensor
48
- Occupancy = "occupancy" # Occupancy/presence detection sensor
49
- Smoke = "smoke" # Smoke detection sensor
50
- Temperature = "temperature" # Temperature sensor
51
- Light = "light" # Light on/off and brightness control
52
- Siren = "siren" # Siren on/off and volume control
53
- Switch = "switch" # Generic on/off switch
54
- Lock = "lock" # Lock/unlock control
55
- Garage = "garage" # Garage door open/close control
56
- PTZ = "ptz" # Pan-tilt-zoom camera control
57
- SecuritySystem = "securitySystem" # Security system arm/disarm control
58
- Doorbell = "doorbell" # Doorbell ring trigger
59
- Battery = "battery" # Battery level and charging state
32
+ """Type of sensor. "Sensor" is camera.ui's umbrella term for the smallest
33
+ smart-home unit. It covers measuring devices and controllable ones alike. The concrete
34
+ classes carry the real meaning (`LightControl`, `MotionSensor`, ...).
35
+ Plugins create sensors of these types, either standalone via the sensor
36
+ manager or attached to a camera via `camera.addSensor()`.
37
+ """
38
+
39
+ Motion = "motion"
40
+ """Video-based motion detection."""
41
+ Object = "object"
42
+ """Object detection (person, vehicle, animal, etc.)."""
43
+ Audio = "audio"
44
+ """Audio event detection (glass break, scream, etc.)."""
45
+ Face = "face"
46
+ """Face detection and recognition."""
47
+ LicensePlate = "licensePlate"
48
+ """License plate detection and OCR."""
49
+ Classifier = "classifier"
50
+ """General-purpose image classifier."""
51
+ Clip = "clip"
52
+ """CLIP embedding generation for semantic search."""
53
+ ObjectAssist = "objectAssist"
54
+ """Locates objects in a frame so secondary detectors get real crops from camera-side detections."""
55
+ Contact = "contact"
56
+ """Contact/open-close sensor (door, window)."""
57
+ Humidity = "humidity"
58
+ """Humidity sensor (0-100%)."""
59
+ Leak = "leak"
60
+ """Water leak detector."""
61
+ Occupancy = "occupancy"
62
+ """Occupancy/presence sensor."""
63
+ Smoke = "smoke"
64
+ """Smoke detector."""
65
+ Temperature = "temperature"
66
+ """Temperature sensor (°C)."""
67
+ Light = "light"
68
+ """Light on/off and brightness control."""
69
+ Siren = "siren"
70
+ """Siren on/off and volume control."""
71
+ Switch = "switch"
72
+ """Generic on/off switch."""
73
+ Lock = "lock"
74
+ """Lock/unlock control."""
75
+ Garage = "garage"
76
+ """Garage door opener."""
77
+ PTZ = "ptz"
78
+ """Pan-tilt-zoom camera control."""
79
+ SecuritySystem = "securitySystem"
80
+ """Security system arm/disarm control."""
81
+ Doorbell = "doorbell"
82
+ """Doorbell ring trigger."""
83
+ Battery = "battery"
84
+ """Battery level and charging state."""
60
85
 
61
86
 
62
87
  class SensorCategory(StrEnum):
63
- """Categorizes a sensor's role in the system."""
88
+ """Categorizes a sensor's role in the system.
89
+
90
+ Determines how the backend treats the sensor (read-only vs. controllable).
91
+ """
64
92
 
65
- Sensor = "sensor" # Read-only detection sensor
66
- Control = "control" # Controllable sensor with set methods
67
- Trigger = "trigger" # Event trigger
68
- Info = "info" # Informational read-only state
93
+ Sensor = "sensor"
94
+ """Read-only detection sensor (motion, object, audio, etc.)."""
95
+ Control = "control"
96
+ """Controllable sensor with set methods (light, siren, PTZ, etc.)."""
97
+ Trigger = "trigger"
98
+ """Event trigger (doorbell ring)."""
99
+ Info = "info"
100
+ """Informational read-only state (battery level)."""
69
101
 
70
102
 
71
103
  class SensorPropertyChangeData(TypedDict):
72
104
  """Emitted on the onPropertyChanged Observable."""
73
105
 
74
106
  property: str
107
+ """Name of the changed property."""
75
108
  value: object
109
+ """New value of the property."""
76
110
  timestamp: int
111
+ """Origin timestamp in milliseconds since epoch."""
77
112
 
78
113
 
79
114
  @runtime_checkable
80
115
  class SensorLike(Protocol):
81
- """Read-only proxy interface for a sensor. Use this type when consuming sensors, not creating them.
116
+ """Read-only view of a sensor, as other plugins and the backend see it.
82
117
 
83
- All state-modifying methods (`setOn`, `reportDetections`, etc.) live on the
118
+ Use this type when consuming sensors, not when creating them. All
119
+ state-modifying methods (`setOn`, `reportDetections`, etc.) live on the
84
120
  concrete sensor classes, not on `SensorLike`. Code that holds a `SensorLike`
85
- reference can only READ state and observe changes.
121
+ reference can only read state and observe changes.
86
122
  """
87
123
 
88
124
  @property
89
125
  def id(self) -> str: ...
126
+
90
127
  @property
91
128
  def type(self) -> SensorType: ...
129
+
92
130
  @property
93
131
  def name(self) -> str: ...
132
+
133
+ @property
134
+ def nativeId(self) -> str | None: ...
135
+
94
136
  @property
95
137
  def pluginId(self) -> str | None: ...
138
+
96
139
  @property
97
140
  def capabilities(self) -> list[str]: ...
98
141
 
142
+ @property
143
+ def connected(self) -> bool: ...
144
+
145
+ @property
146
+ def assignedCameraIds(self) -> list[str]: ...
147
+
148
+ @property
149
+ def assignmentLocked(self) -> bool: ...
150
+
99
151
  @property
100
152
  def displayName(self) -> str: ...
153
+
101
154
  @displayName.setter
102
155
  def displayName(self, value: str) -> None: ...
103
156
 
157
+ @property
158
+ def onPropertyChanged(self) -> Observable[Any]: ...
159
+
160
+ @property
161
+ def onCapabilitiesChanged(self) -> Observable[Any]: ...
162
+
163
+ @property
164
+ def onConnectedChanged(self) -> Observable[bool]: ...
165
+
166
+ @property
167
+ def onAssignmentChanged(self) -> Observable[list[str]]: ...
168
+
104
169
  def getValue(self, property: str) -> Any | None:
105
170
  """Get the current value of a sensor property."""
106
171
  ...
@@ -110,23 +175,17 @@ class SensorLike(Protocol):
110
175
  ...
111
176
 
112
177
  async def updateValue(self, property: str, value: Any) -> None:
113
- """Write a property generically. Cross-process bridges (e.g. HomeKit) bind
114
- generic property names to UI characteristics and call this on a sensor
115
- proxy the proxy forwards via RPC to the owning sensor, where control
116
- sensor classes (`Light`, `Siren`, etc.) override `updateValue` to dispatch
117
- to the appropriate semantic method (`setOn`, `setActive`, ...). This means
118
- plugin-side hardware-action overrides ARE honored end-to-end.
119
-
120
- Plugin authors **must not** call this — they should call the semantic
121
- methods directly on the concrete sensor class.
178
+ """Generic property write used by cross-process bridges.
179
+
180
+ The owning sensor dispatches it to the matching semantic method, so
181
+ plugin-side hardware overrides still run. Plugin authors call the
182
+ semantic methods instead.
122
183
  """
123
184
  ...
124
185
 
125
- @property
126
- def onPropertyChanged(self) -> Observable[Any]: ...
127
- @property
128
- def onCapabilitiesChanged(self) -> Observable[Any]: ...
129
- def hasCapability(self, capability: str) -> bool: ...
186
+ def hasCapability(self, capability: str) -> bool:
187
+ """Whether the sensor advertises the given capability."""
188
+ ...
130
189
 
131
190
 
132
191
  TProperties = TypeVar("TProperties", bound=Mapping[str, Any])
@@ -135,9 +194,10 @@ TCapability = TypeVar("TCapability", bound=str)
135
194
 
136
195
 
137
196
  class PropertiesProxy(Generic[TProperties]):
138
- """Read-only view over a sensor's property store. Subclasses use this to read
139
- current state when implementing semantic methods (e.g. `if self.props.blocked: return`).
140
- Writes go through `Sensor._write_state` assignments through this proxy are not allowed.
197
+ """Read-only view over a sensor's property store.
198
+
199
+ Subclasses read current state from here when implementing semantic methods.
200
+ Writes go through `Sensor._write_state`, assignments through this proxy raise.
141
201
  """
142
202
 
143
203
  _store: dict[str, Any]
@@ -170,26 +230,41 @@ class PropertiesProxy(Generic[TProperties]):
170
230
 
171
231
 
172
232
  class Sensor(ABC, Generic[TProperties, TStorage, TCapability]):
173
- """Abstract base class for all sensors. Plugins extend this (or use specialized subclasses like MotionSensor, LightControl, etc.) to implement sensor logic."""
233
+ """Abstract base class for all sensors. Plugins extend this (or use specialized
234
+ subclasses like MotionSensor, LightControl, etc.) to implement sensor logic.
235
+
236
+ Sensors are standalone entities: the plugin supplies the durable identity
237
+ (``native_id``), everything else belongs to the user: camera assignments,
238
+ display name and whether the sensor is exported or not. A plugin
239
+ never decides where its sensor is used and never handles the export itself.
240
+
241
+ The ``id`` is provisional until registration, when the host swaps in the
242
+ persistent entity id. Reading ``storage`` before registration raises.
243
+ Override ``storage_schema`` to return a JSON schema and get a per-sensor
244
+ settings UI.
245
+ """
174
246
 
175
247
  _requires_frames: bool = False
176
248
 
177
- def __init__(self, name: str) -> None:
178
- self._camera_id: str | None = None
249
+ def __init__(self, name: str, *, native_id: str | None = None) -> None:
179
250
  self._name = name
180
- self._id = str(uuid4())
251
+ self._id = str(uuid4()) # provisional id, replaced by the host's persistent id at registration
252
+ self._native_id = native_id
181
253
  self._display_name = name
182
254
  self._plugin_id: str | None = None
255
+ self._assigned_camera_ids: list[str] = []
256
+ self._assignment_locked = False
183
257
  self._capabilities: list[TCapability] = []
184
258
  self._property_changed_subject: Subject[SensorPropertyChangeData] = Subject()
185
259
  self._capabilities_changed_subject: Subject[list[TCapability]] = Subject()
186
- self._detailed_listeners: set[PropertyChangeListener] = set()
187
- self._assignment_changed_subject: Subject[bool] = Subject()
260
+ self._assignment_changed_subject: Subject[list[str]] = Subject()
261
+ self._connected_changed_subject: Subject[bool] = Subject()
188
262
 
189
263
  self._update_fn: PropertyUpdateFn | None = None
190
264
  self._capabilities_change_fn: Callable[[list[str]], None] | None = None
191
265
  self._storage: DeviceStorage[TStorage] | None = None
192
- self._is_assigned: bool = False
266
+ self._registered: bool = False
267
+ self._active: bool = False
193
268
  self._properties_store: dict[str, Any] = {}
194
269
  self._properties_proxy: PropertiesProxy[TProperties] = PropertiesProxy(
195
270
  self._properties_store,
@@ -207,6 +282,10 @@ class Sensor(ABC, Generic[TProperties, TStorage, TCapability]):
207
282
  def id(self) -> str:
208
283
  return self._id
209
284
 
285
+ @property
286
+ def nativeId(self) -> str | None:
287
+ return self._native_id
288
+
210
289
  @property
211
290
  def name(self) -> str:
212
291
  return self._name
@@ -217,16 +296,6 @@ class Sensor(ABC, Generic[TProperties, TStorage, TCapability]):
217
296
 
218
297
  @displayName.setter
219
298
  def displayName(self, value: str) -> None:
220
- """Set the display name (the only mutable identifier on a sensor).
221
-
222
- Args:
223
- value: Human-readable label shown in the UI.
224
-
225
- Example:
226
- ```python
227
- sensor.displayName = "Front Door Motion"
228
- ```
229
- """
230
299
  self._display_name = value
231
300
 
232
301
  @property
@@ -234,8 +303,16 @@ class Sensor(ABC, Generic[TProperties, TStorage, TCapability]):
234
303
  return self._plugin_id
235
304
 
236
305
  @property
237
- def cameraId(self) -> str | None:
238
- return self._camera_id
306
+ def assignedCameraIds(self) -> list[str]:
307
+ return self._assigned_camera_ids.copy()
308
+
309
+ @property
310
+ def assignmentLocked(self) -> bool:
311
+ return self._assignment_locked
312
+
313
+ @property
314
+ def connected(self) -> bool:
315
+ return self._registered
239
316
 
240
317
  @property
241
318
  def capabilities(self) -> list[TCapability]:
@@ -243,6 +320,7 @@ class Sensor(ABC, Generic[TProperties, TStorage, TCapability]):
243
320
 
244
321
  @capabilities.setter
245
322
  def capabilities(self, value: list[TCapability]) -> None:
323
+ """Set capabilities, deduplicated, and notify backend plus local listeners."""
246
324
  self._capabilities = list(dict.fromkeys(value))
247
325
  if self._capabilities_change_fn:
248
326
  caps_list: list[str] = [str(c) for c in self._capabilities]
@@ -255,18 +333,16 @@ class Sensor(ABC, Generic[TProperties, TStorage, TCapability]):
255
333
 
256
334
  @property
257
335
  def storage_schema(self) -> list[JsonSchema]:
258
- """Override to provide a JSON schema for per-sensor storage settings UI."""
259
336
  return []
260
337
 
261
338
  @property
262
339
  def storage(self) -> DeviceStorage[TStorage]:
263
- """Per-sensor persistent storage. Raises if not yet added to a camera."""
264
- assert self._storage is not None, "Storage not initialized - sensor not added to camera yet"
340
+ assert self._storage is not None, "Storage not initialized - sensor not registered yet"
265
341
  return self._storage
266
342
 
267
343
  @property
268
344
  def isAssigned(self) -> bool:
269
- return self._is_assigned
345
+ return len(self._assigned_camera_ids) > 0
270
346
 
271
347
  @property
272
348
  def props(self) -> PropertiesProxy[TProperties]:
@@ -276,164 +352,68 @@ class Sensor(ABC, Generic[TProperties, TStorage, TCapability]):
276
352
  def rawProps(self) -> dict[str, Any]:
277
353
  return self._properties_store
278
354
 
279
- def _write_state(self, partial: Mapping[str, Any]) -> None:
280
- """SDK-internal state-write API. Performs deep-equal change detection over
281
- the partial, writes changed properties to the store, fires a single batched
282
- RPC update with the delta, and notifies local listeners per-property.
283
-
284
- Used by the semantic helper methods on each sensor type (`setOn`,
285
- `reportDetections`, etc.) — **not for plugin authors**. Plugin code should
286
- call the semantic helpers, not write state directly.
287
-
288
- One `_write_state` call → one `_update_fn` invocation. The receiver sees an
289
- atomic state transition for this sensor.
290
- """
291
- delta: dict[str, Any] = {}
292
- changes: list[tuple[str, Any, Any]] = []
293
-
294
- for key, value in partial.items():
295
- if value is None:
296
- continue
297
- previous = self._properties_store.get(key)
298
- if is_equal(previous, value, True):
299
- continue
300
- self._properties_store[key] = value
301
- delta[key] = value
302
- changes.append((key, value, previous))
303
-
304
- if not delta:
305
- return
306
-
307
- if self._update_fn:
308
- self._update_fn(delta)
309
-
310
- for key, value, previous in changes:
311
- self._notifyListeners(key, value, previous)
355
+ @property
356
+ def onAssignmentChanged(self) -> Observable[list[str]]:
357
+ return self._assignment_changed_subject.as_observable()
312
358
 
313
- def _normalize_reported_detections(
314
- self,
315
- detected: bool,
316
- detections: list[dict[str, Any]] | None,
317
- fallback_label: str,
318
- fallback_extra: dict[str, Any] | None = None,
319
- ) -> list[dict[str, Any]]:
320
- """Helper for `reportDetections(detected, detections?)` flows.
321
-
322
- - If `detected` is False → returns `[]` (clear).
323
- - If `detected` is True and `detections` has items → returns them, substituting a full-frame box where missing.
324
- - If `detected` is True and `detections` is missing/empty → returns a single
325
- synthesized full-frame detection with the given `fallback_label` and any
326
- `fallback_extra` fields (used for type-specific properties like `attribute`,
327
- `plateText`, etc.).
328
- """
329
- if not detected:
330
- return []
331
- if detections:
332
- # Smart-camera plugins report labels without coordinates, while
333
- # downstream consumers (detection coordinator, zone matching)
334
- # require a box on every detection — substitute full-frame.
335
- return [
336
- detection
337
- if detection.get("box")
338
- else {**detection, "box": {"x": 0, "y": 0, "width": 1, "height": 1}}
339
- for detection in detections
340
- ]
341
- synthesized: dict[str, Any] = {
342
- "label": fallback_label,
343
- "confidence": 1,
344
- "box": {"x": 0, "y": 0, "width": 1, "height": 1},
345
- }
346
- if fallback_extra:
347
- synthesized.update(fallback_extra)
348
- return [synthesized]
359
+ @property
360
+ def onConnectedChanged(self) -> Observable[bool]:
361
+ return self._connected_changed_subject.as_observable()
349
362
 
350
- def _setStorage(self, storage: DeviceStorage[TStorage]) -> None:
351
- self._storage = storage
363
+ @property
364
+ def onPropertyChanged(self) -> Observable[SensorPropertyChangeData]:
365
+ return self._property_changed_subject.as_observable()
352
366
 
353
- def on_assigned(self) -> Any:
354
- """Lifecycle hook: the sensor just became assigned to a camera.
367
+ @property
368
+ def onCapabilitiesChanged(self) -> Observable[list[TCapability]]:
369
+ return self._capabilities_changed_subject.as_observable()
355
370
 
356
- Override to start background work that should only run while this
357
- sensor is live polling loops, event subscriptions, timers, external
358
- connections.
371
+ def on_start(self) -> Any:
372
+ """Lifecycle hook, called once the sensor is registered and live.
359
373
 
360
- Called AFTER ``cameraId``, ``storage``, and RPC channels are wired up,
361
- so the override can safely access ``self.cameraId``, ``self.storage``,
362
- and publish properties via the semantic helper methods.
374
+ Storage and RPC are wired up by then. Override it to start work whose
375
+ lifetime matches the sensor's: polling loops, event subscriptions, timers.
363
376
 
364
377
  May be either a plain ``def`` or an ``async def``. If async, the SDK
365
378
  schedules it on the running event loop (fire-and-forget). Errors are
366
- caught and swallowed they will NOT break assignment bookkeeping.
367
-
368
- Paired 1:1 with ``on_deassigned`` — for every ``on_assigned`` call
369
- there is exactly one matching ``on_deassigned`` later (on deassignment
370
- or cleanup).
371
-
372
- Default: no-op. Most sensors don't need lifecycle hooks.
379
+ swallowed, not logged, so handle failures inside the override. Paired
380
+ 1:1 with ``on_stop``, which runs on removal, plugin shutdown or cleanup.
373
381
 
374
382
  Example:
375
383
  ```python
376
- async def on_assigned(self) -> None:
384
+ async def on_start(self) -> None:
377
385
  self._task = asyncio.create_task(self._poll_loop())
378
386
  ```
379
387
  """
380
388
  return None
381
389
 
382
- def on_deassigned(self) -> Any:
383
- """Lifecycle hook: the sensor is being deassigned.
384
-
385
- Override to tear down whatever was started in ``on_assigned`` — clear
386
- timers, close subscriptions, release external resources.
390
+ def on_stop(self) -> Any:
391
+ """Counterpart of ``on_start``: tear down whatever it started, such as
392
+ timers, subscriptions and external resources.
387
393
 
388
- Always called exactly once for each prior ``on_assigned``. Also called
389
- from ``_cleanup`` if the sensor is being removed while still assigned,
390
- so you can rely on this as the single teardown point.
391
-
392
- May be either a plain ``def`` or an ``async def``. See ``on_assigned``
394
+ May be either a plain ``def`` or an ``async def``. See ``on_start``
393
395
  for scheduling semantics.
394
396
 
395
- Default: no-op.
396
-
397
397
  Example:
398
398
  ```python
399
- def on_deassigned(self) -> None:
399
+ def on_stop(self) -> None:
400
400
  if self._task:
401
401
  self._task.cancel()
402
402
  ```
403
403
  """
404
404
  return None
405
405
 
406
- def _fire_lifecycle(self, assigned: bool) -> None:
407
- """Internal helper invoke the appropriate lifecycle hook and, if the
408
- override returned a coroutine, schedule it on the running loop."""
409
- try:
410
- result = self.on_assigned() if assigned else self.on_deassigned()
411
- except Exception: # noqa: BLE001 - lifecycle errors must not break bookkeeping
412
- return
413
- if asyncio.iscoroutine(result):
414
- try:
415
- loop = asyncio.get_running_loop()
416
- except RuntimeError:
417
- # No loop running — the coroutine won't execute. Swallow so
418
- # the coroutine isn't logged as "never awaited".
419
- result.close()
420
- return
421
- task = loop.create_task(result)
422
- # Swallow exceptions from async lifecycle work so they don't
423
- # surface as "Task exception was never retrieved" warnings.
424
- task.add_done_callback(lambda t: t.exception() if not t.cancelled() else None)
425
-
426
- def _setAssigned(self, assigned: bool) -> None:
427
- if self._is_assigned == assigned:
428
- return
429
- self._is_assigned = assigned
430
- self._assignment_changed_subject.next(assigned)
431
- self._fire_lifecycle(assigned)
406
+ def on_assigned(self) -> Any:
407
+ """Deprecated: renamed to ``on_start``. Stub window: still fired
408
+ alongside ``on_start``, remove in the first minor after the
409
+ standalone-sensors release."""
410
+ return None
432
411
 
433
- @property
434
- def onAssignmentChanged(self) -> Observable[bool]:
435
- """Observable for assignment state changes (sensor added/removed from camera)."""
436
- return self._assignment_changed_subject.as_observable()
412
+ def on_deassigned(self) -> Any:
413
+ """Deprecated: renamed to ``on_stop``. Stub window: still fired
414
+ alongside ``on_stop``, remove in the first minor after the
415
+ standalone-sensors release."""
416
+ return None
437
417
 
438
418
  def toJSON(self) -> SensorJSON:
439
419
  """Serialize this sensor to a JSON-safe dict for RPC transport."""
@@ -443,24 +423,16 @@ class Sensor(ABC, Generic[TProperties, TStorage, TCapability]):
443
423
  "name": self.name,
444
424
  "displayName": self.displayName or self.name,
445
425
  "category": self.category,
446
- "cameraId": self._camera_id or "",
447
426
  "properties": self._getProperties(),
448
427
  "capabilities": [str(c) for c in self.capabilities],
449
428
  "requiresFrames": self._requires_frames,
450
429
  }
430
+ if self._native_id:
431
+ result["nativeId"] = self._native_id
451
432
  if self._plugin_id:
452
433
  result["pluginId"] = self._plugin_id
453
434
  return result
454
435
 
455
- def _setPropertyInternal(self, key: str, value: Any, timestamp: int | None = None) -> None:
456
- old_value = self._properties_store.get(key)
457
- if old_value != value:
458
- self._properties_store[key] = value
459
- self._notifyListeners(key, value, old_value, timestamp)
460
-
461
- def _onBackendPropertyChanged(self, property: str, value: Any, timestamp: int | None = None) -> None:
462
- self._setPropertyInternal(property, value, timestamp)
463
-
464
436
  def getValue(self, property: str) -> Any | None:
465
437
  """Get the current value of a sensor property."""
466
438
  return self._properties_store.get(property)
@@ -481,80 +453,181 @@ class Sensor(ABC, Generic[TProperties, TStorage, TCapability]):
481
453
 
482
454
  @abstractmethod
483
455
  async def updateValue(self, property: str, value: Any) -> None:
484
- """External-consumer entry point that satisfies the `SensorLike.updateValue`
485
- contract. Each concrete sensor class implements this — read-only sensors
486
- leave it as a no-op, control sensors dispatch known properties to the
487
- appropriate semantic methods (`setOn`, `setActive`, `setTargetState`, ...)
488
- so plugin overrides drive hardware. Unknown / non-writable properties are
489
- silently ignored.
490
-
491
- **Plugin authors must not call this** they should call the semantic
492
- methods directly on the concrete sensor class.
456
+ """Generic property write coming from a consumer.
457
+
458
+ Read-only sensors implement it as a no-op, control sensors dispatch known
459
+ properties to their semantic methods (`setOn`, `setActive`,
460
+ `setTargetState`) so plugin overrides drive hardware. Unknown or
461
+ non-writable properties are ignored.
462
+
463
+ Plugin authors call the semantic methods on the concrete class instead.
493
464
  """
494
465
  ...
495
466
 
496
467
  def hasCapability(self, capability: TCapability | str) -> bool:
468
+ """Check whether the sensor advertises a capability.
469
+
470
+ Args:
471
+ capability: Capability flag to look for.
472
+
473
+ Returns:
474
+ True if the sensor currently advertises it.
475
+
476
+ Example:
477
+ ```python
478
+ dimmable = sensor.hasCapability("brightness")
479
+ ```
480
+ """
497
481
  return capability in self._capabilities
498
482
 
499
- @property
500
- def onPropertyChanged(self) -> Observable[SensorPropertyChangeData]:
501
- """Observable for property changes."""
502
- return self._property_changed_subject.as_observable()
483
+ def _write_state(self, partial: Mapping[str, Any]) -> None:
484
+ """Write changed properties, fire one batched RPC update and notify listeners.
485
+
486
+ Used by the semantic helpers on each sensor type, not by plugin code.
487
+ """
488
+ delta: dict[str, Any] = {}
489
+ changes: list[tuple[str, Any, Any]] = []
490
+
491
+ for key, value in partial.items():
492
+ if value is None:
493
+ continue
494
+ previous = self._properties_store.get(key)
495
+ if is_equal(previous, value, True):
496
+ continue
497
+ self._properties_store[key] = value
498
+ delta[key] = value
499
+ changes.append((key, value, previous))
500
+
501
+ if not delta:
502
+ return
503
+
504
+ if self._update_fn:
505
+ self._update_fn(delta)
506
+
507
+ for key, value, previous in changes:
508
+ self._notifyListeners(key, value, previous)
509
+
510
+ def _normalize_reported_detections(
511
+ self,
512
+ detected: bool,
513
+ detections: list[dict[str, Any]] | None,
514
+ fallback_label: str,
515
+ fallback_extra: dict[str, Any] | None = None,
516
+ ) -> list[dict[str, Any]]:
517
+ """Normalize the arguments of a `reportDetections(detected, detections)` call.
518
+
519
+ - `detected` is False: returns `[]` (clear).
520
+ - `detected` is True with detections: returns them, substituting a full-frame box where missing.
521
+ - `detected` is True without detections: returns one synthesized full-frame
522
+ detection carrying `fallback_label` and `fallback_extra`.
523
+ """
524
+ if not detected:
525
+ return []
526
+ if detections:
527
+ # smart-camera plugins report labels without coordinates, downstream
528
+ # consumers (coordinator, zone matching) require a box on every detection
529
+ return [
530
+ detection
531
+ if detection.get("box")
532
+ else {**detection, "box": {"x": 0, "y": 0, "width": 1, "height": 1}}
533
+ for detection in detections
534
+ ]
535
+ synthesized: dict[str, Any] = {
536
+ "label": fallback_label,
537
+ "confidence": 1,
538
+ "box": {"x": 0, "y": 0, "width": 1, "height": 1},
539
+ }
540
+ if fallback_extra:
541
+ synthesized.update(fallback_extra)
542
+ return [synthesized]
543
+
544
+ def _setStorage(self, storage: DeviceStorage[TStorage]) -> None:
545
+ self._storage = storage
546
+
547
+ def _fire_lifecycle(self, active: bool) -> None:
548
+ """Invoke the lifecycle hooks and schedule them if an override is async."""
549
+ hooks = (self.on_start, self.on_assigned) if active else (self.on_stop, self.on_deassigned)
550
+ for hook in hooks:
551
+ try:
552
+ result = hook()
553
+ except Exception: # noqa: BLE001 - lifecycle errors must not break bookkeeping
554
+ continue
555
+ if asyncio.iscoroutine(result):
556
+ try:
557
+ loop = asyncio.get_running_loop()
558
+ except RuntimeError:
559
+ # no loop, close so the coroutine isn't logged as "never awaited"
560
+ result.close()
561
+ continue
562
+ task = loop.create_task(result)
563
+ # swallow, otherwise "Task exception was never retrieved" warnings
564
+ task.add_done_callback(lambda t: t.exception() if not t.cancelled() else None)
565
+
566
+ def _setActive(self, active: bool) -> None:
567
+ if self._active == active:
568
+ return
569
+ self._active = active
570
+ self._connected_changed_subject.next(active)
571
+ self._fire_lifecycle(active)
572
+
573
+ def _setPropertyInternal(self, key: str, value: Any, timestamp: int | None = None) -> None:
574
+ old_value = self._properties_store.get(key)
575
+ if old_value != value:
576
+ self._properties_store[key] = value
577
+ self._notifyListeners(key, value, old_value, timestamp)
578
+
579
+ def _onBackendPropertyChanged(self, property: str, value: Any, timestamp: int | None = None) -> None:
580
+ self._setPropertyInternal(property, value, timestamp)
503
581
 
504
582
  def _notifyListeners(
505
- self, property: str, value: Any, previousValue: Any, timestamp: int | None = None
583
+ self,
584
+ property: str,
585
+ value: Any,
586
+ previousValue: Any,
587
+ timestamp: int | None = None,
506
588
  ) -> None:
507
- if not self._camera_id:
589
+ # skip constructor-time writes, listeners only matter once registered
590
+ if not self._registered:
508
591
  return
509
592
 
510
593
  ts = timestamp or int(time.time() * 1000)
511
- if self._detailed_listeners:
512
- event: PropertyChangedEvent = {
513
- "cameraId": self._camera_id,
514
- "sensorId": self._id,
515
- "sensorType": self.type,
516
- "property": property,
517
- "value": value,
518
- "previousValue": previousValue,
519
- "timestamp": ts,
520
- }
521
- for detailed_listener in self._detailed_listeners:
522
- with contextlib.suppress(Exception):
523
- detailed_listener(event)
524
594
  self._property_changed_subject.next({"property": property, "value": value, "timestamp": ts})
525
595
 
526
- @property
527
- def onCapabilitiesChanged(self) -> Observable[list[TCapability]]:
528
- """Observable for capability changes. Emits the full capabilities array when capabilities change."""
529
- return self._capabilities_changed_subject.as_observable()
596
+ def _setId(self, id: str) -> None:
597
+ self._id = id
598
+
599
+ def _setAssignedCameras(self, camera_ids: list[str]) -> None:
600
+ self._assigned_camera_ids = list(camera_ids)
601
+ self._assignment_changed_subject.next(self._assigned_camera_ids.copy())
530
602
 
531
- def _setCameraId(self, camera_id: str) -> None:
532
- self._camera_id = camera_id
603
+ def _setAssignmentLocked(self) -> None:
604
+ self._assignment_locked = True
533
605
 
534
606
  def _setPluginId(self, plugin_id: str) -> None:
535
607
  self._plugin_id = plugin_id
536
608
 
537
609
  def _init(self, update_fn: PropertyUpdateFn) -> None:
538
610
  self._update_fn = update_fn
611
+ self._registered = True
539
612
 
540
613
  def _initCapabilities(self, update_fn: CapabilityUpdateFn) -> None:
541
614
  self._capabilities_change_fn = update_fn
542
615
 
543
616
  def _cleanup(self) -> None:
544
- # Trigger on_deassigned if we're still assigned guarantees the hook
545
- # is paired 1:1 even when the sensor is force-removed without going
546
- # through a proper deassignment path.
547
- if self._is_assigned:
548
- self._is_assigned = False
617
+ # pair on_stop even when the sensor is force-removed without teardown
618
+ if self._active:
619
+ self._active = False
549
620
  self._fire_lifecycle(False)
550
621
 
551
622
  self._update_fn = None
552
623
  self._capabilities_change_fn = None
553
624
  self._storage = None
554
- self._detailed_listeners.clear()
625
+ self._registered = False
626
+ self._assigned_camera_ids = []
555
627
  self._property_changed_subject.complete()
556
628
  self._capabilities_changed_subject.complete()
557
629
  self._assignment_changed_subject.complete()
630
+ self._connected_changed_subject.complete()
558
631
 
559
632
  def _getProperties(self) -> dict[str, Any]:
560
633
  return self._properties_store.copy()