amaran-light-cli 1.11.0 → 1.12.0

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 (363) hide show
  1. package/README.md +108 -14
  2. package/dist/__tests__/autoCct.test.js +27 -0
  3. package/dist/__tests__/autoCct.test.js.map +1 -1
  4. package/dist/__tests__/bleHttpControl.test.d.ts +2 -0
  5. package/dist/__tests__/bleHttpControl.test.d.ts.map +1 -0
  6. package/dist/__tests__/bleHttpControl.test.js +230 -0
  7. package/dist/__tests__/bleHttpControl.test.js.map +1 -0
  8. package/dist/__tests__/bleStack.test.d.ts +2 -0
  9. package/dist/__tests__/bleStack.test.d.ts.map +1 -0
  10. package/dist/__tests__/bleStack.test.js +1239 -0
  11. package/dist/__tests__/bleStack.test.js.map +1 -0
  12. package/dist/__tests__/cctUtil.test.js +9 -4
  13. package/dist/__tests__/cctUtil.test.js.map +1 -1
  14. package/dist/__tests__/circadianDashboardSettings.test.d.ts +2 -0
  15. package/dist/__tests__/circadianDashboardSettings.test.d.ts.map +1 -0
  16. package/dist/__tests__/circadianDashboardSettings.test.js +82 -0
  17. package/dist/__tests__/circadianDashboardSettings.test.js.map +1 -0
  18. package/dist/__tests__/circadianIsolation.test.d.ts +2 -0
  19. package/dist/__tests__/circadianIsolation.test.d.ts.map +1 -0
  20. package/dist/__tests__/circadianIsolation.test.js +30 -0
  21. package/dist/__tests__/circadianIsolation.test.js.map +1 -0
  22. package/dist/__tests__/cli.config.test.js +49 -0
  23. package/dist/__tests__/cli.config.test.js.map +1 -1
  24. package/dist/__tests__/cli.smoke.test.js +34 -0
  25. package/dist/__tests__/cli.smoke.test.js.map +1 -1
  26. package/dist/__tests__/currentCct.test.d.ts +2 -0
  27. package/dist/__tests__/currentCct.test.d.ts.map +1 -0
  28. package/dist/__tests__/currentCct.test.js +29 -0
  29. package/dist/__tests__/currentCct.test.js.map +1 -0
  30. package/dist/__tests__/dashboard.test.d.ts +2 -0
  31. package/dist/__tests__/dashboard.test.d.ts.map +1 -0
  32. package/dist/__tests__/dashboard.test.js +126 -0
  33. package/dist/__tests__/dashboard.test.js.map +1 -0
  34. package/dist/__tests__/daylightSimulationParseUtils.test.d.ts +2 -0
  35. package/dist/__tests__/daylightSimulationParseUtils.test.d.ts.map +1 -0
  36. package/dist/__tests__/daylightSimulationParseUtils.test.js +16 -0
  37. package/dist/__tests__/daylightSimulationParseUtils.test.js.map +1 -0
  38. package/dist/__tests__/desktopImport.test.d.ts +2 -0
  39. package/dist/__tests__/desktopImport.test.d.ts.map +1 -0
  40. package/dist/__tests__/desktopImport.test.js +234 -0
  41. package/dist/__tests__/desktopImport.test.js.map +1 -0
  42. package/dist/__tests__/lightControl.basic.test.d.ts +2 -0
  43. package/dist/__tests__/lightControl.basic.test.d.ts.map +1 -0
  44. package/dist/__tests__/lightControl.basic.test.js +119 -0
  45. package/dist/__tests__/lightControl.basic.test.js.map +1 -0
  46. package/dist/__tests__/lightControl.colorEffects.test.d.ts +2 -0
  47. package/dist/__tests__/lightControl.colorEffects.test.d.ts.map +1 -0
  48. package/dist/__tests__/lightControl.colorEffects.test.js +170 -0
  49. package/dist/__tests__/lightControl.colorEffects.test.js.map +1 -0
  50. package/dist/__tests__/lightControl.management.test.d.ts +2 -0
  51. package/dist/__tests__/lightControl.management.test.d.ts.map +1 -0
  52. package/dist/__tests__/lightControl.management.test.js +90 -0
  53. package/dist/__tests__/lightControl.management.test.js.map +1 -0
  54. package/dist/__tests__/lightControlTestUtils.d.ts +10 -0
  55. package/dist/__tests__/lightControlTestUtils.d.ts.map +1 -0
  56. package/dist/__tests__/lightControlTestUtils.js +57 -0
  57. package/dist/__tests__/lightControlTestUtils.js.map +1 -0
  58. package/dist/__tests__/meshConfiguration.test.d.ts +2 -0
  59. package/dist/__tests__/meshConfiguration.test.d.ts.map +1 -0
  60. package/dist/__tests__/meshConfiguration.test.js +78 -0
  61. package/dist/__tests__/meshConfiguration.test.js.map +1 -0
  62. package/dist/__tests__/nativeGroups.test.d.ts +2 -0
  63. package/dist/__tests__/nativeGroups.test.d.ts.map +1 -0
  64. package/dist/__tests__/nativeGroups.test.js +104 -0
  65. package/dist/__tests__/nativeGroups.test.js.map +1 -0
  66. package/dist/__tests__/programApi.test.d.ts +2 -0
  67. package/dist/__tests__/programApi.test.d.ts.map +1 -0
  68. package/dist/__tests__/programApi.test.js +73 -0
  69. package/dist/__tests__/programApi.test.js.map +1 -0
  70. package/dist/__tests__/programs.test.d.ts +2 -0
  71. package/dist/__tests__/programs.test.d.ts.map +1 -0
  72. package/dist/__tests__/programs.test.js +176 -0
  73. package/dist/__tests__/programs.test.js.map +1 -0
  74. package/dist/__tests__/scheduleMaker.test.d.ts +2 -0
  75. package/dist/__tests__/scheduleMaker.test.d.ts.map +1 -0
  76. package/dist/__tests__/scheduleMaker.test.js +25 -0
  77. package/dist/__tests__/scheduleMaker.test.js.map +1 -0
  78. package/dist/ble/async.d.ts +2 -0
  79. package/dist/ble/async.d.ts.map +1 -0
  80. package/dist/ble/async.js +15 -0
  81. package/dist/ble/async.js.map +1 -0
  82. package/dist/ble/colors.d.ts +5 -0
  83. package/dist/ble/colors.d.ts.map +1 -0
  84. package/dist/ble/colors.js +44 -0
  85. package/dist/ble/colors.js.map +1 -0
  86. package/dist/ble/configuration.d.ts +22 -0
  87. package/dist/ble/configuration.d.ts.map +1 -0
  88. package/dist/ble/configuration.js +122 -0
  89. package/dist/ble/configuration.js.map +1 -0
  90. package/dist/ble/controller.d.ts +118 -0
  91. package/dist/ble/controller.d.ts.map +1 -0
  92. package/dist/ble/controller.js +931 -0
  93. package/dist/ble/controller.js.map +1 -0
  94. package/dist/ble/crypto.d.ts +34 -0
  95. package/dist/ble/crypto.d.ts.map +1 -0
  96. package/dist/ble/crypto.js +178 -0
  97. package/dist/ble/crypto.js.map +1 -0
  98. package/dist/ble/daemon.d.ts +2 -0
  99. package/dist/ble/daemon.d.ts.map +1 -0
  100. package/dist/ble/daemon.js +76 -0
  101. package/dist/ble/daemon.js.map +1 -0
  102. package/dist/ble/dashboard.d.ts +331 -0
  103. package/dist/ble/dashboard.d.ts.map +1 -0
  104. package/dist/ble/dashboard.js +280 -0
  105. package/dist/ble/dashboard.js.map +1 -0
  106. package/dist/ble/desktop.d.ts +4 -0
  107. package/dist/ble/desktop.d.ts.map +1 -0
  108. package/dist/ble/desktop.js +33 -0
  109. package/dist/ble/desktop.js.map +1 -0
  110. package/dist/ble/desktopLibrary.d.ts +12 -0
  111. package/dist/ble/desktopLibrary.d.ts.map +1 -0
  112. package/dist/ble/desktopLibrary.js +346 -0
  113. package/dist/ble/desktopLibrary.js.map +1 -0
  114. package/dist/ble/effects.d.ts +34 -0
  115. package/dist/ble/effects.d.ts.map +1 -0
  116. package/dist/ble/effects.js +138 -0
  117. package/dist/ble/effects.js.map +1 -0
  118. package/dist/ble/fan.d.ts +244 -0
  119. package/dist/ble/fan.d.ts.map +1 -0
  120. package/dist/ble/fan.js +46 -0
  121. package/dist/ble/fan.js.map +1 -0
  122. package/dist/ble/library.d.ts +341 -0
  123. package/dist/ble/library.d.ts.map +1 -0
  124. package/dist/ble/library.js +201 -0
  125. package/dist/ble/library.js.map +1 -0
  126. package/dist/ble/media.d.ts +133 -0
  127. package/dist/ble/media.d.ts.map +1 -0
  128. package/dist/ble/media.js +186 -0
  129. package/dist/ble/media.js.map +1 -0
  130. package/dist/ble/nativeGroups.d.ts +22 -0
  131. package/dist/ble/nativeGroups.d.ts.map +1 -0
  132. package/dist/ble/nativeGroups.js +114 -0
  133. package/dist/ble/nativeGroups.js.map +1 -0
  134. package/dist/ble/packets.d.ts +3 -0
  135. package/dist/ble/packets.d.ts.map +1 -0
  136. package/dist/ble/packets.js +15 -0
  137. package/dist/ble/packets.js.map +1 -0
  138. package/dist/ble/programs.d.ts +318 -0
  139. package/dist/ble/programs.d.ts.map +1 -0
  140. package/dist/ble/programs.js +329 -0
  141. package/dist/ble/programs.js.map +1 -0
  142. package/dist/ble/provisioning.d.ts +13 -0
  143. package/dist/ble/provisioning.d.ts.map +1 -0
  144. package/dist/ble/provisioning.js +39 -0
  145. package/dist/ble/provisioning.js.map +1 -0
  146. package/dist/ble/server.d.ts +18 -0
  147. package/dist/ble/server.d.ts.map +1 -0
  148. package/dist/ble/server.js +548 -0
  149. package/dist/ble/server.js.map +1 -0
  150. package/dist/ble/service.d.ts +2 -0
  151. package/dist/ble/service.d.ts.map +1 -0
  152. package/dist/ble/service.js +77 -0
  153. package/dist/ble/service.js.map +1 -0
  154. package/dist/ble/settings.d.ts +18 -0
  155. package/dist/ble/settings.d.ts.map +1 -0
  156. package/dist/ble/settings.js +25 -0
  157. package/dist/ble/settings.js.map +1 -0
  158. package/dist/ble/setup.d.ts +2 -0
  159. package/dist/ble/setup.d.ts.map +1 -0
  160. package/dist/ble/setup.js +31 -0
  161. package/dist/ble/setup.js.map +1 -0
  162. package/dist/ble/storage.d.ts +94 -0
  163. package/dist/ble/storage.d.ts.map +1 -0
  164. package/dist/ble/storage.js +132 -0
  165. package/dist/ble/storage.js.map +1 -0
  166. package/dist/ble/telink.d.ts +63 -0
  167. package/dist/ble/telink.d.ts.map +1 -0
  168. package/dist/ble/telink.js +108 -0
  169. package/dist/ble/telink.js.map +1 -0
  170. package/dist/ble/transitions.d.ts +3 -0
  171. package/dist/ble/transitions.d.ts.map +1 -0
  172. package/dist/ble/transitions.js +28 -0
  173. package/dist/ble/transitions.js.map +1 -0
  174. package/dist/ble/transport.d.ts +48 -0
  175. package/dist/ble/transport.d.ts.map +1 -0
  176. package/dist/ble/transport.js +370 -0
  177. package/dist/ble/transport.js.map +1 -0
  178. package/dist/circadian.d.ts +3 -0
  179. package/dist/circadian.d.ts.map +1 -1
  180. package/dist/circadian.js +2 -0
  181. package/dist/circadian.js.map +1 -1
  182. package/dist/cli.d.ts +3 -2
  183. package/dist/cli.d.ts.map +1 -1
  184. package/dist/cli.js +125 -6
  185. package/dist/cli.js.map +1 -1
  186. package/dist/commands/__tests__/newCommands.test.js +3 -4
  187. package/dist/commands/__tests__/newCommands.test.js.map +1 -1
  188. package/dist/commands/cmdUtils.d.ts +5 -2
  189. package/dist/commands/cmdUtils.d.ts.map +1 -1
  190. package/dist/commands/cmdUtils.js +29 -10
  191. package/dist/commands/cmdUtils.js.map +1 -1
  192. package/dist/commands/daylightSimulation/autoCct.d.ts.map +1 -1
  193. package/dist/commands/daylightSimulation/autoCct.js +67 -197
  194. package/dist/commands/daylightSimulation/autoCct.js.map +1 -1
  195. package/dist/commands/daylightSimulation/graphSchedule.d.ts +1 -1
  196. package/dist/commands/daylightSimulation/graphSchedule.d.ts.map +1 -1
  197. package/dist/commands/daylightSimulation/printSchedule.d.ts +1 -1
  198. package/dist/commands/daylightSimulation/printSchedule.d.ts.map +1 -1
  199. package/dist/commands/daylightSimulation/printSchedule.js +2 -2
  200. package/dist/commands/daylightSimulation/printSchedule.js.map +1 -1
  201. package/dist/commands/daylightSimulation/service.d.ts +1 -1
  202. package/dist/commands/daylightSimulation/service.d.ts.map +1 -1
  203. package/dist/commands/daylightSimulation/service.js +5 -3
  204. package/dist/commands/daylightSimulation/service.js.map +1 -1
  205. package/dist/commands/daylightSimulation/simulateSchedule.d.ts +1 -1
  206. package/dist/commands/daylightSimulation/simulateSchedule.d.ts.map +1 -1
  207. package/dist/commands/daylightSimulation/simulateSchedule.js +5 -4
  208. package/dist/commands/daylightSimulation/simulateSchedule.js.map +1 -1
  209. package/dist/commands/deviceControl/ble.d.ts +4 -0
  210. package/dist/commands/deviceControl/ble.d.ts.map +1 -0
  211. package/dist/commands/deviceControl/ble.js +214 -0
  212. package/dist/commands/deviceControl/ble.js.map +1 -0
  213. package/dist/commands/deviceControl/cct.d.ts.map +1 -1
  214. package/dist/commands/deviceControl/cct.js +41 -11
  215. package/dist/commands/deviceControl/cct.js.map +1 -1
  216. package/dist/commands/deviceControl/color.d.ts.map +1 -1
  217. package/dist/commands/deviceControl/color.js +13 -3
  218. package/dist/commands/deviceControl/color.js.map +1 -1
  219. package/dist/commands/deviceControl/config.d.ts.map +1 -1
  220. package/dist/commands/deviceControl/config.js +26 -3
  221. package/dist/commands/deviceControl/config.js.map +1 -1
  222. package/dist/commands/deviceControl/{discover.d.ts → desktop.d.ts} +3 -2
  223. package/dist/commands/deviceControl/desktop.d.ts.map +1 -0
  224. package/dist/commands/deviceControl/desktop.js +66 -0
  225. package/dist/commands/deviceControl/desktop.js.map +1 -0
  226. package/dist/commands/deviceControl/effect.d.ts.map +1 -1
  227. package/dist/commands/deviceControl/effect.js +90 -159
  228. package/dist/commands/deviceControl/effect.js.map +1 -1
  229. package/dist/commands/deviceControl/fan.d.ts.map +1 -1
  230. package/dist/commands/deviceControl/fan.js +77 -95
  231. package/dist/commands/deviceControl/fan.js.map +1 -1
  232. package/dist/commands/deviceControl/group.d.ts.map +1 -1
  233. package/dist/commands/deviceControl/group.js +43 -6
  234. package/dist/commands/deviceControl/group.js.map +1 -1
  235. package/dist/commands/deviceControl/hsi.d.ts.map +1 -1
  236. package/dist/commands/deviceControl/hsi.js +3 -1
  237. package/dist/commands/deviceControl/hsi.js.map +1 -1
  238. package/dist/commands/deviceControl/info.d.ts.map +1 -1
  239. package/dist/commands/deviceControl/info.js +0 -50
  240. package/dist/commands/deviceControl/info.js.map +1 -1
  241. package/dist/commands/deviceControl/intensity.d.ts.map +1 -1
  242. package/dist/commands/deviceControl/intensity.js +32 -8
  243. package/dist/commands/deviceControl/intensity.js.map +1 -1
  244. package/dist/commands/deviceControl/list.d.ts.map +1 -1
  245. package/dist/commands/deviceControl/list.js +3 -2
  246. package/dist/commands/deviceControl/list.js.map +1 -1
  247. package/dist/commands/deviceControl/power.d.ts.map +1 -1
  248. package/dist/commands/deviceControl/power.js +9 -3
  249. package/dist/commands/deviceControl/power.js.map +1 -1
  250. package/dist/commands/deviceControl/preset.d.ts.map +1 -1
  251. package/dist/commands/deviceControl/preset.js +56 -19
  252. package/dist/commands/deviceControl/preset.js.map +1 -1
  253. package/dist/commands/deviceControl/program.d.ts +4 -0
  254. package/dist/commands/deviceControl/program.d.ts.map +1 -0
  255. package/dist/commands/deviceControl/program.js +199 -0
  256. package/dist/commands/deviceControl/program.js.map +1 -0
  257. package/dist/commands/deviceControl/quickshot.d.ts.map +1 -1
  258. package/dist/commands/deviceControl/quickshot.js +75 -13
  259. package/dist/commands/deviceControl/quickshot.js.map +1 -1
  260. package/dist/commands/deviceControl/scene.d.ts.map +1 -1
  261. package/dist/commands/deviceControl/scene.js +72 -9
  262. package/dist/commands/deviceControl/scene.js.map +1 -1
  263. package/dist/commands/deviceControl/status.d.ts.map +1 -1
  264. package/dist/commands/deviceControl/status.js +26 -3
  265. package/dist/commands/deviceControl/status.js.map +1 -1
  266. package/dist/commands/parseUtils.d.ts +1 -1
  267. package/dist/commands/parseUtils.d.ts.map +1 -1
  268. package/dist/commands/parseUtils.js +1 -11
  269. package/dist/commands/parseUtils.js.map +1 -1
  270. package/dist/commands-api.d.ts +1 -1
  271. package/dist/commands-api.d.ts.map +1 -1
  272. package/dist/commands-api.js +1 -1
  273. package/dist/commands-api.js.map +1 -1
  274. package/dist/commands.d.ts.map +1 -1
  275. package/dist/commands.js +4 -2
  276. package/dist/commands.js.map +1 -1
  277. package/dist/config.d.ts +82 -0
  278. package/dist/config.d.ts.map +1 -1
  279. package/dist/config.js +13 -2
  280. package/dist/config.js.map +1 -1
  281. package/dist/daylightSimulation/cctUtil.d.ts.map +1 -1
  282. package/dist/daylightSimulation/cctUtil.js +2 -2
  283. package/dist/daylightSimulation/cctUtil.js.map +1 -1
  284. package/dist/daylightSimulation/constants.d.ts +10 -0
  285. package/dist/daylightSimulation/constants.d.ts.map +1 -1
  286. package/dist/daylightSimulation/constants.js +4 -0
  287. package/dist/daylightSimulation/constants.js.map +1 -1
  288. package/dist/daylightSimulation/currentCct.d.ts +42 -0
  289. package/dist/daylightSimulation/currentCct.d.ts.map +1 -0
  290. package/dist/daylightSimulation/currentCct.js +217 -0
  291. package/dist/daylightSimulation/currentCct.js.map +1 -0
  292. package/dist/daylightSimulation/dashboardSettings.d.ts +47 -0
  293. package/dist/daylightSimulation/dashboardSettings.d.ts.map +1 -0
  294. package/dist/daylightSimulation/dashboardSettings.js +95 -0
  295. package/dist/daylightSimulation/dashboardSettings.js.map +1 -0
  296. package/dist/daylightSimulation/dashboardStatus.d.ts +72 -0
  297. package/dist/daylightSimulation/dashboardStatus.d.ts.map +1 -0
  298. package/dist/daylightSimulation/dashboardStatus.js +191 -0
  299. package/dist/daylightSimulation/dashboardStatus.js.map +1 -0
  300. package/dist/daylightSimulation/parseUtils.d.ts +3 -0
  301. package/dist/daylightSimulation/parseUtils.d.ts.map +1 -0
  302. package/dist/daylightSimulation/parseUtils.js +25 -0
  303. package/dist/daylightSimulation/parseUtils.js.map +1 -0
  304. package/dist/daylightSimulation/scheduleMaker.d.ts +2 -2
  305. package/dist/daylightSimulation/scheduleMaker.d.ts.map +1 -1
  306. package/dist/daylightSimulation/scheduleMaker.js +6 -6
  307. package/dist/daylightSimulation/scheduleMaker.js.map +1 -1
  308. package/dist/daylightSimulation/types.d.ts +13 -2
  309. package/dist/daylightSimulation/types.d.ts.map +1 -1
  310. package/dist/daylightSimulation/types.js +0 -2
  311. package/dist/daylightSimulation/types.js.map +1 -1
  312. package/dist/device-control.d.ts +1 -0
  313. package/dist/device-control.d.ts.map +1 -1
  314. package/dist/device-control.js +1 -0
  315. package/dist/device-control.js.map +1 -1
  316. package/dist/deviceControl/bleHttpControl.d.ts +129 -0
  317. package/dist/deviceControl/bleHttpControl.d.ts.map +1 -0
  318. package/dist/deviceControl/bleHttpControl.js +753 -0
  319. package/dist/deviceControl/bleHttpControl.js.map +1 -0
  320. package/dist/deviceControl/lightControl.d.ts +8 -68
  321. package/dist/deviceControl/lightControl.d.ts.map +1 -1
  322. package/dist/deviceControl/lightControl.js +6 -246
  323. package/dist/deviceControl/lightControl.js.map +1 -1
  324. package/dist/deviceControl/lightControlCommands.d.ts +68 -0
  325. package/dist/deviceControl/lightControlCommands.d.ts.map +1 -0
  326. package/dist/deviceControl/lightControlCommands.js +244 -0
  327. package/dist/deviceControl/lightControlCommands.js.map +1 -0
  328. package/dist/deviceControl/types.d.ts +75 -4
  329. package/dist/deviceControl/types.d.ts.map +1 -1
  330. package/dist/deviceControl/types.js +1 -0
  331. package/dist/deviceControl/types.js.map +1 -1
  332. package/dist/index.d.ts +2 -1
  333. package/dist/index.d.ts.map +1 -1
  334. package/dist/index.js +1 -0
  335. package/dist/index.js.map +1 -1
  336. package/dist/test/MockLightServer.d.ts +1 -0
  337. package/dist/test/MockLightServer.d.ts.map +1 -1
  338. package/dist/test/MockLightServer.js +5 -0
  339. package/dist/test/MockLightServer.js.map +1 -1
  340. package/docs/CHANGELOG.md +37 -0
  341. package/docs/DIRECT_BLE.md +359 -0
  342. package/package.json +8 -4
  343. package/scripts/ble-cli-check.ts +129 -0
  344. package/scripts/ble-config-probe.ts +109 -0
  345. package/scripts/ble-effects-check.ts +82 -0
  346. package/scripts/ble-extended-probe.ts +44 -0
  347. package/scripts/ble-fan-check.ts +129 -0
  348. package/scripts/ble-feature-probe.ts +37 -0
  349. package/scripts/ble-followup-check.ts +165 -0
  350. package/scripts/ble-hardware-check.ts +99 -0
  351. package/scripts/ble-live-extended-check.ts +205 -0
  352. package/scripts/ble-non-ota-check.ts +193 -0
  353. package/scripts/ble-probe.ts +45 -0
  354. package/scripts/calibrate-webcam.ts +152 -0
  355. package/scripts/desktop-reference.ts +85 -0
  356. package/scripts/webcam.ts +129 -0
  357. package/dist/__tests__/lightControl.test.d.ts +0 -2
  358. package/dist/__tests__/lightControl.test.d.ts.map +0 -1
  359. package/dist/__tests__/lightControl.test.js +0 -424
  360. package/dist/__tests__/lightControl.test.js.map +0 -1
  361. package/dist/commands/deviceControl/discover.d.ts.map +0 -1
  362. package/dist/commands/deviceControl/discover.js +0 -29
  363. package/dist/commands/deviceControl/discover.js.map +0 -1
@@ -0,0 +1,329 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { setTimeout as delay } from 'node:timers/promises';
3
+ import { z } from 'zod';
4
+ import { validateAction } from './controller.js';
5
+ import { MediaSampleSchema, MediaSourceSchema, mediaCommand, mediaSamples } from './media.js';
6
+ export const ProgramSchema = z
7
+ .object({
8
+ kind: z.enum(['timeline', 'audio', 'picker']),
9
+ targets: z.union([z.literal('all'), z.array(z.string()).min(1)]),
10
+ duration: z.number().min(1).max(1200).default(30),
11
+ restore: z.boolean().default(true),
12
+ maxBrightness: z.number().min(0).max(100).default(100),
13
+ gain: z.number().positive().max(100).default(3),
14
+ source: MediaSourceSchema.optional(),
15
+ steps: z
16
+ .array(z
17
+ .object({
18
+ at: z.number().min(0).max(1200),
19
+ action: z.enum(['cct', 'hsi', 'brightness', 'color', 'gm', 'on', 'off', 'effect', 'effect-stop']),
20
+ args: z.record(z.unknown()),
21
+ })
22
+ .strict())
23
+ .min(1)
24
+ .max(512)
25
+ .optional(),
26
+ })
27
+ .strict()
28
+ .superRefine((program, context) => {
29
+ if (program.kind === 'timeline') {
30
+ if (!program.steps || program.source)
31
+ context.addIssue({ code: 'custom', message: 'A timeline needs steps and no media source' });
32
+ program.steps?.forEach((step, index) => {
33
+ if (step.at > program.duration || (index && step.at - (program.steps?.[index - 1].at ?? 0) < 0.5))
34
+ context.addIssue({
35
+ code: 'custom',
36
+ message: 'Steps must be ordered, at least 0.5 seconds apart, and within duration',
37
+ });
38
+ });
39
+ }
40
+ else {
41
+ if (program.steps || !program.source)
42
+ context.addIssue({ code: 'custom', message: 'Media programs need a source and no timeline steps' });
43
+ if (program.source &&
44
+ (program.kind === 'audio') !==
45
+ (program.source.kind === 'samples'
46
+ ? program.source.media === 'audio'
47
+ : ['audio-file', 'microphone'].includes(program.source.kind)))
48
+ context.addIssue({ code: 'custom', message: 'Media source does not match program kind' });
49
+ }
50
+ });
51
+ export class Programs {
52
+ controller;
53
+ targets;
54
+ jobs = new Map();
55
+ closed = false;
56
+ starts = Promise.resolve();
57
+ generations = new Map();
58
+ constructor(controller, targets) {
59
+ this.controller = controller;
60
+ this.targets = targets;
61
+ }
62
+ list() {
63
+ return [...this.jobs.values()].map((job) => structuredClone(job.status));
64
+ }
65
+ get(id) {
66
+ const job = this.jobs.get(id);
67
+ if (!job)
68
+ throw new Error(`Unknown program ${id}`);
69
+ return structuredClone(job.status);
70
+ }
71
+ async start(value) {
72
+ if (this.closed)
73
+ throw new Error('Program manager is stopping');
74
+ const program = ProgramSchema.parse(value);
75
+ const keys = this.targets(program.targets);
76
+ if (!keys.length)
77
+ throw new Error('Program has no targets');
78
+ for (const key of keys) {
79
+ const light = this.controller.config.lights.find((item) => item.key === key);
80
+ if (!light)
81
+ throw new Error(`Unknown fixture ${key}`);
82
+ if (program.kind === 'timeline')
83
+ for (const step of program.steps ?? [])
84
+ validateAction(light, step.action, step.args);
85
+ else
86
+ validateAction(light, program.kind === 'picker' ? 'hsi' : 'brightness', program.kind === 'picker'
87
+ ? { hue: 0, saturation: 100, brightness: program.maxBrightness }
88
+ : { value: program.maxBrightness });
89
+ }
90
+ if (program.source && program.source.kind !== 'samples')
91
+ mediaCommand(program.source);
92
+ const generations = keys.map((key) => {
93
+ const value = (this.generations.get(key) ?? 0) + 1;
94
+ this.generations.set(key, value);
95
+ return value;
96
+ });
97
+ const previous = this.starts;
98
+ let release = () => undefined;
99
+ this.starts = new Promise((resolve) => {
100
+ release = resolve;
101
+ });
102
+ await previous;
103
+ try {
104
+ const superseded = () => keys.some((key, index) => this.generations.get(key) !== generations[index]);
105
+ if (superseded())
106
+ throw new Error('Program start superseded by newer control');
107
+ await this.cancelExisting(keys);
108
+ if (superseded())
109
+ throw new Error('Program start superseded by newer control');
110
+ if (this.closed)
111
+ throw new Error('Program manager is stopping');
112
+ const active = [...this.jobs.values()].filter((job) => ['running', 'preparing', 'restoring'].includes(job.status.state));
113
+ if (active.length >= 4)
114
+ throw new Error('Too many active programs');
115
+ for (const [id, job] of this.jobs)
116
+ if (this.jobs.size >= 50 && !['running', 'preparing', 'restoring'].includes(job.status.state))
117
+ this.jobs.delete(id);
118
+ const job = {
119
+ status: {
120
+ id: randomUUID(),
121
+ kind: program.kind,
122
+ targets: keys,
123
+ state: 'preparing',
124
+ startedAt: new Date().toISOString(),
125
+ frames: 0,
126
+ },
127
+ program,
128
+ cancel: new AbortController(),
129
+ restore: program.restore,
130
+ changed: false,
131
+ done: Promise.resolve(),
132
+ };
133
+ this.jobs.set(job.status.id, job);
134
+ job.done = this.run(job);
135
+ return structuredClone(job.status);
136
+ }
137
+ finally {
138
+ release();
139
+ }
140
+ }
141
+ async cancelTargets(keys) {
142
+ for (const key of keys)
143
+ this.generations.set(key, (this.generations.get(key) ?? 0) + 1);
144
+ await this.cancelExisting(keys);
145
+ }
146
+ async cancelExisting(keys) {
147
+ const targets = new Set(keys);
148
+ const jobs = [...this.jobs.values()].filter((job) => ['running', 'preparing', 'restoring'].includes(job.status.state) &&
149
+ job.status.targets.some((key) => targets.has(key)));
150
+ for (const job of jobs) {
151
+ job.restore = false;
152
+ job.cancel.abort(new Error('Manual control or another program took over'));
153
+ }
154
+ await Promise.all(jobs.map((job) => job.done));
155
+ }
156
+ async stop(id) {
157
+ const job = this.jobs.get(id);
158
+ if (!job)
159
+ throw new Error(`Unknown program ${id}`);
160
+ job.cancel.abort(new Error('Program stopped'));
161
+ await job.done;
162
+ return structuredClone(job.status);
163
+ }
164
+ sample(id, value) {
165
+ const job = this.jobs.get(id);
166
+ if (!job ||
167
+ job.program.source?.kind !== 'samples' ||
168
+ !['preparing', 'running'].includes(job.status.state) ||
169
+ job.cancel.signal.aborted)
170
+ throw new Error('Program is not accepting live samples');
171
+ const sample = MediaSampleSchema.parse(value);
172
+ if ('rms' in sample !== (job.program.kind === 'audio'))
173
+ throw new Error('Sample does not match the program kind');
174
+ job.latest = sample;
175
+ job.wake?.();
176
+ }
177
+ async *inputSamples(job, signal) {
178
+ while (true) {
179
+ signal.throwIfAborted();
180
+ if (job.latest) {
181
+ const sample = job.latest;
182
+ job.latest = undefined;
183
+ yield sample;
184
+ continue;
185
+ }
186
+ await new Promise((resolve, reject) => {
187
+ const cleanup = () => {
188
+ clearTimeout(timer);
189
+ job.wake = undefined;
190
+ signal.removeEventListener('abort', abort);
191
+ };
192
+ const abort = () => {
193
+ cleanup();
194
+ reject(signal.reason instanceof Error ? signal.reason : new Error('Sample stream cancelled'));
195
+ };
196
+ const timer = setTimeout(() => {
197
+ cleanup();
198
+ reject(new Error('No live samples received for 10 seconds'));
199
+ }, 10_000);
200
+ job.wake = () => {
201
+ cleanup();
202
+ resolve();
203
+ };
204
+ signal.addEventListener('abort', abort, { once: true });
205
+ if (signal.aborted)
206
+ abort();
207
+ });
208
+ }
209
+ }
210
+ async close() {
211
+ this.closed = true;
212
+ for (const job of this.jobs.values()) {
213
+ job.restore = false;
214
+ job.cancel.abort(new Error('Daemon stopped'));
215
+ }
216
+ await Promise.all([...this.jobs.values()].map((job) => job.done));
217
+ }
218
+ async command(job, action, args) {
219
+ job.cancel.signal.throwIfAborted();
220
+ job.changed = true;
221
+ await this.controller.batch(job.status.targets, action, args, false, job.cancel.signal);
222
+ job.status.frames++;
223
+ }
224
+ async run(job) {
225
+ const { program, cancel } = job;
226
+ let before;
227
+ let prior = {};
228
+ let timer;
229
+ let held = false;
230
+ try {
231
+ before = await this.controller.snapshot(job.status.targets);
232
+ cancel.signal.throwIfAborted();
233
+ const remaining = this.controller.overrideStatus(job.status.targets);
234
+ prior = Object.fromEntries(Object.entries(remaining).map(([key, ms]) => [key, ms ? Date.now() + ms : 0]));
235
+ if (program.kind !== 'timeline' && Object.values(before).some((state) => state.sleep || state.mode === 'effect'))
236
+ throw new Error('Start media control with awake fixtures in steady CCT or HSI mode');
237
+ await this.controller.reserveControl(job.status.targets, Math.max(30, program.duration / 60 + 1), cancel.signal);
238
+ held = true;
239
+ job.status.state = 'running';
240
+ const started = Date.now();
241
+ if (program.kind === 'timeline') {
242
+ for (const step of program.steps ?? []) {
243
+ await delay(Math.max(0, started + step.at * 1000 - Date.now()), undefined, { signal: cancel.signal });
244
+ await this.command(job, step.action, step.args);
245
+ }
246
+ await delay(Math.max(0, started + program.duration * 1000 - Date.now()), undefined, { signal: cancel.signal });
247
+ }
248
+ else {
249
+ if (!program.source)
250
+ throw new Error('Missing media source');
251
+ const sourceCancel = new AbortController();
252
+ const cancelled = () => sourceCancel.abort(cancel.signal.reason);
253
+ cancel.signal.addEventListener('abort', cancelled, { once: true });
254
+ if (cancel.signal.aborted)
255
+ cancelled();
256
+ const sourceSignal = sourceCancel.signal;
257
+ const durationEnd = new Error('Media duration completed');
258
+ timer = setTimeout(() => sourceCancel.abort(new Error('Media capture did not start within 10 seconds')), 10_000);
259
+ let mediaStarted;
260
+ let smoothed = 0, next = 0;
261
+ try {
262
+ const samples = program.source.kind === 'samples'
263
+ ? this.inputSamples(job, sourceSignal)
264
+ : mediaSamples(program.source, sourceSignal);
265
+ for await (const sample of samples) {
266
+ cancel.signal.throwIfAborted();
267
+ if (mediaStarted === undefined) {
268
+ mediaStarted = Date.now();
269
+ clearTimeout(timer);
270
+ timer = setTimeout(() => sourceCancel.abort(durationEnd), program.duration * 1000);
271
+ }
272
+ if (Date.now() >= mediaStarted + program.duration * 1000)
273
+ break;
274
+ await delay(Math.max(0, next - Date.now()), undefined, { signal: cancel.signal });
275
+ job.status.lastSample = sample;
276
+ if ('rms' in sample) {
277
+ smoothed = 0.35 * Math.min(1, sample.rms * program.gain) + 0.65 * smoothed;
278
+ await this.command(job, 'brightness', { value: Math.round(smoothed * program.maxBrightness) });
279
+ }
280
+ else {
281
+ const hex = sample.rgb.map((value) => value.toString(16).padStart(2, '0')).join('');
282
+ if (hex === '000000')
283
+ await this.command(job, 'brightness', { value: 0 });
284
+ else
285
+ await this.command(job, 'color', { color: `#${hex}`, brightness: program.maxBrightness });
286
+ }
287
+ next = Date.now() + 500;
288
+ }
289
+ }
290
+ catch (error) {
291
+ if (error !== durationEnd || cancel.signal.aborted)
292
+ throw error;
293
+ }
294
+ finally {
295
+ cancel.signal.removeEventListener('abort', cancelled);
296
+ }
297
+ if (!job.status.frames)
298
+ throw new Error('Media source produced no usable control frames');
299
+ }
300
+ job.status.state = 'completed';
301
+ }
302
+ catch (error) {
303
+ job.status.state = cancel.signal.aborted ? 'cancelled' : 'failed';
304
+ job.status.error = error.message;
305
+ }
306
+ finally {
307
+ clearTimeout(timer);
308
+ if (before && job.restore) {
309
+ const outcome = job.status.state;
310
+ job.status.state = 'restoring';
311
+ try {
312
+ if (job.changed)
313
+ await this.controller.restore(before);
314
+ if (held)
315
+ for (const [key, until] of Object.entries(prior))
316
+ await this.controller.override([key], Math.max(0, (until - Date.now()) / 60_000));
317
+ job.status.state = cancel.signal.aborted && outcome !== 'failed' ? 'cancelled' : outcome;
318
+ }
319
+ catch (error) {
320
+ job.status.state = 'failed';
321
+ job.status.error = `${job.status.error ? `${job.status.error}; ` : ''}Restoration failed: ${error.message}`;
322
+ }
323
+ }
324
+ if (job.status.state === 'failed')
325
+ console.error(`Program ${job.status.id} failed: ${job.status.error}`);
326
+ }
327
+ }
328
+ }
329
+ //# sourceMappingURL=programs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"programs.js","sourceRoot":"","sources":["../../src/ble/programs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface UnprovisionedDevice {
2
+ id: string;
3
+ uuid: string;
4
+ oobInformation: string;
5
+ name?: string;
6
+ rssi?: number;
7
+ }
8
+ export declare function provisioningAdvertisement(data: Buffer): {
9
+ uuid: string;
10
+ oobInformation: string;
11
+ } | undefined;
12
+ export declare function discoverUnprovisioned(): Promise<UnprovisionedDevice[]>;
13
+ //# sourceMappingURL=provisioning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provisioning.d.ts","sourceRoot":"","sources":["../../src/ble/provisioning.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AACD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAG5G;AACD,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA0B5E"}
@@ -0,0 +1,39 @@
1
+ import { setTimeout as delay } from 'node:timers/promises';
2
+ import { deadline } from './async.js';
3
+ export function provisioningAdvertisement(data) {
4
+ if (data.length !== 18 && data.length !== 22)
5
+ return undefined;
6
+ return { uuid: data.subarray(0, 16).toString('hex'), oobInformation: data.subarray(16, 18).toString('hex') };
7
+ }
8
+ export async function discoverUnprovisioned() {
9
+ const { default: noble } = await import('@abandonware/noble');
10
+ if (noble._state !== 'poweredOn')
11
+ throw new Error('Bluetooth must be powered on before discovery');
12
+ const devices = new Map();
13
+ const discover = (peripheral) => {
14
+ for (const service of peripheral.advertisement.serviceData ?? []) {
15
+ if (service.uuid !== '1827')
16
+ continue;
17
+ const data = provisioningAdvertisement(service.data);
18
+ if (!data)
19
+ continue;
20
+ devices.set(data.uuid, {
21
+ ...data,
22
+ id: peripheral.id,
23
+ name: peripheral.advertisement.localName,
24
+ rssi: peripheral.rssi === 127 ? undefined : peripheral.rssi,
25
+ });
26
+ }
27
+ };
28
+ noble.on('discover', discover);
29
+ try {
30
+ await deadline(noble.startScanningAsync(['1827'], true), 5000, 'Provisioning scan start');
31
+ await delay(5000);
32
+ }
33
+ finally {
34
+ noble.removeListener('discover', discover);
35
+ await deadline(noble.stopScanningAsync(), 3000, 'Provisioning scan stop');
36
+ }
37
+ return [...devices.values()];
38
+ }
39
+ //# sourceMappingURL=provisioning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provisioning.js","sourceRoot":"","sources":["../../src/ble/provisioning.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAStC,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,IAAI,IAAI,CAAC,MAAM,KAAK,EAAE,IAAI,IAAI,CAAC,MAAM,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAC/D,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AAC/G,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC9D,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnG,MAAM,OAAO,GAAG,IAAI,GAAG,EAA+B,CAAC;IACvD,MAAM,QAAQ,GAAG,CAAC,UAAsB,EAAE,EAAE;QAC1C,KAAK,MAAM,OAAO,IAAI,UAAU,CAAC,aAAa,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;YACjE,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM;gBAAE,SAAS;YACtC,MAAM,IAAI,GAAG,yBAAyB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACrD,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE;gBACrB,GAAG,IAAI;gBACP,EAAE,EAAE,UAAU,CAAC,EAAE;gBACjB,IAAI,EAAE,UAAU,CAAC,aAAa,CAAC,SAAS;gBACxC,IAAI,EAAE,UAAU,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI;aAC5D,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IACF,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC/B,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,yBAAyB,CAAC,CAAC;QAC1F,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC3C,MAAM,QAAQ,CAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,wBAAwB,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type IncomingMessage } from 'node:http';
2
+ import type { MaxLuxCalibration } from '../config.js';
3
+ import type { CircadianDashboardStatus } from '../daylightSimulation/dashboardStatus.js';
4
+ import { type VerifiedController } from './controller.js';
5
+ import { DashboardStore } from './dashboard.js';
6
+ import { LocalLibrary } from './library.js';
7
+ import type { MeshConfig } from './storage.js';
8
+ export declare function createBleServer(controller: VerifiedController, library?: LocalLibrary, options?: {
9
+ persistMesh?: (config: MeshConfig) => void;
10
+ dashboard?: DashboardStore;
11
+ luxCalibration?: MaxLuxCalibration;
12
+ luxByModel?: Partial<Record<MeshConfig['lights'][number]['model'], MaxLuxCalibration>>;
13
+ circadianStatus?: () => Promise<CircadianDashboardStatus>;
14
+ updateCircadianSettings?: (value: Record<string, unknown>) => Promise<CircadianDashboardStatus>;
15
+ }): import("http").Server<typeof IncomingMessage, typeof import("http").ServerResponse> & {
16
+ stopPrograms: () => Promise<void>;
17
+ };
18
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/ble/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAE/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AACzF,OAAO,EAAgB,KAAK,kBAAkB,EAAkB,MAAM,iBAAiB,CAAC;AACxF,OAAO,EACL,cAAc,EAMf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAA0B,YAAY,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAiB/C,wBAAgB,eAAe,CAC7B,UAAU,EAAE,kBAAkB,EAC9B,OAAO,eAAqB,EAC5B,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,cAAc,CAAC,EAAE,iBAAiB,CAAC;IACnC,UAAU,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACvF,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC1D,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAC;CAC5F;;EAsiBP"}