@camera.ui/server 0.0.22-alpha.1 → 0.0.22-alpha.3

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 (568) hide show
  1. package/dist/interface/@intlify.DXtFJcML.0.0.22-alpha.3.js +15 -0
  2. package/dist/interface/@mdi.C1UTQKuc.0.0.22-alpha.3.js +1 -0
  3. package/dist/interface/@tanstack.BQDLPv59.0.0.22-alpha.3.js +1 -0
  4. package/dist/interface/{@vee-validate.CBoqAk51.0.0.22-alpha.1.js → @vee-validate.B6iHt3KQ.0.0.22-alpha.3.js} +2 -2
  5. package/dist/interface/@vue.dAKyD-3P.0.0.22-alpha.3.js +17 -0
  6. package/dist/interface/{@vueform.20m7Hn_5.0.0.22-alpha.1.js → @vueform.fX_skaP7.0.0.22-alpha.3.js} +1 -1
  7. package/dist/interface/@vueuse.UomdiF5b.0.0.22-alpha.3.js +1 -0
  8. package/dist/interface/Account.CV0129ox.0.0.22-alpha.3.js +1 -0
  9. package/dist/interface/Adminpanel.BdWgx08_.0.0.22-alpha.3.js +2 -0
  10. package/dist/interface/Appearance.BIXs4v77.0.0.22-alpha.3.js +1 -0
  11. package/dist/interface/Backup.DD8_FKRe.0.0.22-alpha.3.js +1 -0
  12. package/dist/interface/Camera.D35ZcCy9.0.0.22-alpha.3.js +1 -0
  13. package/dist/interface/Cameras.DjHsEC_O.0.0.22-alpha.3.js +1 -0
  14. package/dist/interface/Camview.B7RlCn-N.0.0.22-alpha.3.js +1 -0
  15. package/dist/interface/Config.D59faV9o.0.0.22-alpha.3.js +1 -0
  16. package/dist/interface/Console.AYN2urXI.0.0.22-alpha.3.js +4 -0
  17. package/dist/interface/FirstSteps.GCJrwiwA.0.0.22-alpha.3.js +1 -0
  18. package/dist/interface/{NewCamera.BoQ_EpL5.0.0.22-alpha.1.js → NewCamera.vdINgQcu.0.0.22-alpha.3.js} +2 -2
  19. package/dist/interface/Plugin.CNSuNdoN.0.0.22-alpha.3.js +1 -0
  20. package/dist/interface/Plugins.CEuVE1ye.0.0.22-alpha.3.js +1 -0
  21. package/dist/interface/Recordings.9X_sLd-K.0.0.22-alpha.3.js +1 -0
  22. package/dist/interface/Recordings.Ci_Cay__.0.0.22-alpha.3.js +1 -0
  23. package/dist/interface/Settings.BoS_2afy.0.0.22-alpha.3.js +1 -0
  24. package/dist/interface/System.OQzLrmLL.0.0.22-alpha.3.js +4 -0
  25. package/dist/interface/User.3YvVz6r3.0.0.22-alpha.3.js +1 -0
  26. package/dist/interface/VConfigEditor.vue_vue_type_script_setup_true_lang.CIO7vqXE.0.0.22-alpha.3.js +2 -0
  27. package/dist/interface/VConsole.J4Bg7nPY.0.0.22-alpha.3.js +1 -0
  28. package/dist/interface/VPlayer.CEpiQ-rx.0.0.22-alpha.3.js +4 -0
  29. package/dist/interface/VPluginCard.D0qUSLbT.0.0.22-alpha.3.js +4 -0
  30. package/dist/interface/{ace-builds.GNWBVG5S.0.0.22-alpha.1.js → ace-builds.Ch6vRC6Y.0.0.22-alpha.3.js} +27 -27
  31. package/dist/interface/{apexcharts.BMrxVPFF.0.0.22-alpha.1.js → apexcharts.BzKjYm5L.0.0.22-alpha.3.js} +1 -1
  32. package/dist/interface/assets/Adminpanel.0.0.22-alpha.3.a3t1v3MB.css +1 -0
  33. package/dist/interface/assets/Camera.0.0.22-alpha.3.D1I-fW4q.css +1 -0
  34. package/dist/interface/assets/Cameras.0.0.22-alpha.3.Buf1Dgce.css +1 -0
  35. package/dist/interface/assets/Camview.0.0.22-alpha.3.B7Cja2ry.css +1 -0
  36. package/dist/interface/assets/Config.0.0.22-alpha.3.DNGo2krN.css +1 -0
  37. package/dist/interface/assets/Console.0.0.22-alpha.3.Bh8l9QnM.css +1 -0
  38. package/dist/interface/assets/FirstSteps.0.0.22-alpha.3.sPEcItZ6.css +1 -0
  39. package/dist/interface/assets/NewCamera.0.0.22-alpha.3.Cq8GzeJ7.css +1 -0
  40. package/dist/interface/assets/{Settings.0.0.22-alpha.1.DC_-E3CR.css → Settings.0.0.22-alpha.3.CVmui2kE.css} +1 -1
  41. package/dist/interface/assets/VConsole.0.0.22-alpha.3.BCqKHpmJ.css +1 -0
  42. package/dist/interface/assets/VPlayer.0.0.22-alpha.3.DNtDNhfg.css +1 -0
  43. package/dist/interface/assets/VPluginCard.0.0.22-alpha.3.C8Lj6X-J.css +1 -0
  44. package/dist/interface/assets/main.0.0.22-alpha.3.DNhh__S1.css +1 -0
  45. package/dist/interface/assets/{vuetify.0.0.22-alpha.1.Cd1awv3t.css → vuetify.0.0.22-alpha.3.CgGsw6iO.css} +2 -2
  46. package/dist/interface/birpc.l0sNRNKZ.0.0.22-alpha.3.js +1 -0
  47. package/dist/interface/{dnd-core.DMTh_43Y.0.0.22-alpha.1.js → dnd-core.B29WFSBv.0.0.22-alpha.3.js} +1 -1
  48. package/dist/interface/{draggabilly.Bp5rpROY.0.0.22-alpha.1.js → draggabilly.DqeTwBQP.0.0.22-alpha.3.js} +1 -1
  49. package/dist/interface/engine.io-client.JaCvSrgR.0.0.22-alpha.3.js +1 -0
  50. package/dist/interface/{ev-emitter.D9A4-Zp4.0.0.22-alpha.1.js → ev-emitter.Ctd6XSNq.0.0.22-alpha.3.js} +1 -1
  51. package/dist/interface/{fast-deep-equal.CynR0Ykh.0.0.22-alpha.1.js → fast-deep-equal.CFCsEgyF.0.0.22-alpha.3.js} +1 -1
  52. package/dist/interface/{highlight.js.BcAmtPT9.0.0.22-alpha.1.js → highlight.js.QZPea1Ru.0.0.22-alpha.3.js} +1 -1
  53. package/dist/interface/hookable.B8xFkYCm.0.0.22-alpha.3.js +1 -0
  54. package/dist/interface/index.html +34 -36
  55. package/dist/interface/{linkify-it.zJgnXBKD.0.0.22-alpha.1.js → linkify-it.BT40Wvw5.0.0.22-alpha.3.js} +1 -1
  56. package/dist/interface/main.BASwd6Tx.0.0.22-alpha.3.js +5 -0
  57. package/dist/interface/{markdown-it.DSn07YT-.0.0.22-alpha.1.js → markdown-it.DMx4rp8B.0.0.22-alpha.3.js} +1 -1
  58. package/dist/interface/{nprogress.B-sfF0qV.0.0.22-alpha.1.js → nprogress.Bqe-TtYa.0.0.22-alpha.3.js} +1 -1
  59. package/dist/interface/perfect-debounce.Cp2ysxOb.0.0.22-alpha.3.js +1 -0
  60. package/dist/interface/pinia.nQAfYRjL.0.0.22-alpha.3.js +5 -0
  61. package/dist/interface/plugins.CHFY7I4J.0.0.22-alpha.3.js +1 -0
  62. package/dist/interface/point-in-polygon-hao.l0sNRNKZ.0.0.22-alpha.3.js +1 -0
  63. package/dist/interface/{qrcode.BcJHYbhe.0.0.22-alpha.1.js → qrcode.BSQ3LbvQ.0.0.22-alpha.3.js} +1 -1
  64. package/dist/interface/{react-dnd-touch-backend.B9_17rX-.0.0.22-alpha.1.js → react-dnd-touch-backend.B_d86_Kg.0.0.22-alpha.3.js} +1 -1
  65. package/dist/interface/{rxjs.BlwZeIMX.0.0.22-alpha.1.js → rxjs.D2GEiPyD.0.0.22-alpha.3.js} +1 -1
  66. package/dist/interface/socket.io-client.DOo2Esna.0.0.22-alpha.3.js +1 -0
  67. package/dist/interface/{socket.io-parser.DbDzb_0x.0.0.22-alpha.1.js → socket.io-parser.q3PQfUUu.0.0.22-alpha.3.js} +1 -1
  68. package/dist/interface/sw.js +1 -1
  69. package/dist/interface/sweepline-intersections.l0sNRNKZ.0.0.22-alpha.3.js +1 -0
  70. package/dist/interface/system.szbtAGtP.0.0.22-alpha.3.js +1 -0
  71. package/dist/interface/types.Cz9TaZAP.0.0.22-alpha.3.js +1 -0
  72. package/dist/interface/{unidragger.BfsybYBO.0.0.22-alpha.1.js → unidragger.DwHLT_zc.0.0.22-alpha.3.js} +1 -1
  73. package/dist/interface/utils.mAKpSMLY.0.0.22-alpha.3.js +1 -0
  74. package/dist/interface/uuid.Ch9TGLTe.0.0.22-alpha.3.js +1 -0
  75. package/dist/interface/vee-validate.qxpwZY6E.0.0.22-alpha.3.js +5 -0
  76. package/dist/interface/vue-i18n.DMhK1_Az.0.0.22-alpha.3.js +5 -0
  77. package/dist/interface/{vue-inline-svg.Br_paQwQ.0.0.22-alpha.1.js → vue-inline-svg.Prc07HPO.0.0.22-alpha.3.js} +1 -1
  78. package/dist/interface/vue-router.C9BwSYH-.0.0.22-alpha.3.js +5 -0
  79. package/dist/interface/vue.l0sNRNKZ.0.0.22-alpha.3.js +1 -0
  80. package/dist/interface/vue3-apexcharts.hYX9eZBy.0.0.22-alpha.3.js +1 -0
  81. package/dist/interface/{vue3-dnd.DpYuZy8Q.0.0.22-alpha.1.js → vue3-dnd.DSl3niZz.0.0.22-alpha.3.js} +1 -1
  82. package/dist/interface/vue3-toastify.B5gZpsI3.0.0.22-alpha.3.js +1 -0
  83. package/dist/interface/vuetify.B9f2I1HK.0.0.22-alpha.3.js +5 -0
  84. package/dist/interface/zod.DnW1_kUe.0.0.22-alpha.3.js +1 -0
  85. package/dist/server/bin/cameraui-server.js +8 -0
  86. package/dist/server/bin/cameraui-server.js.map +1 -0
  87. package/dist/server/package.json +44 -70
  88. package/dist/server/requirements.txt +6 -5
  89. package/dist/server/src/api/controllers/auth.controller.js +1 -1
  90. package/dist/server/src/api/controllers/auth.controller.js.map +1 -1
  91. package/dist/server/src/api/controllers/backup.controller.js +2 -2
  92. package/dist/server/src/api/controllers/backup.controller.js.map +1 -1
  93. package/dist/server/src/api/controllers/cameras.controller.d.ts +4 -2
  94. package/dist/server/src/api/controllers/cameras.controller.js +88 -42
  95. package/dist/server/src/api/controllers/cameras.controller.js.map +1 -1
  96. package/dist/server/src/api/controllers/files.controller.js.map +1 -1
  97. package/dist/server/src/api/controllers/frameWorkers.controller.d.ts +1 -1
  98. package/dist/server/src/api/controllers/frameWorkers.controller.js +15 -7
  99. package/dist/server/src/api/controllers/frameWorkers.controller.js.map +1 -1
  100. package/dist/server/src/api/controllers/plugins.controller.d.ts +3 -4
  101. package/dist/server/src/api/controllers/plugins.controller.js +141 -202
  102. package/dist/server/src/api/controllers/plugins.controller.js.map +1 -1
  103. package/dist/server/src/api/controllers/system.controller.d.ts +9 -3
  104. package/dist/server/src/api/controllers/system.controller.js +73 -53
  105. package/dist/server/src/api/controllers/system.controller.js.map +1 -1
  106. package/dist/server/src/api/controllers/users.controller.js +12 -10
  107. package/dist/server/src/api/controllers/users.controller.js.map +1 -1
  108. package/dist/server/src/api/database/checks.d.ts +55 -0
  109. package/dist/server/src/api/database/checks.js +183 -0
  110. package/dist/server/src/api/database/checks.js.map +1 -0
  111. package/dist/server/src/api/database/constants.d.ts +8 -0
  112. package/dist/server/src/api/database/constants.js +9 -0
  113. package/dist/server/src/api/database/constants.js.map +1 -0
  114. package/dist/server/src/api/database/index.d.ts +4 -13
  115. package/dist/server/src/api/database/index.js +61 -39
  116. package/dist/server/src/api/database/index.js.map +1 -1
  117. package/dist/server/src/api/database/migration.d.ts +1 -0
  118. package/dist/server/src/api/database/migration.js +73 -7
  119. package/dist/server/src/api/database/migration.js.map +1 -1
  120. package/dist/server/src/api/database/selfcheck.d.ts +48 -0
  121. package/dist/server/src/api/database/selfcheck.js +398 -0
  122. package/dist/server/src/api/database/selfcheck.js.map +1 -0
  123. package/dist/server/src/api/database/types.d.ts +15 -141
  124. package/dist/server/src/api/go2rtc/api/application.js +3 -2
  125. package/dist/server/src/api/go2rtc/api/application.js.map +1 -1
  126. package/dist/server/src/api/go2rtc/api/index.js +3 -2
  127. package/dist/server/src/api/go2rtc/api/index.js.map +1 -1
  128. package/dist/server/src/api/go2rtc/api/streams.d.ts +1 -1
  129. package/dist/server/src/api/go2rtc/api/streams.js +4 -2
  130. package/dist/server/src/api/go2rtc/api/streams.js.map +1 -1
  131. package/dist/server/src/api/go2rtc/index.d.ts +1 -0
  132. package/dist/server/src/api/go2rtc/index.js +6 -1
  133. package/dist/server/src/api/go2rtc/index.js.map +1 -1
  134. package/dist/server/src/api/go2rtc/types.d.ts +2 -18
  135. package/dist/server/src/api/index.d.ts +1 -0
  136. package/dist/server/src/api/index.js +21 -29
  137. package/dist/server/src/api/index.js.map +1 -1
  138. package/dist/server/src/api/middlewares/authPermission.middleware.d.ts +3 -3
  139. package/dist/server/src/api/middlewares/authPermission.middleware.js.map +1 -1
  140. package/dist/server/src/api/middlewares/authValidation.middleware.d.ts +2 -2
  141. package/dist/server/src/api/middlewares/authValidation.middleware.js +3 -3
  142. package/dist/server/src/api/middlewares/authValidation.middleware.js.map +1 -1
  143. package/dist/server/src/api/middlewares/socketAuth.middleware.d.ts +1 -1
  144. package/dist/server/src/api/middlewares/socketAuth.middleware.js +1 -1
  145. package/dist/server/src/api/plugins/header.plugin.d.ts +2 -0
  146. package/dist/server/src/api/plugins/header.plugin.js +13 -0
  147. package/dist/server/src/api/plugins/header.plugin.js.map +1 -0
  148. package/dist/server/src/api/plugins/logger.plugin.js +1 -1
  149. package/dist/server/src/api/plugins/logger.plugin.js.map +1 -1
  150. package/dist/server/src/api/plugins/system.plugin.d.ts +3 -1
  151. package/dist/server/src/api/plugins/system.plugin.js +6 -1
  152. package/dist/server/src/api/plugins/system.plugin.js.map +1 -1
  153. package/dist/server/src/api/plugins/useragent.plugin.d.ts +1 -1
  154. package/dist/server/src/api/plugins/useragent.plugin.js +1 -1
  155. package/dist/server/src/api/plugins/useragent.plugin.js.map +1 -1
  156. package/dist/server/src/api/routes/cameras.routes.js +12 -0
  157. package/dist/server/src/api/routes/cameras.routes.js.map +1 -1
  158. package/dist/server/src/api/routes/plugins.routes.js +24 -0
  159. package/dist/server/src/api/routes/plugins.routes.js.map +1 -1
  160. package/dist/server/src/api/routes/system.routes.js +3 -6
  161. package/dist/server/src/api/routes/system.routes.js.map +1 -1
  162. package/dist/server/src/api/schemas/backup.schema.js.map +1 -1
  163. package/dist/server/src/api/schemas/cameras.schema.d.ts +227 -187
  164. package/dist/server/src/api/schemas/cameras.schema.js +25 -6
  165. package/dist/server/src/api/schemas/cameras.schema.js.map +1 -1
  166. package/dist/server/src/api/schemas/config.schema.d.ts +12 -20
  167. package/dist/server/src/api/schemas/config.schema.js +0 -2
  168. package/dist/server/src/api/schemas/config.schema.js.map +1 -1
  169. package/dist/server/src/api/schemas/go2rtc.schema.d.ts +143 -143
  170. package/dist/server/src/api/schemas/plugins.schema.d.ts +5 -5
  171. package/dist/server/src/api/schemas/plugins.schema.js +1 -1
  172. package/dist/server/src/api/schemas/plugins.schema.js.map +1 -1
  173. package/dist/server/src/api/schemas/system.schema.d.ts +8 -0
  174. package/dist/server/src/api/schemas/system.schema.js +5 -0
  175. package/dist/server/src/api/schemas/system.schema.js.map +1 -1
  176. package/dist/server/src/api/schemas/users.schema.d.ts +170 -170
  177. package/dist/server/src/api/schemas/users.schema.js.map +1 -1
  178. package/dist/server/src/api/services/auth.service.js +17 -17
  179. package/dist/server/src/api/services/auth.service.js.map +1 -1
  180. package/dist/server/src/api/services/backup.service.js.map +1 -1
  181. package/dist/server/src/api/services/cameras.service.d.ts +10 -5
  182. package/dist/server/src/api/services/cameras.service.js +166 -89
  183. package/dist/server/src/api/services/cameras.service.js.map +1 -1
  184. package/dist/server/src/api/services/plugins.service.d.ts +1 -0
  185. package/dist/server/src/api/services/plugins.service.js +16 -11
  186. package/dist/server/src/api/services/plugins.service.js.map +1 -1
  187. package/dist/server/src/api/services/system.service.js +4 -4
  188. package/dist/server/src/api/services/system.service.js.map +1 -1
  189. package/dist/server/src/api/services/users.service.js +29 -29
  190. package/dist/server/src/api/services/users.service.js.map +1 -1
  191. package/dist/server/src/api/types/index.d.ts +127 -129
  192. package/dist/server/src/api/types/index.js.map +1 -1
  193. package/dist/server/src/api/utils/cameraSource.d.ts +2 -0
  194. package/dist/server/src/api/utils/cameraSource.js +34 -0
  195. package/dist/server/src/api/utils/cameraSource.js.map +1 -0
  196. package/dist/server/src/api/utils/cert.d.ts +7 -7
  197. package/dist/server/src/api/utils/cert.js +178 -385
  198. package/dist/server/src/api/utils/cert.js.map +1 -1
  199. package/dist/server/src/api/utils/constants.d.ts +0 -2
  200. package/dist/server/src/api/utils/constants.js +4 -7
  201. package/dist/server/src/api/utils/constants.js.map +1 -1
  202. package/dist/server/src/api/websocket/index.js +2 -1
  203. package/dist/server/src/api/websocket/index.js.map +1 -1
  204. package/dist/server/src/api/websocket/nsp/logs.d.ts +10 -2
  205. package/dist/server/src/api/websocket/nsp/logs.js +110 -76
  206. package/dist/server/src/api/websocket/nsp/logs.js.map +1 -1
  207. package/dist/server/src/api/websocket/nsp/metrics.d.ts +1 -1
  208. package/dist/server/src/api/websocket/nsp/metrics.js +19 -16
  209. package/dist/server/src/api/websocket/nsp/metrics.js.map +1 -1
  210. package/dist/server/src/api/websocket/nsp/notifications.js +1 -1
  211. package/dist/server/src/api/websocket/nsp/notifications.js.map +1 -1
  212. package/dist/server/src/api/websocket/nsp/plugins.d.ts +1 -1
  213. package/dist/server/src/api/websocket/nsp/plugins.js +3 -4
  214. package/dist/server/src/api/websocket/nsp/plugins.js.map +1 -1
  215. package/dist/server/src/api/websocket/nsp/server.d.ts +9 -4
  216. package/dist/server/src/api/websocket/nsp/server.js +57 -20
  217. package/dist/server/src/api/websocket/nsp/server.js.map +1 -1
  218. package/dist/server/src/api/websocket/nsp/status.d.ts +1 -1
  219. package/dist/server/src/api/websocket/nsp/status.js +9 -7
  220. package/dist/server/src/api/websocket/nsp/status.js.map +1 -1
  221. package/dist/server/src/api/websocket/types.d.ts +7 -13
  222. package/dist/server/src/api.d.ts +8 -23
  223. package/dist/server/src/api.js +43 -24
  224. package/dist/server/src/api.js.map +1 -1
  225. package/dist/server/src/camera/controller.d.ts +31 -14
  226. package/dist/server/src/camera/controller.js +371 -68
  227. package/dist/server/src/camera/controller.js.map +1 -1
  228. package/dist/server/src/{decoder/worker.d.ts → camera/frameWorker.d.ts} +11 -8
  229. package/dist/server/src/camera/frameWorker.js +305 -0
  230. package/dist/server/src/camera/frameWorker.js.map +1 -0
  231. package/dist/server/src/camera/types.d.ts +1 -199
  232. package/dist/server/src/camera/types.js +1 -6
  233. package/dist/server/src/camera/types.js.map +1 -1
  234. package/dist/server/src/go2rtc/index.js +23 -11
  235. package/dist/server/src/go2rtc/index.js.map +1 -1
  236. package/dist/server/src/main.d.ts +21 -0
  237. package/dist/server/src/main.js +130 -74
  238. package/dist/server/src/main.js.map +1 -1
  239. package/dist/server/src/nats/index.d.ts +5 -5
  240. package/dist/server/src/nats/index.js +5 -6
  241. package/dist/server/src/nats/index.js.map +1 -1
  242. package/dist/server/src/nats/proxy/cameraDevice.d.ts +4 -4
  243. package/dist/server/src/nats/proxy/cameraDevice.js +41 -58
  244. package/dist/server/src/nats/proxy/cameraDevice.js.map +1 -1
  245. package/dist/server/src/nats/proxy/coreManager.d.ts +4 -4
  246. package/dist/server/src/nats/proxy/coreManager.js +6 -1
  247. package/dist/server/src/nats/proxy/coreManager.js.map +1 -1
  248. package/dist/server/src/nats/proxy/deviceManager.d.ts +5 -7
  249. package/dist/server/src/nats/proxy/deviceManager.js +4 -2
  250. package/dist/server/src/nats/proxy/deviceManager.js.map +1 -1
  251. package/dist/server/src/nats/server.js +33 -22
  252. package/dist/server/src/nats/server.js.map +1 -1
  253. package/dist/server/src/nats/types.d.ts +3 -121
  254. package/dist/server/src/nats/utils.d.ts +1 -1
  255. package/dist/server/src/nats/websocket.d.ts +2 -2
  256. package/dist/server/src/nats/websocket.js +7 -6
  257. package/dist/server/src/nats/websocket.js.map +1 -1
  258. package/dist/server/src/plugins/index.d.ts +3 -4
  259. package/dist/server/src/plugins/index.js +40 -38
  260. package/dist/server/src/plugins/index.js.map +1 -1
  261. package/dist/server/src/plugins/plugin.d.ts +6 -3
  262. package/dist/server/src/plugins/plugin.js +59 -23
  263. package/dist/server/src/plugins/plugin.js.map +1 -1
  264. package/dist/server/src/plugins/types.d.ts +1 -148
  265. package/dist/server/src/plugins/types.js +0 -15
  266. package/dist/server/src/plugins/types.js.map +1 -1
  267. package/dist/server/src/plugins/worker.d.ts +22 -3
  268. package/dist/server/src/plugins/worker.js +201 -59
  269. package/dist/server/src/plugins/worker.js.map +1 -1
  270. package/dist/server/src/services/config/constants.d.ts +3 -1
  271. package/dist/server/src/services/config/constants.js +12 -8
  272. package/dist/server/src/services/config/constants.js.map +1 -1
  273. package/dist/server/src/services/config/index.d.ts +15 -9
  274. package/dist/server/src/services/config/index.js +135 -46
  275. package/dist/server/src/services/config/index.js.map +1 -1
  276. package/dist/server/src/services/config/types.d.ts +10 -15
  277. package/dist/server/src/services/config/types.js.map +1 -1
  278. package/dist/server/src/services/logger/index.d.ts +10 -17
  279. package/dist/server/src/services/logger/index.js +44 -91
  280. package/dist/server/src/services/logger/index.js.map +1 -1
  281. package/dist/server/src/types.d.ts +24 -0
  282. package/localdeps.txt +6 -0
  283. package/package.json +44 -70
  284. package/dist/interface/@intlify.YW_pt133.0.0.22-alpha.1.js +0 -15
  285. package/dist/interface/@mdi.DnMbZhUH.0.0.22-alpha.1.js +0 -1
  286. package/dist/interface/@popperjs.BQBsAJpH.0.0.22-alpha.1.js +0 -1
  287. package/dist/interface/@tanstack.DlheOlVk.0.0.22-alpha.1.js +0 -1
  288. package/dist/interface/@vue.CvjRlaU6.0.0.22-alpha.1.js +0 -17
  289. package/dist/interface/@vueuse.-m94veKi.0.0.22-alpha.1.js +0 -1
  290. package/dist/interface/Account.CvNGInZy.0.0.22-alpha.1.js +0 -1
  291. package/dist/interface/Adminpanel.B38rrP4P.0.0.22-alpha.1.js +0 -2
  292. package/dist/interface/Appearance.kFVBM4J9.0.0.22-alpha.1.js +0 -1
  293. package/dist/interface/Backup.lo3nC5DR.0.0.22-alpha.1.js +0 -1
  294. package/dist/interface/Camera.BukjTYOy.0.0.22-alpha.1.js +0 -1
  295. package/dist/interface/Cameras.HNjLEphi.0.0.22-alpha.1.js +0 -1
  296. package/dist/interface/Camview.BXcJwv3e.0.0.22-alpha.1.js +0 -1
  297. package/dist/interface/Config.Bwtjrsr9.0.0.22-alpha.1.js +0 -1
  298. package/dist/interface/Console.DOkTKmKh.0.0.22-alpha.1.js +0 -4
  299. package/dist/interface/FirstSteps.BXQqfdBY.0.0.22-alpha.1.js +0 -1
  300. package/dist/interface/Plugin.DlATvyTj.0.0.22-alpha.1.js +0 -1
  301. package/dist/interface/Plugins.BekJdBK8.0.0.22-alpha.1.js +0 -1
  302. package/dist/interface/Recordings.B4YRWWi3.0.0.22-alpha.1.js +0 -1
  303. package/dist/interface/Recordings.U1858KpO.0.0.22-alpha.1.js +0 -1
  304. package/dist/interface/Settings.CiF0fVqP.0.0.22-alpha.1.js +0 -1
  305. package/dist/interface/System.Ca9T8x4i.0.0.22-alpha.1.js +0 -4
  306. package/dist/interface/User.C_3ugpqz.0.0.22-alpha.1.js +0 -1
  307. package/dist/interface/VConfigEditor.vue_vue_type_script_setup_true_lang.EB4E_zDr.0.0.22-alpha.1.js +0 -2
  308. package/dist/interface/VConsole.DJWV6CZ9.0.0.22-alpha.1.js +0 -1
  309. package/dist/interface/VPlayer.CpZzx0nW.0.0.22-alpha.1.js +0 -1
  310. package/dist/interface/VPluginCard.Cm4M7xYg.0.0.22-alpha.1.js +0 -4
  311. package/dist/interface/assets/Adminpanel.0.0.22-alpha.1.CXsTAXPL.css +0 -1
  312. package/dist/interface/assets/Camera.0.0.22-alpha.1.BDtUJ-lA.css +0 -1
  313. package/dist/interface/assets/Cameras.0.0.22-alpha.1.Djx0F2MM.css +0 -1
  314. package/dist/interface/assets/Camview.0.0.22-alpha.1.Ce_V-Nxj.css +0 -1
  315. package/dist/interface/assets/Config.0.0.22-alpha.1.k4QpWumg.css +0 -1
  316. package/dist/interface/assets/Console.0.0.22-alpha.1.DWrfRWs9.css +0 -1
  317. package/dist/interface/assets/FirstSteps.0.0.22-alpha.1.B3-pv8-a.css +0 -1
  318. package/dist/interface/assets/NewCamera.0.0.22-alpha.1.DJ3tUBT_.css +0 -1
  319. package/dist/interface/assets/VConsole.0.0.22-alpha.1.BZT1WyS-.css +0 -1
  320. package/dist/interface/assets/VPlayer.0.0.22-alpha.1.CZXlTn4I.css +0 -1
  321. package/dist/interface/assets/VPluginCard.0.0.22-alpha.1.CIL48ca_.css +0 -1
  322. package/dist/interface/assets/main.0.0.22-alpha.1.BOf8IWhK.css +0 -1
  323. package/dist/interface/assets/v-calendar.0.0.22-alpha.1.CtSuDYZU.css +0 -1
  324. package/dist/interface/engine.io-client.CY7UpWto.0.0.22-alpha.1.js +0 -1
  325. package/dist/interface/main.D-V5Qegn.0.0.22-alpha.1.js +0 -4
  326. package/dist/interface/pinia.Dn9R-5lV.0.0.22-alpha.1.js +0 -5
  327. package/dist/interface/plugins.9yif7gTi.0.0.22-alpha.1.js +0 -1
  328. package/dist/interface/socket.io-client.ZxUZ7LHn.0.0.22-alpha.1.js +0 -1
  329. package/dist/interface/system.D_1Xg-Sy.0.0.22-alpha.1.js +0 -1
  330. package/dist/interface/ui.BA2qa-Pn.0.0.22-alpha.1.js +0 -1
  331. package/dist/interface/utils.BvINh1mj.0.0.22-alpha.1.js +0 -1
  332. package/dist/interface/uuid.DvF23Exx.0.0.22-alpha.1.js +0 -1
  333. package/dist/interface/v-calendar.CemaWgJz.0.0.22-alpha.1.js +0 -1
  334. package/dist/interface/vee-validate.CpAAwmyb.0.0.22-alpha.1.js +0 -5
  335. package/dist/interface/vue-i18n.mw20Rif9.0.0.22-alpha.1.js +0 -5
  336. package/dist/interface/vue-router.BchJROVt.0.0.22-alpha.1.js +0 -5
  337. package/dist/interface/vue3-apexcharts.BiZhZbF2.0.0.22-alpha.1.js +0 -1
  338. package/dist/interface/vue3-toastify.DdCHHmXT.0.0.22-alpha.1.js +0 -1
  339. package/dist/interface/vuetify.red0JsnZ.0.0.22-alpha.1.js +0 -5
  340. package/dist/interface/zod.BaF2dDCd.0.0.22-alpha.1.js +0 -1
  341. package/dist/server/bin/cameraui.d.ts +0 -54
  342. package/dist/server/bin/cameraui.js +0 -622
  343. package/dist/server/bin/cameraui.js.map +0 -1
  344. package/dist/server/bin/fork.js +0 -13
  345. package/dist/server/bin/fork.js.map +0 -1
  346. package/dist/server/bin/installer/base.d.ts +0 -17
  347. package/dist/server/bin/installer/base.js +0 -45
  348. package/dist/server/bin/installer/base.js.map +0 -1
  349. package/dist/server/bin/installer/darwin.d.ts +0 -61
  350. package/dist/server/bin/installer/darwin.js +0 -249
  351. package/dist/server/bin/installer/darwin.js.map +0 -1
  352. package/dist/server/bin/installer/freebsd.d.ts +0 -64
  353. package/dist/server/bin/installer/freebsd.js +0 -254
  354. package/dist/server/bin/installer/freebsd.js.map +0 -1
  355. package/dist/server/bin/installer/linux.d.ts +0 -103
  356. package/dist/server/bin/installer/linux.js +0 -482
  357. package/dist/server/bin/installer/linux.js.map +0 -1
  358. package/dist/server/bin/installer/win32.d.ts +0 -45
  359. package/dist/server/bin/installer/win32.js +0 -178
  360. package/dist/server/bin/installer/win32.js.map +0 -1
  361. package/dist/server/src/api/plugins/cameraui.plugin.d.ts +0 -11
  362. package/dist/server/src/api/plugins/cameraui.plugin.js +0 -6
  363. package/dist/server/src/api/plugins/cameraui.plugin.js.map +0 -1
  364. package/dist/server/src/api/plugins/database.plugin.d.ts +0 -11
  365. package/dist/server/src/api/plugins/database.plugin.js +0 -12
  366. package/dist/server/src/api/plugins/database.plugin.js.map +0 -1
  367. package/dist/server/src/api/plugins/go2rtc.plugin.d.ts +0 -11
  368. package/dist/server/src/api/plugins/go2rtc.plugin.js +0 -11
  369. package/dist/server/src/api/plugins/go2rtc.plugin.js.map +0 -1
  370. package/dist/server/src/camera/device.d.ts +0 -29
  371. package/dist/server/src/camera/device.js +0 -20
  372. package/dist/server/src/camera/device.js.map +0 -1
  373. package/dist/server/src/camera/index.d.ts +0 -94
  374. package/dist/server/src/camera/index.js +0 -620
  375. package/dist/server/src/camera/index.js.map +0 -1
  376. package/dist/server/src/camera/interfaces/camera.d.ts +0 -10
  377. package/dist/server/src/camera/interfaces/camera.js +0 -23
  378. package/dist/server/src/camera/interfaces/camera.js.map +0 -1
  379. package/dist/server/src/camera/interfaces/prebuffer.d.ts +0 -11
  380. package/dist/server/src/camera/interfaces/prebuffer.js +0 -26
  381. package/dist/server/src/camera/interfaces/prebuffer.js.map +0 -1
  382. package/dist/server/src/camera/interfaces/ptz.d.ts +0 -13
  383. package/dist/server/src/camera/interfaces/ptz.js +0 -47
  384. package/dist/server/src/camera/interfaces/ptz.js.map +0 -1
  385. package/dist/server/src/camera/iou.d.ts +0 -2
  386. package/dist/server/src/camera/iou.js +0 -53
  387. package/dist/server/src/camera/iou.js.map +0 -1
  388. package/dist/server/src/camera/polygon.d.ts +0 -6
  389. package/dist/server/src/camera/polygon.js +0 -151
  390. package/dist/server/src/camera/polygon.js.map +0 -1
  391. package/dist/server/src/camera/streaming/peer-connection.d.ts +0 -55
  392. package/dist/server/src/camera/streaming/peer-connection.js +0 -203
  393. package/dist/server/src/camera/streaming/peer-connection.js.map +0 -1
  394. package/dist/server/src/camera/streaming/webrtc-connection.d.ts +0 -35
  395. package/dist/server/src/camera/streaming/webrtc-connection.js +0 -170
  396. package/dist/server/src/camera/streaming/webrtc-connection.js.map +0 -1
  397. package/dist/server/src/camera/streaming/werift-session.d.ts +0 -41
  398. package/dist/server/src/camera/streaming/werift-session.js +0 -179
  399. package/dist/server/src/camera/streaming/werift-session.js.map +0 -1
  400. package/dist/server/src/camera/videoFrame.d.ts +0 -24
  401. package/dist/server/src/camera/videoFrame.js +0 -104
  402. package/dist/server/src/camera/videoFrame.js.map +0 -1
  403. package/dist/server/src/decoder/index.d.ts +0 -11
  404. package/dist/server/src/decoder/index.js +0 -32
  405. package/dist/server/src/decoder/index.js.map +0 -1
  406. package/dist/server/src/decoder/types.d.ts +0 -151
  407. package/dist/server/src/decoder/types.js +0 -2
  408. package/dist/server/src/decoder/types.js.map +0 -1
  409. package/dist/server/src/decoder/worker.js +0 -245
  410. package/dist/server/src/decoder/worker.js.map +0 -1
  411. package/dist/server/src/index.d.ts +0 -18
  412. package/dist/server/src/index.js +0 -5
  413. package/dist/server/src/index.js.map +0 -1
  414. package/dist/server/src/nats/connection.d.ts +0 -17
  415. package/dist/server/src/nats/connection.js +0 -66
  416. package/dist/server/src/nats/connection.js.map +0 -1
  417. package/dist/server/src/nats/constants.d.ts +0 -1
  418. package/dist/server/src/nats/constants.js +0 -2
  419. package/dist/server/src/nats/constants.js.map +0 -1
  420. package/dist/server/src/nats/error.d.ts +0 -9
  421. package/dist/server/src/nats/error.js +0 -11
  422. package/dist/server/src/nats/error.js.map +0 -1
  423. package/dist/server/src/nats/messageQueue.d.ts +0 -20
  424. package/dist/server/src/nats/messageQueue.js +0 -132
  425. package/dist/server/src/nats/messageQueue.js.map +0 -1
  426. package/dist/server/src/nats/subscription.d.ts +0 -12
  427. package/dist/server/src/nats/subscription.js +0 -21
  428. package/dist/server/src/nats/subscription.js.map +0 -1
  429. package/dist/server/src/plugins/interfaces/audioDetection.d.ts +0 -7
  430. package/dist/server/src/plugins/interfaces/audioDetection.js +0 -4
  431. package/dist/server/src/plugins/interfaces/audioDetection.js.map +0 -1
  432. package/dist/server/src/plugins/interfaces/base.d.ts +0 -6
  433. package/dist/server/src/plugins/interfaces/base.js +0 -3
  434. package/dist/server/src/plugins/interfaces/base.js.map +0 -1
  435. package/dist/server/src/plugins/interfaces/motionDetection.d.ts +0 -6
  436. package/dist/server/src/plugins/interfaces/motionDetection.js +0 -4
  437. package/dist/server/src/plugins/interfaces/motionDetection.js.map +0 -1
  438. package/dist/server/src/plugins/interfaces/objectDetection.d.ts +0 -7
  439. package/dist/server/src/plugins/interfaces/objectDetection.js +0 -4
  440. package/dist/server/src/plugins/interfaces/objectDetection.js.map +0 -1
  441. package/dist/server/src/polyglot/node/decoder/child.d.ts +0 -1
  442. package/dist/server/src/polyglot/node/decoder/child.js +0 -644
  443. package/dist/server/src/polyglot/node/decoder/child.js.map +0 -1
  444. package/dist/server/src/polyglot/node/decoder/imageUtils.d.ts +0 -24
  445. package/dist/server/src/polyglot/node/decoder/imageUtils.js +0 -205
  446. package/dist/server/src/polyglot/node/decoder/imageUtils.js.map +0 -1
  447. package/dist/server/src/polyglot/node/decoder/wasm/build/decoder.d.ts +0 -144
  448. package/dist/server/src/polyglot/node/decoder/wasm/build/decoder.js +0 -65
  449. package/dist/server/src/polyglot/node/decoder/wasm/build/decoder.wasm +0 -0
  450. package/dist/server/src/polyglot/node/decoder/wasm/test/imageUtils.py +0 -106
  451. package/dist/server/src/polyglot/node/plugins/cameraStorage.d.ts +0 -107
  452. package/dist/server/src/polyglot/node/plugins/cameraStorage.js +0 -292
  453. package/dist/server/src/polyglot/node/plugins/cameraStorage.js.map +0 -1
  454. package/dist/server/src/polyglot/node/plugins/child.d.ts +0 -28
  455. package/dist/server/src/polyglot/node/plugins/child.js +0 -222
  456. package/dist/server/src/polyglot/node/plugins/child.js.map +0 -1
  457. package/dist/server/src/polyglot/node/plugins/configService.d.ts +0 -104
  458. package/dist/server/src/polyglot/node/plugins/configService.js +0 -213
  459. package/dist/server/src/polyglot/node/plugins/configService.js.map +0 -1
  460. package/dist/server/src/polyglot/node/plugins/pluginApi.d.ts +0 -35
  461. package/dist/server/src/polyglot/node/plugins/pluginApi.js +0 -23
  462. package/dist/server/src/polyglot/node/plugins/pluginApi.js.map +0 -1
  463. package/dist/server/src/polyglot/node/plugins/pluginLogger.d.ts +0 -18
  464. package/dist/server/src/polyglot/node/plugins/pluginLogger.js +0 -89
  465. package/dist/server/src/polyglot/node/plugins/pluginLogger.js.map +0 -1
  466. package/dist/server/src/polyglot/node/plugins/proxy/cameraDevice.d.ts +0 -69
  467. package/dist/server/src/polyglot/node/plugins/proxy/cameraDevice.js +0 -432
  468. package/dist/server/src/polyglot/node/plugins/proxy/cameraDevice.js.map +0 -1
  469. package/dist/server/src/polyglot/node/plugins/proxy/coreManager.d.ts +0 -40
  470. package/dist/server/src/polyglot/node/plugins/proxy/coreManager.js +0 -105
  471. package/dist/server/src/polyglot/node/plugins/proxy/coreManager.js.map +0 -1
  472. package/dist/server/src/polyglot/node/plugins/proxy/deviceManager.d.ts +0 -47
  473. package/dist/server/src/polyglot/node/plugins/proxy/deviceManager.js +0 -164
  474. package/dist/server/src/polyglot/node/plugins/proxy/deviceManager.js.map +0 -1
  475. package/dist/server/src/polyglot/node/plugins/schema.d.ts +0 -293
  476. package/dist/server/src/polyglot/node/plugins/schema.js +0 -740
  477. package/dist/server/src/polyglot/node/plugins/schema.js.map +0 -1
  478. package/dist/server/src/polyglot/node/plugins/storageController.d.ts +0 -30
  479. package/dist/server/src/polyglot/node/plugins/storageController.js +0 -40
  480. package/dist/server/src/polyglot/node/plugins/storageController.js.map +0 -1
  481. package/dist/server/src/polyglot/python/camera/interfaces/camera.py +0 -20
  482. package/dist/server/src/polyglot/python/camera/interfaces/prebuffer.py +0 -25
  483. package/dist/server/src/polyglot/python/camera/interfaces/ptz.py +0 -38
  484. package/dist/server/src/polyglot/python/camera/iou.py +0 -80
  485. package/dist/server/src/polyglot/python/camera/polygon.py +0 -173
  486. package/dist/server/src/polyglot/python/camera/video_frame.py +0 -188
  487. package/dist/server/src/polyglot/python/camera_ui_types/__init__.py +0 -1196
  488. package/dist/server/src/polyglot/python/decoder/child.py +0 -882
  489. package/dist/server/src/polyglot/python/decoder/image_utils.py +0 -149
  490. package/dist/server/src/polyglot/python/decoder/typings.py +0 -99
  491. package/dist/server/src/polyglot/python/plugins/camera_storage.py +0 -391
  492. package/dist/server/src/polyglot/python/plugins/child.py +0 -394
  493. package/dist/server/src/polyglot/python/plugins/config_service.py +0 -187
  494. package/dist/server/src/polyglot/python/plugins/constants.py +0 -1
  495. package/dist/server/src/polyglot/python/plugins/message_queue.py +0 -182
  496. package/dist/server/src/polyglot/python/plugins/plugin_api.py +0 -34
  497. package/dist/server/src/polyglot/python/plugins/plugin_logger.py +0 -111
  498. package/dist/server/src/polyglot/python/plugins/proxy/camera_device.py +0 -1677
  499. package/dist/server/src/polyglot/python/plugins/proxy/core_manager.py +0 -145
  500. package/dist/server/src/polyglot/python/plugins/proxy/device_manager.py +0 -226
  501. package/dist/server/src/polyglot/python/plugins/schema.py +0 -181
  502. package/dist/server/src/polyglot/python/plugins/storage_controller.py +0 -58
  503. package/dist/server/src/polyglot/python/plugins/typings.py +0 -253
  504. package/dist/server/src/polyglot/python/utilities/connection.py +0 -86
  505. package/dist/server/src/polyglot/python/utilities/json_lmdb.py +0 -19
  506. package/dist/server/src/polyglot/python/utilities/object_path.py +0 -195
  507. package/dist/server/src/polyglot/python/utilities/packer.py +0 -11
  508. package/dist/server/src/polyglot/python/utilities/subscriptions.py +0 -22
  509. package/dist/server/src/polyglot/python/utilities/task.py +0 -35
  510. package/dist/server/src/polyglot/python/utilities/thread.py +0 -10
  511. package/dist/server/src/polyglot/python/utilities/utils.py +0 -73
  512. package/dist/server/src/utils/ffmpeg.d.ts +0 -2
  513. package/dist/server/src/utils/ffmpeg.js +0 -61
  514. package/dist/server/src/utils/ffmpeg.js.map +0 -1
  515. package/dist/server/src/utils/network.d.ts +0 -12
  516. package/dist/server/src/utils/network.js +0 -92
  517. package/dist/server/src/utils/network.js.map +0 -1
  518. package/dist/server/src/utils/npm.d.ts +0 -4
  519. package/dist/server/src/utils/npm.js +0 -128
  520. package/dist/server/src/utils/npm.js.map +0 -1
  521. package/dist/server/src/utils/packer.d.ts +0 -2
  522. package/dist/server/src/utils/packer.js +0 -17
  523. package/dist/server/src/utils/packer.js.map +0 -1
  524. package/dist/server/src/utils/pythonInstaller.d.ts +0 -48
  525. package/dist/server/src/utils/pythonInstaller.js +0 -494
  526. package/dist/server/src/utils/pythonInstaller.js.map +0 -1
  527. package/dist/server/src/utils/reader.d.ts +0 -5
  528. package/dist/server/src/utils/reader.js +0 -41
  529. package/dist/server/src/utils/reader.js.map +0 -1
  530. package/dist/server/src/utils/subscribed.d.ts +0 -9
  531. package/dist/server/src/utils/subscribed.js +0 -17
  532. package/dist/server/src/utils/subscribed.js.map +0 -1
  533. package/dist/server/src/utils/utils.d.ts +0 -10
  534. package/dist/server/src/utils/utils.js +0 -165
  535. package/dist/server/src/utils/utils.js.map +0 -1
  536. package/upgrade-server.sh +0 -205
  537. /package/dist/interface/{@babel.l0sNRNKZ.0.0.22-alpha.1.js → @babel.l0sNRNKZ.0.0.22-alpha.3.js} +0 -0
  538. /package/dist/interface/{@react-dnd.CcwRs9xb.0.0.22-alpha.1.js → @react-dnd.CcwRs9xb.0.0.22-alpha.3.js} +0 -0
  539. /package/dist/interface/{@socket.io.Dkula2eQ.0.0.22-alpha.1.js → @socket.io.Dkula2eQ.0.0.22-alpha.3.js} +0 -0
  540. /package/dist/interface/{vue.l0sNRNKZ.0.0.22-alpha.1.js → @turf.l0sNRNKZ.0.0.22-alpha.3.js} +0 -0
  541. /package/dist/interface/{@xterm.DV-IE8JS.0.0.22-alpha.1.js → @xterm.nBWIhP-E.0.0.22-alpha.3.js} +0 -0
  542. /package/dist/interface/assets/{@vueform.0.0.22-alpha.1.h7tNX9p6.css → @vueform.0.0.22-alpha.3.CroAHJs8.css} +0 -0
  543. /package/dist/interface/assets/{@xterm.0.0.22-alpha.1.CGrrDQr5.css → @xterm.0.0.22-alpha.3.CFbL2ovg.css} +0 -0
  544. /package/dist/interface/assets/{Account.0.0.22-alpha.1.Ce3OmKrC.css → Account.0.0.22-alpha.3.J7oAjogS.css} +0 -0
  545. /package/dist/interface/assets/{Backup.0.0.22-alpha.1.BIwaSlv3.css → Backup.0.0.22-alpha.3.CX0rT0QJ.css} +0 -0
  546. /package/dist/interface/assets/{Plugin.0.0.22-alpha.1.BtRA6zDt.css → Plugin.0.0.22-alpha.3.DJbgaQc1.css} +0 -0
  547. /package/dist/interface/assets/{Plugins.0.0.22-alpha.1.Cwu0aGUO.css → Plugins.0.0.22-alpha.3.DXSoO9M1.css} +0 -0
  548. /package/dist/interface/assets/{User.0.0.22-alpha.1.DPDcJbx8.css → User.0.0.22-alpha.3.BiGtIFqt.css} +0 -0
  549. /package/dist/interface/assets/{highlight.0.0.22-alpha.1.DgoK_Xib.css → highlight.0.0.22-alpha.3.Ch2EwETz.css} +0 -0
  550. /package/dist/interface/assets/{logo-256.0.0.22-alpha.1.BCQk9H1-.png → logo-256.0.0.22-alpha.3.BCQk9H1-.png} +0 -0
  551. /package/dist/interface/assets/{logo-512.0.0.22-alpha.1.DLKVOU2S.png → logo-512.0.0.22-alpha.3.DLKVOU2S.png} +0 -0
  552. /package/dist/interface/assets/{logo.0.0.22-alpha.1.DmEiRk0z.png → logo.0.0.22-alpha.3.DmEiRk0z.png} +0 -0
  553. /package/dist/interface/assets/{mode-json.0.0.22-alpha.1.Br7xisR1.js → mode-json.0.0.22-alpha.3.Br7xisR1.js} +0 -0
  554. /package/dist/interface/assets/{mode-yaml.0.0.22-alpha.1.CIYL8U3d.js → mode-yaml.0.0.22-alpha.3.CIYL8U3d.js} +0 -0
  555. /package/dist/interface/assets/{vue3-toastify.0.0.22-alpha.1.DTY1DMRs.css → vue3-toastify.0.0.22-alpha.3.DHXAGmwn.css} +0 -0
  556. /package/dist/interface/{axios.C-n2IhIP.0.0.22-alpha.1.js → axios.C-n2IhIP.0.0.22-alpha.3.js} +0 -0
  557. /package/dist/interface/{compare-versions.DqEOhma6.0.0.22-alpha.1.js → compare-versions.DqEOhma6.0.0.22-alpha.3.js} +0 -0
  558. /package/dist/interface/{dijkstrajs.D_NXgYpA.0.0.22-alpha.1.js → dijkstrajs.D_NXgYpA.0.0.22-alpha.3.js} +0 -0
  559. /package/dist/interface/{engine.io-parser.BiEtp6m2.0.0.22-alpha.1.js → engine.io-parser.BiEtp6m2.0.0.22-alpha.3.js} +0 -0
  560. /package/dist/interface/{entities.C20TfXL6.0.0.22-alpha.1.js → entities.C20TfXL6.0.0.22-alpha.3.js} +0 -0
  561. /package/dist/interface/{get-size.D1dS-IaP.0.0.22-alpha.1.js → get-size.D1dS-IaP.0.0.22-alpha.3.js} +0 -0
  562. /package/dist/interface/{mdurl.k9Sl0PQj.0.0.22-alpha.1.js → mdurl.k9Sl0PQj.0.0.22-alpha.3.js} +0 -0
  563. /package/dist/interface/{punycode.js.Dj65hjkv.0.0.22-alpha.1.js → punycode.js.Dj65hjkv.0.0.22-alpha.3.js} +0 -0
  564. /package/dist/interface/{react-dnd-html5-backend.1HQjlkwI.0.0.22-alpha.1.js → react-dnd-html5-backend.1HQjlkwI.0.0.22-alpha.3.js} +0 -0
  565. /package/dist/interface/{redux.CuxFRhX_.0.0.22-alpha.1.js → redux.CuxFRhX_.0.0.22-alpha.3.js} +0 -0
  566. /package/dist/interface/{tslib.9k7AwCpt.0.0.22-alpha.1.js → tslib.9k7AwCpt.0.0.22-alpha.3.js} +0 -0
  567. /package/dist/interface/{uc.micro.kMc2yuuw.0.0.22-alpha.1.js → uc.micro.kMc2yuuw.0.0.22-alpha.3.js} +0 -0
  568. /package/dist/server/bin/{fork.d.ts → cameraui-server.d.ts} +0 -0
@@ -1,1677 +0,0 @@
1
- import asyncio
2
- import inspect
3
- import traceback
4
- from collections.abc import AsyncGenerator
5
- from contextlib import suppress
6
- from copy import deepcopy
7
- from datetime import datetime
8
- from typing import Any, Optional, Union, cast
9
- from uuid import uuid4
10
-
11
- import aiohttp
12
- from cachetools import LRUCache, cached
13
- from camera.iou import merge_detections
14
- from camera.polygon import are_motion_detections_valid, are_object_detections_valid
15
- from camera.video_frame import MotionFrame, VideoFrame
16
- from camera_ui_types import (
17
- AudioSetEvent,
18
- AudioState,
19
- BatterySetEvent,
20
- BatteryState,
21
- Camera,
22
- CameraActivitySettings,
23
- CameraConfigInputSettings,
24
- CameraConfigInputSettingsPartial,
25
- CameraDelegate,
26
- CameraDelegateMethodNames,
27
- CameraFrameWorkerSettings,
28
- CameraInformation,
29
- CameraInput,
30
- CameraPrebufferDelegate,
31
- CameraPrebufferDelegateMethodNames,
32
- CameraPropertyObservableObject,
33
- CameraPTZDelegate,
34
- CameraPTZDelegateMethodNames,
35
- CameraPublicProperties,
36
- CameraType,
37
- Container,
38
- DetectionZone,
39
- DoorbellSetEvent,
40
- DoorbellState,
41
- FrameData,
42
- FrameMetadata,
43
- FrameState,
44
- LightSetEvent,
45
- LightState,
46
- MotionSetEvent,
47
- MotionState,
48
- ObjectSetEvent,
49
- ObjectState,
50
- PrebufferState,
51
- SetValue,
52
- SirenSetEvent,
53
- SirenState,
54
- StateNames,
55
- StateValue,
56
- )
57
- from decoder.typings import AuthConfig, PingMessage, PongMessage, SignalingRequest, SignalingResponse
58
- from deepdiff import DeepDiff
59
- from message_queue import MessageQueue
60
- from nats.aio.msg import Msg
61
- from plugin_api import PluginAPI
62
- from plugin_logger import PluginLogger
63
- from reactivex import Observable
64
- from reactivex import operators as ops
65
- from reactivex.subject.behaviorsubject import BehaviorSubject
66
- from typing_extensions import Literal, overload
67
- from typings import (
68
- CameraDeviceProxyMethodNames,
69
- ClientType,
70
- Delegates,
71
- DeserializedError,
72
- FrameSubscribtion,
73
- PluginInfo,
74
- ProxyMessageStructure,
75
- )
76
- from utilities.connection import ProxyConnection
77
- from utilities.packer import pack, unpack
78
- from utilities.subscriptions import ProxySubscription
79
- from utilities.task import TaskSet
80
-
81
-
82
- class CameraSource:
83
- def __init__(self, source: CameraInput, parent: Any):
84
- self.__parent: CameraDeviceProxy = parent
85
-
86
- self.id = source["_id"]
87
- self.name = source["name"]
88
- self.roles = source["roles"]
89
- self.urls = source["urls"]
90
-
91
- async def update_prebuffer_state(self, container: Container, state: PrebufferState) -> None:
92
- return await self.__parent.prebufferDelegate.updatePrebufferState(self.id, container, state)
93
-
94
- def get_prebuffering_state(self, container: Container) -> PrebufferState:
95
- return self.__parent.camera_source_prebuffer_state(self.id, container)
96
-
97
- def on_prebuffering(self, container: Container) -> Observable[PrebufferState]:
98
- return self.__parent.create_prebuffer_state_observable(self.id, container)
99
-
100
- async def get_stream_info(self):
101
- return await self.__parent.prebufferDelegate.getStreamInfo(self.id)
102
-
103
-
104
- class CameraDeviceProxy:
105
- def __init__(
106
- self,
107
- api: PluginAPI,
108
- logger: PluginLogger,
109
- camera: Camera,
110
- plugin: PluginInfo,
111
- proxy_endpoints: list[str],
112
- auth: AuthConfig,
113
- ):
114
- self.snapshot_cache = LRUCache(maxsize=100)
115
- self.camera_subject = BehaviorSubject(camera)
116
-
117
- self.camera_state = BehaviorSubject[bool](False)
118
- self.light_state = BehaviorSubject[LightState](self.__get_light_state({"state": False}, True))
119
- self.motion_state = BehaviorSubject[MotionState](
120
- self.__get_motion_state({"detections": [], "state": False}, True)
121
- )
122
- self.audio_state = BehaviorSubject[AudioState](
123
- self.__get_audio_state({"state": False, "db": 0}, True)
124
- )
125
- self.object_state = BehaviorSubject[ObjectState](self.__get_object_state({"detections": []}, True))
126
- self.doorbell_state = BehaviorSubject[DoorbellState](
127
- self.__get_doorbell_state({"state": False}, True)
128
- )
129
- self.siren_state = BehaviorSubject[SirenState](
130
- self.__get_siren_state({"state": False, "level": 0}, True)
131
- )
132
- self.battery_state = BehaviorSubject[BatteryState](
133
- self.__get_battery_state({"level": 100, "charging": False, "lowBattery": False}, True)
134
- )
135
- self.__frame_state = BehaviorSubject[FrameState](
136
- {
137
- "timestamp": int(datetime.now().timestamp() * 1000),
138
- "detections": [],
139
- "frameData": cast(FrameData, {}),
140
- "metadata": cast(FrameMetadata, {}),
141
- },
142
- )
143
- self.prebuffer_state_subjects: dict[str, dict[str, BehaviorSubject[PrebufferState]]] = {}
144
-
145
- self.on_connected: Observable[bool] = self.__create_state_observable(self.camera_state)
146
- self.on_light_switched: Observable[LightState] = self.__create_state_observable(self.light_state)
147
- self.on_motion_detected: Observable[MotionState] = self.__create_state_observable(self.motion_state)
148
- self.on_audio_detected: Observable[AudioState] = self.__create_state_observable(self.audio_state)
149
- self.on_object_detected: Observable[ObjectState] = self.__create_state_observable(self.object_state)
150
- self.on_doorbell_pressed: Observable[DoorbellState] = self.__create_state_observable(
151
- self.doorbell_state
152
- )
153
- self.on_siren_detected: Observable[SirenState] = self.__create_state_observable(self.siren_state)
154
- self.on_battery_changed: Observable[BatteryState] = self.__create_state_observable(self.battery_state)
155
- self.__on_frame: Observable[FrameState] = self.__create_motion_frame_observable()
156
-
157
- if camera["pluginId"] == "native":
158
- self.camera_state.on_next(True)
159
-
160
- self.initialized = False
161
-
162
- self.api = api
163
- self.logger = logger
164
-
165
- self.auth = auth
166
- self.proxy_endpoints = proxy_endpoints
167
- self.plugin = plugin
168
-
169
- from camera.interfaces.camera import CameraInterface
170
- from camera.interfaces.prebuffer import CameraPrebufferInterface
171
- from camera.interfaces.ptz import CameraPTZInterface
172
-
173
- self.cameraDelegate = CameraInterface(self, logger)
174
- self.ptzDelegate = CameraPTZInterface(self, logger)
175
- self.prebufferDelegate = CameraPrebufferInterface(self, logger)
176
-
177
- self.subject = f"{self.plugin['id']}.camera.{self.id}"
178
- self.camera_subscriber_subject = f"{self.id}.camera"
179
- self.camera_plugin_subscriber_subject = f"{self.id}.camera.{self.plugin['id']}"
180
- self.frame_subject = f"{self.id}.frameReceiver"
181
- self.motion_frame_subject = f"{self.id}.frameGenerator.motionFrame"
182
- self.signaling_subject = f"{self.plugin['id']}.camera.{self.id}.signaling"
183
- self.signaling_target_subject = f"{self.id}.frameGenerator.signaling"
184
-
185
- self.publisher: Optional[ProxyConnection] = None
186
- self.camera_publisher: Optional[ProxyConnection] = None
187
- self.frame_publisher: Optional[ProxyConnection] = None
188
- self.motion_frame_publisher: Optional[ProxyConnection] = None
189
- self.signaling_publisher: Optional[ProxyConnection] = None
190
-
191
- self.subscriber: Optional[ProxySubscription] = None
192
- self.camera_subscriber: Optional[ProxySubscription] = None
193
- self.camera_plugin_subscriber: Optional[ProxySubscription] = None
194
- self.signaling_subscriber: Optional[ProxySubscription] = None
195
- self.frame_subscribers: list[FrameSubscribtion] = []
196
- self.motion_frame_subscribers: list[FrameSubscribtion] = []
197
-
198
- self.tasks: TaskSet = TaskSet(f"{self.plugin['name']} - {self.name} - CameraDeviceProxy")
199
- self.message_queue: Optional[MessageQueue] = None
200
- self.active_requests: set[str] = set()
201
- self.active_motion_requests: set[str] = set()
202
-
203
- # print(("INIT camera device with clientSubject", self.subject))
204
-
205
- self.__on_frame.subscribe(self.__on_motion_frame)
206
-
207
- self.api.once("shutdown", self.cleanup)
208
-
209
- @property
210
- def camera_object(self) -> Camera:
211
- return deepcopy(self.camera_subject.value)
212
-
213
- @property
214
- def id(self) -> str:
215
- return self.camera_subject.value.get("_id")
216
-
217
- @property
218
- def native_id(self) -> Optional[str]:
219
- return self.camera_subject.value.get("nativeId")
220
-
221
- @property
222
- def plugin_id(self) -> str:
223
- return self.camera_subject.value.get("pluginId")
224
-
225
- @property
226
- def connected(self) -> bool:
227
- return self.camera_state.value or False
228
-
229
- @property
230
- def disabled(self) -> bool:
231
- return self.camera_subject.value.get("disabled")
232
-
233
- @property
234
- def name(self) -> str:
235
- return self.camera_subject.value.get("name")
236
-
237
- @property
238
- def type(self) -> CameraType:
239
- return self.camera_subject.value.get("type")
240
-
241
- @property
242
- def info(self) -> CameraInformation:
243
- return deepcopy(self.camera_subject.value.get("info"))
244
-
245
- @property
246
- def is_cloud_camera(self) -> bool:
247
- return self.camera_subject.value.get("isCloud")
248
-
249
- @property
250
- def has_light(self) -> bool:
251
- return self.camera_subject.value.get("hasLight")
252
-
253
- @property
254
- def has_siren(self) -> bool:
255
- return self.camera_subject.value.get("hasSiren")
256
-
257
- @property
258
- def has_binary_sensor(self) -> bool:
259
- return self.camera_subject.value.get("hasBinarySensor")
260
-
261
- @property
262
- def has_battery(self) -> bool:
263
- return self.camera_subject.value.get("hasBattery")
264
-
265
- @property
266
- def has_motion_detector(self) -> bool:
267
- return self.camera_subject.value.get("hasMotionDetector")
268
-
269
- @property
270
- def has_audio_detector(self) -> bool:
271
- return self.camera_subject.value.get("hasAudioDetector")
272
-
273
- @property
274
- def has_object_detector(self) -> bool:
275
- return self.camera_subject.value.get("hasObjectDetector")
276
-
277
- @property
278
- def has_ptz(self) -> bool:
279
- return self.camera_subject.value.get("hasPtz")
280
-
281
- @property
282
- def has_prebuffer(self) -> bool:
283
- return self.camera_subject.value.get("hasPrebuffer")
284
-
285
- @property
286
- def activity_zones(self) -> list[DetectionZone]:
287
- return deepcopy(self.camera_subject.value.get("activityZones"))
288
-
289
- @property
290
- def activity_settings(self) -> CameraActivitySettings:
291
- return deepcopy(self.camera_subject.value.get("activitySettings"))
292
-
293
- @property
294
- def frameworker_settings(self) -> CameraFrameWorkerSettings:
295
- return deepcopy(self.camera_subject.value.get("frameWorkerSettings"))
296
-
297
- @property
298
- def sources(self) -> list[CameraSource]:
299
- sources = deepcopy(self.camera_subject.value.get("sources"))
300
- return [CameraSource(source, self) for source in sources]
301
-
302
- @property
303
- def stream_source(self) -> CameraSource:
304
- source = self.high_resolution_source or self.mid_resolution_source or self.low_resolution_source
305
- return cast(CameraSource, source)
306
-
307
- @property
308
- def snapshot_source(self) -> Optional[CameraSource]:
309
- return next(source for source in self.sources if "snapshot" in source.roles)
310
-
311
- @property
312
- def high_resolution_source(self) -> Optional[CameraSource]:
313
- return next(source for source in self.sources if "high-resolution" in source.roles)
314
-
315
- @property
316
- def mid_resolution_source(self) -> Optional[CameraSource]:
317
- return next(source for source in self.sources if "mid-resolution" in source.roles)
318
-
319
- @property
320
- def low_resolution_source(self) -> Optional[CameraSource]:
321
- return next(source for source in self.sources if "low-resolution" in source.roles)
322
-
323
- @property
324
- def ptz(self) -> CameraPTZDelegate:
325
- return self.ptzDelegate
326
-
327
- async def init(self):
328
- if self.initialized:
329
- return
330
-
331
- self.initialized = True
332
-
333
- self.publisher = ProxyConnection(self.subject, self.proxy_endpoints, self.auth)
334
- await self.publisher.connect()
335
-
336
- self.camera_publisher = ProxyConnection(
337
- self.camera_subscriber_subject, self.proxy_endpoints, self.auth
338
- )
339
- await self.camera_publisher.connect()
340
-
341
- self.signaling_publisher = ProxyConnection(self.signaling_subject, self.proxy_endpoints, self.auth)
342
- await self.signaling_publisher.connect()
343
-
344
- self.frame_publisher = ProxyConnection(self.frame_subject, self.proxy_endpoints, self.auth)
345
- await self.frame_publisher.connect()
346
-
347
- self.motion_frame_publisher = ProxyConnection(
348
- self.motion_frame_subject, self.proxy_endpoints, self.auth
349
- )
350
- await self.motion_frame_publisher.connect()
351
-
352
- self.subscriber = await self.publisher.subscribe(subject=self.subject)
353
- self.message_queue = MessageQueue(
354
- self.logger,
355
- self.publisher,
356
- self.subscriber,
357
- self.__request_handler,
358
- )
359
-
360
- self.signaling_subscriber = await self.signaling_publisher.subscribe(subject=self.signaling_subject)
361
- self.signaling_subscriber.on("message", self.__on_signaling_message)
362
-
363
- self.camera_subscriber = await self.camera_publisher.subscribe(subject=self.camera_subscriber_subject)
364
- self.camera_subscriber.on("message", self.__on_proxy_message)
365
-
366
- self.camera_plugin_subscriber = await self.camera_publisher.subscribe(
367
- subject=self.camera_plugin_subscriber_subject
368
- )
369
- self.camera_plugin_subscriber.on("message", self.__on_proxy_message)
370
-
371
- await self.refresh_states()
372
-
373
- @overload
374
- def set_delegate(self, name: Literal["cameraDelegate"], delegate: CameraDelegate) -> None: ...
375
- @overload
376
- def set_delegate(self, name: Literal["prebufferDelegate"], delegate: CameraPrebufferDelegate) -> None: ...
377
- @overload
378
- def set_delegate(self, name: Literal["ptzDelegate"], delegate: CameraPTZDelegate) -> None: ...
379
- def set_delegate(self, name: Delegates, delegate: Any) -> None:
380
- delegate = getattr(self, name, None)
381
-
382
- if delegate:
383
- delegate.delegate = delegate
384
-
385
- async def connect(self) -> None:
386
- return await self.on_request("cameraFn", "connect")
387
-
388
- async def disconnect(self) -> None:
389
- return await self.on_request("cameraFn", "disconnect")
390
-
391
- @cached(cache=lambda self: self.snapshot_cache) # type: ignore
392
- async def snapshot(self, force_new: Optional[bool] = None) -> Optional[bytes]:
393
- source = self.snapshot_source or self.stream_source
394
- cache_key = source.id
395
-
396
- snapshot_url = source.urls["www"]["jpegSnapshot"]
397
- from_cache: Any = self.snapshot_cache.get(snapshot_url) if cache_key in self.snapshot_cache else None
398
-
399
- if from_cache and not force_new:
400
- return from_cache
401
-
402
- if "snapshot" not in source.roles and self.camera_object["pluginId"] != "native":
403
- snapshot = await self.cameraDelegate.snapshot()
404
-
405
- if snapshot and len(snapshot) > 0:
406
- self.snapshot_cache[cache_key] = snapshot
407
-
408
- return snapshot
409
-
410
- async with aiohttp.ClientSession() as session, session.get(snapshot_url) as response:
411
- if response.status != 200:
412
- raise Exception(f"Status Code: {response.status}")
413
-
414
- snapshot = await response.read()
415
-
416
- if len(snapshot) > 0:
417
- self.snapshot_cache[cache_key] = snapshot
418
-
419
- return snapshot
420
-
421
- async def get_frames(self, prebuffer_duration: int = 0) -> AsyncGenerator[VideoFrame, None]:
422
- if not self.frame_publisher:
423
- raise Exception("Frame Publisher is not initialized")
424
-
425
- request_type: Literal["frame", "prebuffer"] = "frame"
426
- prebuffer_duration = abs(prebuffer_duration)
427
-
428
- if prebuffer_duration > 0:
429
- request_type = "prebuffer"
430
- prebuffer_duration = min(prebuffer_duration, 5)
431
-
432
- request_id = f"{str(uuid4())}-{request_type}"
433
-
434
- try:
435
- metadata = await self.__connect_to_decoder(request_id)
436
- frame_subscriber = await self.frame_publisher.subscribe(self.frame_subject)
437
-
438
- self.frame_subscribers.append({"request_id": request_id, "subscriber": frame_subscriber})
439
-
440
- try:
441
- async for msg in frame_subscriber.subscriber.messages:
442
- if (
443
- not self.initialized
444
- or len(self.active_requests) == 0
445
- or request_id not in self.active_requests
446
- ):
447
- return
448
-
449
- if len(msg.data) == 0:
450
- continue
451
-
452
- frame_data: FrameData = unpack(msg.data)
453
-
454
- yield VideoFrame(self.id, self.frame_publisher, frame_data, metadata, prebuffer_duration)
455
-
456
- except GeneratorExit:
457
- return
458
-
459
- except asyncio.CancelledError:
460
- return
461
- except Exception as e:
462
- if self.initialized:
463
- self.logger.error("Error while generating frames:", e)
464
- raise
465
- finally:
466
- await self.__disconnect_from_decoder(request_id)
467
-
468
- async def get_motion_frames(self) -> AsyncGenerator[MotionFrame, None]:
469
- if not self.motion_frame_publisher:
470
- raise Exception("Motion Frame Publisher is not initialized")
471
-
472
- request_id = f"{str(uuid4())}-motion"
473
-
474
- try:
475
- self.active_motion_requests.add(request_id)
476
-
477
- motion_frame_subscriber = await self.motion_frame_publisher.subscribe(self.motion_frame_subject)
478
-
479
- self.motion_frame_subscribers.append(
480
- {"request_id": request_id, "subscriber": motion_frame_subscriber}
481
- )
482
-
483
- try:
484
- async for msg in motion_frame_subscriber.subscriber.messages:
485
- if (
486
- not self.initialized
487
- or len(self.active_motion_requests) == 0
488
- or request_id not in self.active_motion_requests
489
- ):
490
- break
491
-
492
- if not msg or not msg.data or len(msg.data) == 0:
493
- continue
494
-
495
- motion_frame: FrameState = unpack(msg.data)
496
- motion_state: MotionState = {
497
- "timestamp": motion_frame["timestamp"],
498
- "detections": motion_frame["detections"],
499
- "lastEvent": motion_frame.get("lastEvent", None),
500
- "state": motion_frame.get("state", False),
501
- }
502
-
503
- yield MotionFrame(
504
- self.id,
505
- self.motion_frame_publisher,
506
- motion_frame["frameData"],
507
- motion_state,
508
- motion_frame["metadata"],
509
- )
510
-
511
- except GeneratorExit:
512
- return
513
-
514
- except asyncio.CancelledError:
515
- pass
516
- except Exception as e:
517
- if self.initialized:
518
- self.logger.error("Error while generating motion frames:", e)
519
- raise
520
- finally:
521
- if request_id in self.active_motion_requests:
522
- self.active_motion_requests.remove(request_id)
523
-
524
- motion_frame_subscribtion = next(
525
- (sub for sub in self.motion_frame_subscribers if sub["request_id"] == request_id), None
526
- )
527
-
528
- if motion_frame_subscribtion:
529
- self.motion_frame_subscribers.remove(motion_frame_subscribtion)
530
- await motion_frame_subscribtion["subscriber"].close()
531
-
532
- if len(self.motion_frame_subscribers) == 0:
533
- await self.__close_motion_frame_subscribers()
534
-
535
- @overload
536
- def get_value(self, state_name: Literal["light"]) -> LightState: ...
537
- @overload
538
- def get_value(self, state_name: Literal["motion"]) -> MotionState: ...
539
- @overload
540
- def get_value(self, state_name: Literal["audio"]) -> AudioState: ...
541
- @overload
542
- def get_value(self, state_name: Literal["object"]) -> ObjectState: ...
543
- @overload
544
- def get_value(self, state_name: Literal["doorbell"]) -> DoorbellState: ...
545
- @overload
546
- def get_value(self, state_name: Literal["siren"]) -> SirenState: ...
547
- @overload
548
- def get_value(self, state_name: Literal["battery"]) -> BatteryState: ...
549
- def get_value(
550
- self, state_name: str
551
- ) -> Union[
552
- LightState,
553
- MotionState,
554
- AudioState,
555
- ObjectState,
556
- DoorbellState,
557
- SirenState,
558
- BatteryState,
559
- ]:
560
- if state_name == "light":
561
- return deepcopy(self.light_state.value)
562
- elif state_name == "motion":
563
- return deepcopy(self.motion_state.value)
564
- elif state_name == "audio":
565
- return deepcopy(self.audio_state.value)
566
- elif state_name == "object":
567
- return deepcopy(self.object_state.value)
568
- elif state_name == "doorbell":
569
- return deepcopy(self.doorbell_state.value)
570
- elif state_name == "siren":
571
- return deepcopy(self.siren_state.value)
572
- elif state_name == "battery":
573
- return deepcopy(self.battery_state.value)
574
- else:
575
- raise Exception(f"Unknown state: {state_name}")
576
-
577
- @overload
578
- async def update_state(
579
- self,
580
- state_name: Literal["light"],
581
- event_data: LightSetEvent,
582
- ) -> None: ...
583
- @overload
584
- async def update_state(
585
- self,
586
- state_name: Literal["motion"],
587
- event_data: MotionSetEvent,
588
- frame: Optional[VideoFrame] = None,
589
- ) -> None: ...
590
- @overload
591
- async def update_state(
592
- self,
593
- state_name: Literal["audio"],
594
- event_data: AudioSetEvent,
595
- ) -> None: ...
596
- @overload
597
- async def update_state(
598
- self,
599
- state_name: Literal["object"],
600
- event_data: ObjectSetEvent,
601
- ) -> None: ...
602
- @overload
603
- async def update_state(
604
- self,
605
- state_name: Literal["doorbell"],
606
- event_data: DoorbellSetEvent,
607
- ) -> None: ...
608
- @overload
609
- async def update_state(
610
- self,
611
- state_name: Literal["siren"],
612
- event_data: SirenSetEvent,
613
- ) -> None: ...
614
- @overload
615
- async def update_state(
616
- self,
617
- state_name: Literal["battery"],
618
- event_data: BatterySetEvent,
619
- ) -> None: ...
620
- async def update_state(
621
- self,
622
- state_name: Literal["light", "motion", "audio", "object", "doorbell", "siren", "battery"],
623
- event_data: Union[
624
- LightSetEvent,
625
- MotionSetEvent,
626
- AudioSetEvent,
627
- ObjectSetEvent,
628
- DoorbellSetEvent,
629
- SirenSetEvent,
630
- BatterySetEvent,
631
- ],
632
- frame: Optional[VideoFrame] = None,
633
- ) -> None:
634
- changed, event = cast(
635
- tuple[
636
- bool,
637
- Union[
638
- LightSetEvent,
639
- MotionSetEvent,
640
- AudioSetEvent,
641
- ObjectSetEvent,
642
- DoorbellSetEvent,
643
- SirenSetEvent,
644
- BatterySetEvent,
645
- ],
646
- ],
647
- self.__check_state_internal(cast(Any, state_name), cast(Any, event_data)),
648
- )
649
-
650
- if not changed:
651
- return
652
-
653
- if state_name == "motion" and frame:
654
- motion_event = cast(MotionState, event)
655
- self.__frame_state.on_next(
656
- {**motion_event, "frameData": frame.frame_data, "metadata": frame.metadata}
657
- )
658
-
659
- self.__update_state_internal(cast(Any, state_name), cast(Any, event), True)
660
- await self.on_request("cameraFn", "updateState", [state_name, event], 0)
661
-
662
- async def add_camera_source(self, source: CameraConfigInputSettings) -> None:
663
- return await self.on_request("cameraFn", "addCameraSource", [source])
664
-
665
- async def update_camera_source(self, source_id: str, source: CameraConfigInputSettingsPartial) -> None:
666
- return await self.on_request("cameraFn", "updateCameraSource", [source_id, source])
667
-
668
- async def remove_camera_source(self, source_id: str) -> None:
669
- return await self.on_request("cameraFn", "removeCameraSource", [source_id])
670
-
671
- async def refresh_states(self) -> None:
672
- response = await self.on_request("cameraFn", "refreshStates")
673
-
674
- self.update_camera(response["camera"])
675
- self.update_camera_state(response["cameraState"])
676
-
677
- for key, value in response["states"].items():
678
- self.__update_state_internal(key, value, True)
679
-
680
- for source_id, states in response["prebufferStates"].items():
681
- self.update_prebuffer(source_id, "mp4", states["mp4"])
682
- self.update_prebuffer(source_id, "mpegts", states["mpegts"])
683
-
684
- def update_camera(self, camera: Camera) -> None:
685
- self.camera_subject.on_next(camera)
686
- self.update_camera_sources_state()
687
-
688
- def update_prebuffer(self, source_id: str, container: Container, state: PrebufferState) -> None:
689
- if (
690
- source_id in self.prebuffer_state_subjects
691
- and container in self.prebuffer_state_subjects[source_id]
692
- ):
693
- prebuffer_state: PrebufferState = {
694
- "state": state["state"],
695
- "url": state.get("url", None),
696
- "duration": state["duration"],
697
- }
698
-
699
- self.prebuffer_state_subjects[source_id][container].on_next(prebuffer_state)
700
-
701
- def update_camera_state(self, state: bool) -> None:
702
- self.camera_state.on_next(state)
703
-
704
- def update_camera_sources_state(self) -> None:
705
- sources = self.camera_subject.value.get("sources")
706
- source_ids_to_remove: list[str] = []
707
-
708
- for source_id in self.prebuffer_state_subjects:
709
- if not any(source["_id"] == source_id for source in sources):
710
- for container in self.prebuffer_state_subjects[source_id]:
711
- self.prebuffer_state_subjects[source_id][container].on_completed()
712
-
713
- source_ids_to_remove.append(source_id)
714
-
715
- for source_id in source_ids_to_remove:
716
- del self.prebuffer_state_subjects[source_id]
717
-
718
- def camera_source_prebuffer_state(self, source_id: str, container: Container) -> PrebufferState:
719
- prebuffer_state: PrebufferState = {"state": False, "duration": 0}
720
-
721
- if (
722
- source_id in self.prebuffer_state_subjects
723
- and container in self.prebuffer_state_subjects[source_id]
724
- ):
725
- prebuffer_state = self.prebuffer_state_subjects[source_id][container].value
726
-
727
- return prebuffer_state
728
-
729
- def remove_all_listeners(self) -> None:
730
- self.__frame_state.on_completed()
731
- self.light_state.on_completed()
732
- self.motion_state.on_completed()
733
- self.audio_state.on_completed()
734
- self.object_state.on_completed()
735
- self.doorbell_state.on_completed()
736
- self.siren_state.on_completed()
737
- self.battery_state.on_completed()
738
- self.camera_subject.on_completed()
739
- self.camera_state.on_completed()
740
-
741
- async def cleanup(self) -> None:
742
- self.initialized = False
743
- self.remove_all_listeners()
744
- self.api.remove_listener("shutdown", self.cleanup)
745
- self.active_requests.clear()
746
-
747
- if self.message_queue:
748
- self.message_queue.abort_queue()
749
-
750
- with suppress(Exception):
751
- if self.publisher:
752
- await self.publisher.close()
753
-
754
- if self.camera_publisher:
755
- await self.camera_publisher.close()
756
-
757
- if self.signaling_publisher:
758
- await self.signaling_publisher.close()
759
-
760
- if self.frame_publisher:
761
- await self.frame_publisher.close()
762
-
763
- if self.motion_frame_publisher:
764
- await self.motion_frame_publisher.close()
765
-
766
- @overload
767
- def on_state_change(self, state_name: Literal["light"]) -> Observable[tuple[LightState, LightState]]: ...
768
- @overload
769
- def on_state_change(
770
- self, state_name: Literal["motion"]
771
- ) -> Observable[tuple[MotionState, MotionState]]: ...
772
- @overload
773
- def on_state_change(self, state_name: Literal["audio"]) -> Observable[tuple[AudioState, AudioState]]: ...
774
- @overload
775
- def on_state_change(
776
- self, state_name: Literal["doorbell"]
777
- ) -> Observable[tuple[DoorbellState, DoorbellState]]: ...
778
- @overload
779
- def on_state_change(self, state_name: Literal["siren"]) -> Observable[tuple[SirenState, SirenState]]: ...
780
- @overload
781
- def on_state_change(
782
- self, state_name: Literal["battery"]
783
- ) -> Observable[tuple[BatteryState, BatteryState]]: ...
784
- @overload
785
- def on_state_change(
786
- self, state_name: Literal["object"]
787
- ) -> Observable[tuple[ObjectState, ObjectState]]: ...
788
- def on_state_change(self, state_name: StateNames) -> Observable[tuple[StateValue, StateValue]]:
789
- state: Union[BehaviorSubject[StateValue], None] = getattr(self, f"{state_name}_state", None)
790
-
791
- if not state:
792
- raise Exception(f"{state_name}_state not found")
793
-
794
- def filter_fn(states: tuple[StateValue, StateValue]) -> bool:
795
- old_state = states[0]
796
- new_state = states[1]
797
-
798
- if isinstance(old_state, bool) or isinstance(new_state, bool):
799
- return old_state != new_state
800
- else:
801
- return self.__state_changed(old_state, new_state, state_name)
802
-
803
- return state.pipe(
804
- ops.pairwise(),
805
- ops.filter(filter_fn),
806
- ops.share(),
807
- )
808
-
809
- def on_property_change(
810
- self, property: Union[CameraPublicProperties, list[CameraPublicProperties]]
811
- ) -> Observable[CameraPropertyObservableObject]:
812
- def map_fn(
813
- cameras: tuple[Camera, Camera],
814
- ) -> list[Any]:
815
- properties = property if isinstance(property, list) else [property]
816
- return [
817
- {
818
- "property": prop,
819
- "old_state": cameras[0].get(prop),
820
- "new_state": cameras[1].get(prop),
821
- }
822
- for prop in properties
823
- ]
824
-
825
- def filter_fn(
826
- cameras: tuple[CameraPropertyObservableObject, CameraPropertyObservableObject],
827
- ) -> bool:
828
- return (
829
- DeepDiff(
830
- cameras[0]["old_state"],
831
- cameras[1]["new_state"],
832
- ignore_order=True,
833
- )
834
- != {}
835
- )
836
-
837
- return self.camera_subject.pipe(
838
- ops.pairwise(),
839
- ops.flat_map(map_fn),
840
- ops.filter(filter_fn),
841
- ops.share(),
842
- )
843
-
844
- def __on_motion_frame(self, motion_frame: FrameState) -> None:
845
- if not self.frame_publisher:
846
- return
847
-
848
- self.tasks.add(self.__send_motion_frame(motion_frame))
849
-
850
- async def __send_motion_frame(self, frame: FrameState) -> None:
851
- if not self.frame_publisher:
852
- return
853
-
854
- await self.frame_publisher.publish(self.motion_frame_subject, frame)
855
-
856
- @overload
857
- def __check_state_internal(
858
- self, state_name: Literal["light"], event_data: LightSetEvent
859
- ) -> tuple[bool, LightState]: ...
860
- @overload
861
- def __check_state_internal(
862
- self, state_name: Literal["motion"], event_data: MotionSetEvent
863
- ) -> tuple[bool, MotionState]: ...
864
- @overload
865
- def __check_state_internal(
866
- self, state_name: Literal["audio"], event_data: AudioSetEvent
867
- ) -> tuple[bool, AudioState]: ...
868
- @overload
869
- def __check_state_internal(
870
- self, state_name: Literal["object"], event_data: ObjectSetEvent
871
- ) -> tuple[bool, ObjectState]: ...
872
- @overload
873
- def __check_state_internal(
874
- self, state_name: Literal["doorbell"], event_data: DoorbellSetEvent
875
- ) -> tuple[bool, DoorbellState]: ...
876
- @overload
877
- def __check_state_internal(
878
- self, state_name: Literal["siren"], event_data: SirenSetEvent
879
- ) -> tuple[bool, SirenState]: ...
880
- @overload
881
- def __check_state_internal(
882
- self, state_name: Literal["battery"], event_data: BatterySetEvent
883
- ) -> tuple[bool, BatteryState]: ...
884
- def __check_state_internal(
885
- self,
886
- state_name: Literal["light", "motion", "audio", "object", "doorbell", "siren", "battery"],
887
- event_data: Union[
888
- LightSetEvent,
889
- MotionSetEvent,
890
- AudioSetEvent,
891
- ObjectSetEvent,
892
- DoorbellSetEvent,
893
- SirenSetEvent,
894
- BatterySetEvent,
895
- ],
896
- ) -> tuple[
897
- bool,
898
- Union[
899
- LightState,
900
- MotionState,
901
- AudioState,
902
- ObjectState,
903
- DoorbellState,
904
- SirenState,
905
- BatteryState,
906
- ],
907
- ]:
908
- changed = False
909
- target_state = None
910
-
911
- if state_name == "audio":
912
- audio_event = cast(AudioSetEvent, event_data)
913
- target_state = self.__get_audio_state(audio_event)
914
- changed = self.__state_changed(self.get_value("audio"), target_state, "audio")
915
-
916
- elif state_name == "light":
917
- light_event = cast(LightSetEvent, event_data)
918
- target_state = self.__get_light_state(light_event)
919
- changed = self.__state_changed(self.get_value("light"), target_state, "light")
920
-
921
- elif state_name == "motion":
922
- motion_event = cast(MotionSetEvent, event_data)
923
-
924
- if motion_event.get("state", None) is not None:
925
- motion_event["detections"] = []
926
-
927
- # fix bounding box type to to tuple, do we need?
928
- for det in motion_event["detections"]:
929
- det["boundingBox"] = cast(tuple[int, int, int, int], tuple(det["boundingBox"]))
930
- det["confidence"] = float(det["confidence"])
931
-
932
- motion_event["detections"] = merge_detections(motion_event["detections"])
933
-
934
- motion_event["detections"] = are_motion_detections_valid(
935
- motion_event["detections"], self.activity_zones, self.activity_settings
936
- )
937
-
938
- target_state = self.__get_motion_state(motion_event)
939
- changed = self.__state_changed(self.get_value("motion"), target_state, "motion")
940
-
941
- elif state_name == "object":
942
- object_event = cast(ObjectSetEvent, event_data)
943
-
944
- # fix bounding box type to to tuple
945
- for det in object_event["detections"]:
946
- det["boundingBox"] = tuple(det["boundingBox"]) # type: ignore
947
- det["confidence"] = float(det["confidence"])
948
-
949
- object_event["detections"] = are_object_detections_valid(
950
- object_event["detections"], self.activity_zones, self.activity_settings
951
- )
952
-
953
- target_state = self.__get_object_state(object_event)
954
- changed = self.__state_changed(self.get_value("object"), target_state, "object")
955
-
956
- elif state_name == "doorbell":
957
- doorbell_event = cast(DoorbellSetEvent, event_data)
958
- target_state = self.__get_doorbell_state(doorbell_event)
959
- changed = self.__state_changed(self.get_value("doorbell"), target_state, "doorbell")
960
-
961
- elif state_name == "siren":
962
- siren_event = cast(SirenSetEvent, event_data)
963
- target_state = self.__get_siren_state(siren_event)
964
- changed = self.__state_changed(self.get_value("siren"), target_state, "siren")
965
-
966
- elif state_name == "battery":
967
- battery_event = cast(BatterySetEvent, event_data)
968
- target_state = self.__get_battery_state(battery_event)
969
- changed = self.__state_changed(self.get_value("battery"), target_state, "battery")
970
-
971
- else:
972
- raise Exception(f"Unknown state: {state_name}")
973
-
974
- return changed, target_state
975
-
976
- @overload
977
- def __update_state_internal(
978
- self, state_name: Literal["light"], event_data: LightSetEvent, skip_check: Optional[bool] = None
979
- ) -> None: ...
980
- @overload
981
- def __update_state_internal(
982
- self, state_name: Literal["motion"], event_data: MotionSetEvent, skip_check: Optional[bool] = None
983
- ) -> None: ...
984
- @overload
985
- def __update_state_internal(
986
- self, state_name: Literal["audio"], event_data: AudioSetEvent, skip_check: Optional[bool] = None
987
- ) -> None: ...
988
- @overload
989
- def __update_state_internal(
990
- self, state_name: Literal["object"], event_data: ObjectSetEvent, skip_check: Optional[bool] = None
991
- ) -> None: ...
992
- @overload
993
- def __update_state_internal(
994
- self, state_name: Literal["doorbell"], event_data: DoorbellSetEvent, skip_check: Optional[bool] = None
995
- ) -> None: ...
996
- @overload
997
- def __update_state_internal(
998
- self, state_name: Literal["siren"], event_data: SirenSetEvent, skip_check: Optional[bool] = None
999
- ) -> None: ...
1000
- @overload
1001
- def __update_state_internal(
1002
- self, state_name: Literal["battery"], event_data: BatterySetEvent, skip_check: Optional[bool] = None
1003
- ) -> None: ...
1004
- def __update_state_internal(
1005
- self,
1006
- state_name: Literal["light", "motion", "audio", "object", "doorbell", "siren", "battery"],
1007
- event_data: Union[
1008
- LightSetEvent,
1009
- MotionSetEvent,
1010
- AudioSetEvent,
1011
- ObjectSetEvent,
1012
- DoorbellSetEvent,
1013
- SirenSetEvent,
1014
- BatterySetEvent,
1015
- ],
1016
- skip_check: Optional[bool] = None,
1017
- ) -> None:
1018
- if skip_check:
1019
- changed = True
1020
- event = event_data
1021
- else:
1022
- changed, event = cast(
1023
- tuple[
1024
- bool,
1025
- Union[
1026
- LightSetEvent,
1027
- MotionSetEvent,
1028
- AudioSetEvent,
1029
- ObjectSetEvent,
1030
- DoorbellSetEvent,
1031
- SirenSetEvent,
1032
- BatterySetEvent,
1033
- ],
1034
- ],
1035
- self.__check_state_internal(cast(Any, state_name), cast(Any, event_data)),
1036
- )
1037
-
1038
- if not changed:
1039
- return
1040
-
1041
- if state_name == "light":
1042
- self.light_state.on_next(self.__get_light_state(cast(LightSetEvent, event)))
1043
- elif state_name == "motion":
1044
- self.motion_state.on_next(self.__get_motion_state(cast(MotionSetEvent, event)))
1045
- elif state_name == "audio":
1046
- self.audio_state.on_next(self.__get_audio_state(cast(AudioSetEvent, event)))
1047
- elif state_name == "object":
1048
- self.object_state.on_next(self.__get_object_state(cast(ObjectSetEvent, event)))
1049
- elif state_name == "doorbell":
1050
- self.doorbell_state.on_next(self.__get_doorbell_state(cast(DoorbellSetEvent, event)))
1051
- elif state_name == "siren":
1052
- self.siren_state.on_next(self.__get_siren_state(cast(SirenSetEvent, event)))
1053
- elif state_name == "battery" and self.has_battery:
1054
- self.battery_state.on_next(self.__get_battery_state(cast(BatterySetEvent, event)))
1055
-
1056
- def __create_motion_frame_observable(self) -> Observable[FrameState]:
1057
- return self.__frame_state.pipe(ops.share())
1058
-
1059
- def __create_state_observable(self, state_subject: BehaviorSubject[Any]) -> Observable[Any]:
1060
- return state_subject.pipe(ops.share())
1061
-
1062
- def __state_changed(
1063
- self,
1064
- old_state: Optional[SetValue],
1065
- new_state: Optional[SetValue],
1066
- type: Optional[StateNames],
1067
- ) -> bool:
1068
- if not old_state or not new_state or not type:
1069
- return False
1070
-
1071
- if type == "audio":
1072
- if not self.has_audio_detector:
1073
- return False
1074
-
1075
- old_state = cast(AudioSetEvent, old_state)
1076
- new_state = cast(AudioSetEvent, new_state)
1077
-
1078
- return old_state["state"] != new_state["state"] or old_state.get("db") != new_state.get("db")
1079
- elif type == "motion":
1080
- if not self.has_motion_detector:
1081
- return False
1082
-
1083
- old_state = cast(MotionSetEvent, old_state)
1084
- new_state = cast(MotionSetEvent, new_state)
1085
-
1086
- if new_state.get("state", None) is not None:
1087
- return old_state.get("state", False) != new_state.get("state", False)
1088
-
1089
- # if len(new_state["detections"]) == 0:
1090
- # return False
1091
-
1092
- return (
1093
- DeepDiff(
1094
- old_state["detections"],
1095
- new_state["detections"],
1096
- ignore_order=True,
1097
- )
1098
- != {}
1099
- )
1100
- elif type == "object":
1101
- if not self.has_object_detector:
1102
- return False
1103
-
1104
- old_state = cast(ObjectSetEvent, old_state)
1105
- new_state = cast(ObjectSetEvent, new_state)
1106
-
1107
- # if len(new_state["detections"]) == 0:
1108
- # return False
1109
-
1110
- return (
1111
- DeepDiff(
1112
- old_state["detections"],
1113
- new_state["detections"],
1114
- ignore_order=True,
1115
- )
1116
- != {}
1117
- )
1118
- elif type == "siren":
1119
- if not self.has_siren:
1120
- return False
1121
-
1122
- old_state = cast(SirenSetEvent, old_state)
1123
- new_state = cast(SirenSetEvent, new_state)
1124
-
1125
- return old_state["state"] != new_state["state"] or old_state.get("level") != new_state.get(
1126
- "level"
1127
- )
1128
- elif type == "battery":
1129
- if not self.has_battery:
1130
- return False
1131
-
1132
- old_state = cast(BatterySetEvent, old_state)
1133
- new_state = cast(BatterySetEvent, new_state)
1134
-
1135
- return (
1136
- old_state["level"] != new_state["level"]
1137
- or old_state.get("lowBattery") != new_state.get("lowBattery")
1138
- or old_state.get("charging") != new_state.get("charging")
1139
- )
1140
- elif type == "doorbell":
1141
- if not self.has_binary_sensor:
1142
- return False
1143
-
1144
- old_state = cast(DoorbellSetEvent, old_state)
1145
- new_state = cast(DoorbellSetEvent, new_state)
1146
-
1147
- return old_state["state"] != new_state["state"]
1148
- elif type == "light":
1149
- if not self.has_light:
1150
- return False
1151
-
1152
- old_state = cast(LightSetEvent, old_state)
1153
- new_state = cast(LightSetEvent, new_state)
1154
-
1155
- return old_state["state"] != new_state["state"]
1156
- else:
1157
- return False
1158
-
1159
- def create_prebuffer_state_observable(
1160
- self, source_id: str, container: Container
1161
- ) -> Observable[PrebufferState]:
1162
- if source_id not in self.prebuffer_state_subjects:
1163
- self.prebuffer_state_subjects[source_id] = {}
1164
-
1165
- if container not in self.prebuffer_state_subjects[source_id]:
1166
- self.prebuffer_state_subjects[source_id][container] = BehaviorSubject(
1167
- {"state": False, "duration": 0}
1168
- )
1169
-
1170
- return self.prebuffer_state_subjects[source_id][container].pipe(
1171
- ops.distinct_until_changed(comparer=self.__prebuffer_state_comperator),
1172
- ops.share(),
1173
- )
1174
-
1175
- def __prebuffer_state_comperator(
1176
- self, previous_state: PrebufferState, current_state: PrebufferState
1177
- ) -> bool:
1178
- return previous_state["state"] == current_state["state"] and previous_state.get(
1179
- "url"
1180
- ) == current_state.get("url")
1181
-
1182
- def __get_audio_state(self, event: AudioSetEvent, ignore_last_event: bool = False) -> AudioState:
1183
- last_event: Optional[AudioState] = None
1184
-
1185
- if ignore_last_event is False:
1186
- last_state = self.get_value("audio")
1187
-
1188
- if last_state["state"]:
1189
- last_event = last_state
1190
- elif "lastEvent" in last_state and last_state["lastEvent"] and last_state["lastEvent"]["state"]:
1191
- last_event = last_state["lastEvent"] # type: ignore
1192
-
1193
- if last_event and "lastEvent" in last_event:
1194
- del last_event["lastEvent"]
1195
-
1196
- new_state: AudioState
1197
-
1198
- if "timestamp" in event:
1199
- new_state = event
1200
- else:
1201
- state = cast(AudioState, event).copy()
1202
- state["timestamp"] = int(datetime.now().timestamp() * 1000)
1203
-
1204
- new_state = {
1205
- "state": event["state"],
1206
- "db": event.get("db", None) or last_event.get("db", None) if last_event else 0,
1207
- "timestamp": int(datetime.now().timestamp() * 1000),
1208
- "lastEvent": last_event if last_event else state if state["state"] else None,
1209
- }
1210
-
1211
- return new_state
1212
-
1213
- def __get_motion_state(self, event: MotionSetEvent, ignore_last_event: bool = False) -> MotionState:
1214
- last_event: Optional[MotionState] = None
1215
-
1216
- if ignore_last_event is False:
1217
- last_state = self.get_value("motion")
1218
-
1219
- if len(last_state["detections"]) > 0:
1220
- last_event = last_state
1221
- elif (
1222
- "lastEvent" in last_state
1223
- and last_state["lastEvent"] is not None
1224
- and len(last_state["lastEvent"]["detections"]) > 0
1225
- ):
1226
- last_event = last_state["lastEvent"] # type: ignore
1227
-
1228
- if last_event and "lastEvent" in last_event:
1229
- del last_event["lastEvent"]
1230
-
1231
- new_state: MotionState
1232
-
1233
- if "timestamp" in event:
1234
- new_state = event
1235
- else:
1236
- state = cast(MotionState, event).copy()
1237
- state["timestamp"] = int(datetime.now().timestamp() * 1000)
1238
-
1239
- new_state = {
1240
- "detections": event["detections"],
1241
- "timestamp": int(datetime.now().timestamp() * 1000),
1242
- "lastEvent": last_event if last_event else state if len(state["detections"]) > 0 else None,
1243
- }
1244
-
1245
- return new_state
1246
-
1247
- def __get_object_state(self, event: ObjectSetEvent, ignore_last_event: bool = False) -> ObjectState:
1248
- last_event: Optional[ObjectState] = None
1249
-
1250
- if ignore_last_event is False:
1251
- last_state = self.get_value("object")
1252
-
1253
- if len(last_state["detections"]) > 0:
1254
- last_event = last_state
1255
- elif (
1256
- "lastEvent" in last_state
1257
- and last_state["lastEvent"]
1258
- and len(last_state["lastEvent"]["detections"]) > 0
1259
- ):
1260
- last_event = last_state["lastEvent"] # type: ignore
1261
-
1262
- if last_event and "lastEvent" in last_event:
1263
- del last_event["lastEvent"]
1264
-
1265
- new_state: ObjectState
1266
-
1267
- if "timestamp" in event:
1268
- new_state = event
1269
- else:
1270
- state = cast(ObjectState, event).copy()
1271
- state["timestamp"] = int(datetime.now().timestamp() * 1000)
1272
-
1273
- new_state = {
1274
- "detections": event["detections"],
1275
- "timestamp": int(datetime.now().timestamp() * 1000),
1276
- "lastEvent": last_event if last_event else state if len(state["detections"]) > 0 else None,
1277
- }
1278
-
1279
- return new_state
1280
-
1281
- def __get_doorbell_state(self, event: DoorbellSetEvent, ignore_last_event: bool = False) -> DoorbellState:
1282
- last_event: Optional[DoorbellState] = None
1283
-
1284
- if ignore_last_event is False:
1285
- last_state = self.get_value("doorbell")
1286
-
1287
- if last_state["state"]:
1288
- last_event = last_state
1289
- elif "lastEvent" in last_state and last_state["lastEvent"] and last_state["lastEvent"]["state"]:
1290
- last_event = last_state["lastEvent"] # type: ignore
1291
-
1292
- if last_event and "lastEvent" in last_event:
1293
- del last_event["lastEvent"]
1294
-
1295
- new_state: DoorbellState
1296
-
1297
- if "timestamp" in event:
1298
- new_state = event
1299
- else:
1300
- state = cast(DoorbellState, event).copy()
1301
- state["timestamp"] = int(datetime.now().timestamp() * 1000)
1302
-
1303
- new_state = {
1304
- "state": event["state"],
1305
- "timestamp": int(datetime.now().timestamp() * 1000),
1306
- "lastEvent": last_event if last_event else state if state["state"] else None,
1307
- }
1308
-
1309
- return new_state
1310
-
1311
- def __get_light_state(self, event: LightSetEvent, ignore_last_event: bool = False) -> LightState:
1312
- last_event: Optional[LightState] = None
1313
-
1314
- if ignore_last_event is False:
1315
- last_state = self.get_value("light")
1316
-
1317
- if last_state["state"]:
1318
- last_event = last_state
1319
- elif "lastEvent" in last_state and last_state["lastEvent"] and last_state["lastEvent"]["state"]:
1320
- last_event = last_state["lastEvent"] # type: ignore
1321
-
1322
- if last_event and "lastEvent" in last_event:
1323
- del last_event["lastEvent"]
1324
-
1325
- new_state: LightState
1326
-
1327
- if "timestamp" in event:
1328
- new_state = event
1329
- else:
1330
- state = cast(LightState, event).copy()
1331
- state["timestamp"] = int(datetime.now().timestamp() * 1000)
1332
-
1333
- new_state = {
1334
- **state,
1335
- "lastEvent": last_event if last_event else state if state["state"] else None,
1336
- }
1337
-
1338
- return new_state
1339
-
1340
- def __get_siren_state(self, event: SirenSetEvent, ignore_last_event: bool = False) -> SirenState:
1341
- last_event: Optional[SirenState] = None
1342
-
1343
- if ignore_last_event is False:
1344
- last_state = self.get_value("siren")
1345
-
1346
- if last_state["state"]:
1347
- last_event = last_state
1348
- elif "lastEvent" in last_state and last_state["lastEvent"] and last_state["lastEvent"]["state"]:
1349
- last_event = last_state["lastEvent"] # type: ignore
1350
-
1351
- if last_event and "lastEvent" in last_event:
1352
- del last_event["lastEvent"]
1353
-
1354
- new_state: SirenState
1355
-
1356
- if "timestamp" in event:
1357
- new_state = event
1358
- else:
1359
- state = cast(SirenState, event).copy()
1360
- state["timestamp"] = int(datetime.now().timestamp() * 1000)
1361
-
1362
- new_state = {
1363
- "state": event["state"],
1364
- "level": event.get("level", None) or last_event.get("level", None) if last_event else 0,
1365
- "timestamp": int(datetime.now().timestamp() * 1000),
1366
- "lastEvent": last_event if last_event else state if state["state"] else None,
1367
- }
1368
-
1369
- return new_state
1370
-
1371
- def __get_battery_state(self, event: BatterySetEvent, ignore_last_event: bool = False) -> BatteryState:
1372
- last_event: Optional[BatteryState] = None
1373
-
1374
- if ignore_last_event is False:
1375
- last_state = self.get_value("battery")
1376
-
1377
- if self.__state_changed(last_state, event, "battery"):
1378
- last_event = last_state
1379
- elif (
1380
- "lastEvent" in last_state
1381
- and last_state["lastEvent"]
1382
- and self.__state_changed(last_state["lastEvent"], event, "battery")
1383
- ):
1384
- last_event = last_state["lastEvent"] # type: ignore
1385
-
1386
- if last_event and "lastEvent" in last_event:
1387
- del last_event["lastEvent"]
1388
-
1389
- new_state: BatteryState
1390
-
1391
- if "timestamp" in event:
1392
- new_state = event
1393
- else:
1394
- state = cast(BatteryState, event).copy()
1395
- state["timestamp"] = int(datetime.now().timestamp() * 1000)
1396
-
1397
- new_state = {
1398
- "level": event["level"],
1399
- "charging": event.get("charging", None) or last_event.get("charging", None)
1400
- if last_event
1401
- else False,
1402
- "lowBattery": event.get("lowBattery", None) or last_event.get("lowBattery", None)
1403
- if last_event
1404
- else False,
1405
- "timestamp": int(datetime.now().timestamp() * 1000),
1406
- "lastEvent": last_event if last_event else state,
1407
- }
1408
-
1409
- return new_state
1410
-
1411
- async def __connect_to_decoder(self, request_id: str) -> FrameMetadata:
1412
- if not self.signaling_publisher:
1413
- raise Exception("Signaling Publisher not initialized")
1414
-
1415
- message: SignalingRequest = {
1416
- "type": "connect",
1417
- "requestId": request_id,
1418
- "cameraId": self.id,
1419
- "pluginId": self.plugin["id"],
1420
- }
1421
-
1422
- await self.signaling_publisher.publish(self.signaling_target_subject, message)
1423
-
1424
- self.active_requests.add(request_id)
1425
-
1426
- metadata = await self.__get_metadata(request_id, 60)
1427
-
1428
- if not metadata:
1429
- raise Exception("Invalid metadata response")
1430
-
1431
- return metadata
1432
-
1433
- async def __get_metadata(self, request_id: str, timeout: int) -> Union[FrameMetadata, None]:
1434
- if not self.signaling_publisher:
1435
- raise Exception("Signaling Publisher not initialized")
1436
-
1437
- try:
1438
- metadata_request: SignalingRequest = {
1439
- "type": "metadata",
1440
- "requestId": request_id,
1441
- "cameraId": self.id,
1442
- "pluginId": self.plugin["id"],
1443
- }
1444
-
1445
- metadata_response: SignalingResponse = await self.signaling_publisher.request(
1446
- self.signaling_target_subject,
1447
- metadata_request,
1448
- timeout=timeout,
1449
- )
1450
-
1451
- metadata = metadata_response.get("metadata")
1452
-
1453
- return metadata
1454
- except Exception as e:
1455
- self.logger.error("Failed to get metadata! Frame Worker FFmpeg process might not be running", e)
1456
-
1457
- async def __disconnect_from_decoder(self, request_id: str) -> None:
1458
- if request_id in self.active_requests:
1459
- self.active_requests.remove(request_id)
1460
-
1461
- frame_subscription = next(
1462
- (sub for sub in self.frame_subscribers if sub["request_id"] == request_id), None
1463
- )
1464
-
1465
- if frame_subscription:
1466
- self.frame_subscribers.remove(frame_subscription)
1467
- await frame_subscription["subscriber"].close()
1468
-
1469
- if self.signaling_publisher:
1470
- message: SignalingRequest = {
1471
- "type": "disconnect",
1472
- "requestId": request_id,
1473
- "cameraId": self.id,
1474
- "pluginId": self.plugin["id"],
1475
- }
1476
-
1477
- await self.signaling_publisher.publish(self.signaling_target_subject, message)
1478
-
1479
- async def __close_frame_subscribers(self) -> None:
1480
- self.active_requests.clear()
1481
-
1482
- for sub in self.frame_subscribers:
1483
- with suppress(Exception):
1484
- await sub["subscriber"].close()
1485
-
1486
- self.frame_subscribers.clear()
1487
-
1488
- async def __close_motion_frame_subscribers(self) -> None:
1489
- self.active_motion_requests.clear()
1490
-
1491
- for sub in self.motion_frame_subscribers:
1492
- with suppress(Exception):
1493
- await sub["subscriber"].close()
1494
-
1495
- self.motion_frame_subscribers.clear()
1496
-
1497
- async def __request_handler(self, message: ProxyMessageStructure) -> None:
1498
- if not self.message_queue:
1499
- raise Exception("Message queue not initialized")
1500
-
1501
- reply = message.copy()
1502
- reply["type"] = "reply"
1503
-
1504
- try:
1505
- if (
1506
- message["client"] == "cameraDelegate"
1507
- or message["client"] == "prebufferDelegate"
1508
- or message["client"] == "ptzDelegate"
1509
- ):
1510
- delegate = getattr(self, message["client"], None)
1511
-
1512
- if not delegate:
1513
- raise Exception(f"Delegate not set: {message['client']}")
1514
-
1515
- fn: Any = message.get("fn")
1516
- args = message.get("args", [])
1517
-
1518
- if not hasattr(delegate, fn) and not callable(getattr(delegate, fn)):
1519
- raise Exception(f"Unknown delegate function: {message['client']} ({fn})")
1520
-
1521
- method_to_call = getattr(delegate, fn)
1522
-
1523
- if inspect.iscoroutinefunction(method_to_call):
1524
- reply["response"] = await method_to_call(*args)
1525
- else:
1526
- reply["response"] = method_to_call(*args)
1527
- elif message.get("client") == "cameraFn":
1528
- fn: Any = message.get("fn")
1529
- args = message.get("args", [])
1530
-
1531
- if not hasattr(self, fn) and not callable(getattr(self, fn)):
1532
- raise Exception(f"Unknown camera function: {fn}")
1533
-
1534
- method_to_call = getattr(self, fn)
1535
-
1536
- if inspect.iscoroutinefunction(method_to_call):
1537
- reply["response"] = await method_to_call(*args)
1538
- else:
1539
- reply["response"] = method_to_call(*args)
1540
- else:
1541
- raise Exception(f"Unknown client: {message['client']}")
1542
-
1543
- except Exception as e:
1544
- deserialized_error: DeserializedError = {
1545
- "name": type(e).__name__,
1546
- "message": str(e),
1547
- "stack": traceback.format_exc(),
1548
- }
1549
-
1550
- reply["error"] = deserialized_error
1551
-
1552
- if reply["timeout"] == 0:
1553
- return
1554
- else:
1555
- await self.message_queue.enqueue(reply)
1556
-
1557
- async def __on_proxy_message(self, msg: Msg) -> None:
1558
- if not self.initialized:
1559
- return
1560
-
1561
- message = unpack(msg.data)
1562
-
1563
- if "type" in message:
1564
- type = message["type"]
1565
- if type == "removed":
1566
- await self.cleanup()
1567
- elif type == "updated":
1568
- self.update_camera(message["data"])
1569
- elif type == "cameraState":
1570
- self.update_camera_state(message["data"])
1571
- elif type == "prebufferState":
1572
- self.update_prebuffer(
1573
- message["data"]["sourceId"],
1574
- message["data"]["container"],
1575
- message["data"]["state"],
1576
- )
1577
- else:
1578
- state_name = message["stateName"]
1579
- new_data = message["data"]["newEvent"]
1580
-
1581
- self.__update_state_internal(state_name, new_data, True)
1582
-
1583
- async def __on_signaling_message(self, msg: Msg) -> None:
1584
- if not self.initialized:
1585
- return
1586
-
1587
- message: Union[SignalingResponse, PingMessage] = unpack(msg.data)
1588
-
1589
- if message["type"] == "ping":
1590
- if message["requestId"] in self.active_requests:
1591
- self.tasks.add(self.__respond_to_signaling_message(msg, message))
1592
-
1593
- elif message["type"] == "disconnect":
1594
- if message["requestId"] in self.active_requests:
1595
- self.active_requests.remove(message["requestId"])
1596
-
1597
- frame_subscribtion = next(
1598
- (sub for sub in self.frame_subscribers if sub["request_id"] == message["requestId"]), None
1599
- )
1600
-
1601
- if frame_subscribtion:
1602
- self.frame_subscribers.remove(frame_subscribtion)
1603
- await frame_subscribtion["subscriber"].close()
1604
-
1605
- if len(self.active_requests) == 0:
1606
- self.tasks.add(self.__close_frame_subscribers())
1607
-
1608
- async def __respond_to_signaling_message(self, msg: Msg, message: PingMessage) -> None:
1609
- try:
1610
- pong_message: PongMessage = {
1611
- "type": "pong",
1612
- "requestId": message["requestId"],
1613
- }
1614
-
1615
- await msg.respond(pack(pong_message))
1616
- except Exception as e:
1617
- if self.initialized:
1618
- self.logger.error("Error while processing singaling respond:", e)
1619
-
1620
- @overload
1621
- async def on_request(
1622
- self,
1623
- client: Literal["cameraFn"],
1624
- fn: CameraDeviceProxyMethodNames,
1625
- args: list[Any] = [],
1626
- timeout: int = 5000,
1627
- ) -> Any: ...
1628
- @overload
1629
- async def on_request(
1630
- self,
1631
- client: Literal["cameraDelegate"],
1632
- fn: CameraDelegateMethodNames,
1633
- args: list[Any] = [],
1634
- timeout: int = 5000,
1635
- ) -> Any: ...
1636
- @overload
1637
- async def on_request(
1638
- self,
1639
- client: Literal["prebufferDelegate"],
1640
- fn: CameraPrebufferDelegateMethodNames,
1641
- args: list[Any] = [],
1642
- timeout: int = 5000,
1643
- ) -> Any: ...
1644
- @overload
1645
- async def on_request(
1646
- self,
1647
- client: Literal["ptzDelegate"],
1648
- fn: CameraPTZDelegateMethodNames,
1649
- args: list[Any] = [],
1650
- timeout: int = 5000,
1651
- ) -> Any: ...
1652
- async def on_request(
1653
- self,
1654
- client: ClientType,
1655
- fn: Any,
1656
- args: list[Any] = [],
1657
- timeout: int = 5000,
1658
- ) -> Any:
1659
- if not self.message_queue:
1660
- raise Exception("Message queue not initialized")
1661
-
1662
- message: ProxyMessageStructure = {
1663
- "requestId": str(uuid4()),
1664
- "targetId": self.subject,
1665
- "targetName": self.name,
1666
- "pluginId": self.plugin["id"],
1667
- "cameraId": self.id,
1668
- "type": "request",
1669
- "proxy": "camera",
1670
- "client": "cameraFn",
1671
- "fn": fn,
1672
- "args": args,
1673
- "timestamp": int(datetime.now().timestamp() * 1000),
1674
- "timeout": timeout,
1675
- }
1676
-
1677
- return await self.message_queue.enqueue(message)