@willieee802/zigbee-herdsman 0.14.112 → 0.15.1

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 (348) hide show
  1. package/.release-please-manifest.json +4 -0
  2. package/CHANGELOG.md +27 -0
  3. package/dist/adapter/adapter.d.ts +61 -61
  4. package/dist/adapter/adapter.d.ts.map +1 -1
  5. package/dist/adapter/adapter.js +146 -100
  6. package/dist/adapter/adapter.js.map +1 -1
  7. package/dist/adapter/deconz/adapter/deconzAdapter.d.ts +68 -68
  8. package/dist/adapter/deconz/adapter/deconzAdapter.d.ts.map +1 -1
  9. package/dist/adapter/deconz/adapter/deconzAdapter.js +1060 -1063
  10. package/dist/adapter/deconz/adapter/deconzAdapter.js.map +1 -1
  11. package/dist/adapter/deconz/adapter/index.d.ts +2 -2
  12. package/dist/adapter/deconz/adapter/index.js +10 -10
  13. package/dist/adapter/deconz/driver/constants.d.ts +104 -104
  14. package/dist/adapter/deconz/driver/constants.js +55 -55
  15. package/dist/adapter/deconz/driver/driver.d.ts +81 -81
  16. package/dist/adapter/deconz/driver/driver.js +732 -732
  17. package/dist/adapter/deconz/driver/frame.d.ts +6 -6
  18. package/dist/adapter/deconz/driver/frame.js +13 -13
  19. package/dist/adapter/deconz/driver/frameParser.d.ts +2 -2
  20. package/dist/adapter/deconz/driver/frameParser.js +443 -443
  21. package/dist/adapter/deconz/driver/parser.d.ts +12 -12
  22. package/dist/adapter/deconz/driver/parser.js +61 -61
  23. package/dist/adapter/deconz/driver/writer.d.ts +8 -8
  24. package/dist/adapter/deconz/driver/writer.js +44 -44
  25. package/dist/adapter/events.d.ts +47 -47
  26. package/dist/adapter/events.js +14 -14
  27. package/dist/adapter/ezsp/adapter/backup.d.ts +9 -9
  28. package/dist/adapter/ezsp/adapter/backup.js +53 -53
  29. package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts +59 -59
  30. package/dist/adapter/ezsp/adapter/ezspAdapter.js +585 -585
  31. package/dist/adapter/ezsp/adapter/index.d.ts +2 -2
  32. package/dist/adapter/ezsp/adapter/index.js +10 -10
  33. package/dist/adapter/ezsp/driver/commands.d.ts +36 -34
  34. package/dist/adapter/ezsp/driver/commands.d.ts.map +1 -1
  35. package/dist/adapter/ezsp/driver/commands.js +2359 -2357
  36. package/dist/adapter/ezsp/driver/commands.js.map +1 -1
  37. package/dist/adapter/ezsp/driver/consts.d.ts +10 -10
  38. package/dist/adapter/ezsp/driver/consts.js +13 -13
  39. package/dist/adapter/ezsp/driver/driver.d.ts +103 -103
  40. package/dist/adapter/ezsp/driver/driver.js +639 -639
  41. package/dist/adapter/ezsp/driver/driver.js.map +1 -1
  42. package/dist/adapter/ezsp/driver/ezsp.d.ts +96 -96
  43. package/dist/adapter/ezsp/driver/ezsp.d.ts.map +1 -1
  44. package/dist/adapter/ezsp/driver/ezsp.js +586 -577
  45. package/dist/adapter/ezsp/driver/ezsp.js.map +1 -1
  46. package/dist/adapter/ezsp/driver/index.d.ts +3 -3
  47. package/dist/adapter/ezsp/driver/index.js +8 -8
  48. package/dist/adapter/ezsp/driver/multicast.d.ts +12 -12
  49. package/dist/adapter/ezsp/driver/multicast.js +74 -74
  50. package/dist/adapter/ezsp/driver/parser.d.ts +12 -12
  51. package/dist/adapter/ezsp/driver/parser.js +111 -111
  52. package/dist/adapter/ezsp/driver/types/basic.d.ts +62 -62
  53. package/dist/adapter/ezsp/driver/types/basic.js +208 -208
  54. package/dist/adapter/ezsp/driver/types/basic.js.map +1 -1
  55. package/dist/adapter/ezsp/driver/types/index.d.ts +9 -9
  56. package/dist/adapter/ezsp/driver/types/index.js +133 -133
  57. package/dist/adapter/ezsp/driver/types/named.d.ts +697 -697
  58. package/dist/adapter/ezsp/driver/types/named.js +1726 -1726
  59. package/dist/adapter/ezsp/driver/types/named.js.map +1 -1
  60. package/dist/adapter/ezsp/driver/types/struct.d.ts +251 -251
  61. package/dist/adapter/ezsp/driver/types/struct.js +708 -708
  62. package/dist/adapter/ezsp/driver/types/struct.js.map +1 -1
  63. package/dist/adapter/ezsp/driver/uart.d.ts +44 -44
  64. package/dist/adapter/ezsp/driver/uart.d.ts.map +1 -1
  65. package/dist/adapter/ezsp/driver/uart.js +368 -366
  66. package/dist/adapter/ezsp/driver/uart.js.map +1 -1
  67. package/dist/adapter/ezsp/driver/utils/crc16ccitt.d.ts +2 -2
  68. package/dist/adapter/ezsp/driver/utils/crc16ccitt.js +55 -55
  69. package/dist/adapter/ezsp/driver/utils/index.d.ts +18 -18
  70. package/dist/adapter/ezsp/driver/utils/index.js +67 -67
  71. package/dist/adapter/ezsp/driver/writer.d.ts +13 -13
  72. package/dist/adapter/ezsp/driver/writer.js +88 -88
  73. package/dist/adapter/index.d.ts +4 -4
  74. package/dist/adapter/index.js +35 -35
  75. package/dist/adapter/serialPort.d.ts +8 -8
  76. package/dist/adapter/serialPort.js +22 -22
  77. package/dist/adapter/serialPort.js.map +1 -1
  78. package/dist/adapter/serialPortUtils.d.ts +12 -12
  79. package/dist/adapter/serialPortUtils.js +18 -18
  80. package/dist/adapter/socketPortUtils.d.ts +10 -10
  81. package/dist/adapter/socketPortUtils.js +16 -16
  82. package/dist/adapter/tstype.d.ts +85 -85
  83. package/dist/adapter/tstype.js +2 -2
  84. package/dist/adapter/z-stack/adapter/adapter-backup.d.ts +62 -62
  85. package/dist/adapter/z-stack/adapter/adapter-backup.js +441 -441
  86. package/dist/adapter/z-stack/adapter/adapter-nv-memory.d.ts +150 -150
  87. package/dist/adapter/z-stack/adapter/adapter-nv-memory.js +258 -258
  88. package/dist/adapter/z-stack/adapter/endpoints.d.ts +11 -11
  89. package/dist/adapter/z-stack/adapter/endpoints.js +73 -73
  90. package/dist/adapter/z-stack/adapter/index.d.ts +2 -2
  91. package/dist/adapter/z-stack/adapter/index.js +8 -8
  92. package/dist/adapter/z-stack/adapter/manager.d.ts +86 -86
  93. package/dist/adapter/z-stack/adapter/manager.js +476 -476
  94. package/dist/adapter/z-stack/adapter/tstype.d.ts +6 -6
  95. package/dist/adapter/z-stack/adapter/tstype.js +10 -10
  96. package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts +81 -81
  97. package/dist/adapter/z-stack/adapter/zStackAdapter.js +868 -868
  98. package/dist/adapter/z-stack/constants/af.d.ts +23 -23
  99. package/dist/adapter/z-stack/constants/af.js +27 -27
  100. package/dist/adapter/z-stack/constants/common.d.ts +278 -278
  101. package/dist/adapter/z-stack/constants/common.js +289 -289
  102. package/dist/adapter/z-stack/constants/dbg.d.ts +22 -22
  103. package/dist/adapter/z-stack/constants/dbg.js +24 -24
  104. package/dist/adapter/z-stack/constants/index.d.ts +10 -10
  105. package/dist/adapter/z-stack/constants/index.js +47 -47
  106. package/dist/adapter/z-stack/constants/mac.d.ts +127 -127
  107. package/dist/adapter/z-stack/constants/mac.js +129 -129
  108. package/dist/adapter/z-stack/constants/sapi.d.ts +24 -24
  109. package/dist/adapter/z-stack/constants/sapi.js +26 -26
  110. package/dist/adapter/z-stack/constants/sys.d.ts +71 -71
  111. package/dist/adapter/z-stack/constants/sys.js +73 -73
  112. package/dist/adapter/z-stack/constants/util.d.ts +81 -81
  113. package/dist/adapter/z-stack/constants/util.js +83 -83
  114. package/dist/adapter/z-stack/constants/utils.d.ts +4 -4
  115. package/dist/adapter/z-stack/constants/utils.js +14 -14
  116. package/dist/adapter/z-stack/constants/zdo.d.ts +102 -102
  117. package/dist/adapter/z-stack/constants/zdo.js +104 -104
  118. package/dist/adapter/z-stack/models/index.d.ts +1 -1
  119. package/dist/adapter/z-stack/models/index.js +17 -17
  120. package/dist/adapter/z-stack/models/startup-options.d.ts +12 -12
  121. package/dist/adapter/z-stack/models/startup-options.js +2 -2
  122. package/dist/adapter/z-stack/structs/entries/address-manager-entry.d.ts +23 -23
  123. package/dist/adapter/z-stack/structs/entries/address-manager-entry.js +45 -45
  124. package/dist/adapter/z-stack/structs/entries/address-manager-table.d.ts +10 -10
  125. package/dist/adapter/z-stack/structs/entries/address-manager-table.js +22 -22
  126. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-entry.d.ts +10 -10
  127. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-entry.js +21 -21
  128. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-table.d.ts +10 -10
  129. package/dist/adapter/z-stack/structs/entries/aps-link-key-data-table.js +23 -23
  130. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-entry.d.ts +10 -10
  131. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-entry.js +24 -24
  132. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-table.d.ts +10 -10
  133. package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-table.js +23 -23
  134. package/dist/adapter/z-stack/structs/entries/channel-list.d.ts +8 -8
  135. package/dist/adapter/z-stack/structs/entries/channel-list.js +15 -15
  136. package/dist/adapter/z-stack/structs/entries/has-configured.d.ts +8 -8
  137. package/dist/adapter/z-stack/structs/entries/has-configured.js +16 -16
  138. package/dist/adapter/z-stack/structs/entries/index.d.ts +16 -16
  139. package/dist/adapter/z-stack/structs/entries/index.js +32 -32
  140. package/dist/adapter/z-stack/structs/entries/nib.d.ts +10 -10
  141. package/dist/adapter/z-stack/structs/entries/nib.js +68 -68
  142. package/dist/adapter/z-stack/structs/entries/nwk-key-descriptor.d.ts +10 -10
  143. package/dist/adapter/z-stack/structs/entries/nwk-key-descriptor.js +18 -18
  144. package/dist/adapter/z-stack/structs/entries/nwk-key.d.ts +8 -8
  145. package/dist/adapter/z-stack/structs/entries/nwk-key.js +15 -15
  146. package/dist/adapter/z-stack/structs/entries/nwk-pan-id.d.ts +8 -8
  147. package/dist/adapter/z-stack/structs/entries/nwk-pan-id.js +15 -15
  148. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.d.ts +13 -13
  149. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.js +23 -23
  150. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.d.ts +10 -10
  151. package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.js +22 -22
  152. package/dist/adapter/z-stack/structs/entries/security-manager-entry.d.ts +20 -20
  153. package/dist/adapter/z-stack/structs/entries/security-manager-entry.js +36 -36
  154. package/dist/adapter/z-stack/structs/entries/security-manager-table.d.ts +10 -10
  155. package/dist/adapter/z-stack/structs/entries/security-manager-table.js +24 -24
  156. package/dist/adapter/z-stack/structs/index.d.ts +4 -4
  157. package/dist/adapter/z-stack/structs/index.js +20 -20
  158. package/dist/adapter/z-stack/structs/serializable-memory-object.d.ts +13 -13
  159. package/dist/adapter/z-stack/structs/serializable-memory-object.js +2 -2
  160. package/dist/adapter/z-stack/structs/struct.d.ts +99 -99
  161. package/dist/adapter/z-stack/structs/struct.js +295 -295
  162. package/dist/adapter/z-stack/structs/table.d.ts +94 -94
  163. package/dist/adapter/z-stack/structs/table.js +161 -161
  164. package/dist/adapter/z-stack/unpi/constants.d.ts +28 -28
  165. package/dist/adapter/z-stack/unpi/constants.js +41 -41
  166. package/dist/adapter/z-stack/unpi/frame.d.ts +16 -16
  167. package/dist/adapter/z-stack/unpi/frame.js +48 -48
  168. package/dist/adapter/z-stack/unpi/index.d.ts +5 -5
  169. package/dist/adapter/z-stack/unpi/index.js +37 -37
  170. package/dist/adapter/z-stack/unpi/parser.d.ts +10 -10
  171. package/dist/adapter/z-stack/unpi/parser.js +74 -74
  172. package/dist/adapter/z-stack/unpi/writer.d.ts +10 -10
  173. package/dist/adapter/z-stack/unpi/writer.js +44 -44
  174. package/dist/adapter/z-stack/utils/channel-list.d.ts +20 -20
  175. package/dist/adapter/z-stack/utils/channel-list.js +40 -40
  176. package/dist/adapter/z-stack/utils/index.d.ts +2 -2
  177. package/dist/adapter/z-stack/utils/index.js +18 -18
  178. package/dist/adapter/z-stack/utils/network-options.d.ts +8 -8
  179. package/dist/adapter/z-stack/utils/network-options.js +22 -22
  180. package/dist/adapter/z-stack/znp/buffaloZnp.d.ts +11 -11
  181. package/dist/adapter/z-stack/znp/buffaloZnp.js +113 -113
  182. package/dist/adapter/z-stack/znp/definition.d.ts +5 -5
  183. package/dist/adapter/z-stack/znp/definition.js +3050 -3050
  184. package/dist/adapter/z-stack/znp/index.d.ts +3 -3
  185. package/dist/adapter/z-stack/znp/index.js +10 -10
  186. package/dist/adapter/z-stack/znp/parameterType.d.ts +22 -22
  187. package/dist/adapter/z-stack/znp/parameterType.js +25 -25
  188. package/dist/adapter/z-stack/znp/tstype.d.ts +21 -21
  189. package/dist/adapter/z-stack/znp/tstype.js +2 -2
  190. package/dist/adapter/z-stack/znp/znp.d.ts +43 -43
  191. package/dist/adapter/z-stack/znp/znp.js +325 -325
  192. package/dist/adapter/z-stack/znp/zpiObject.d.ts +19 -19
  193. package/dist/adapter/z-stack/znp/zpiObject.js +96 -96
  194. package/dist/adapter/zigate/adapter/index.d.ts +2 -2
  195. package/dist/adapter/zigate/adapter/index.js +10 -10
  196. package/dist/adapter/zigate/adapter/zigateAdapter.d.ts +69 -69
  197. package/dist/adapter/zigate/adapter/zigateAdapter.js +678 -678
  198. package/dist/adapter/zigate/debug.d.ts +7 -7
  199. package/dist/adapter/zigate/debug.js +22 -22
  200. package/dist/adapter/zigate/driver/buffaloZiGate.d.ts +18 -18
  201. package/dist/adapter/zigate/driver/buffaloZiGate.js +139 -139
  202. package/dist/adapter/zigate/driver/commandType.d.ts +41 -41
  203. package/dist/adapter/zigate/driver/commandType.js +385 -385
  204. package/dist/adapter/zigate/driver/constants.d.ts +276 -276
  205. package/dist/adapter/zigate/driver/constants.js +371 -371
  206. package/dist/adapter/zigate/driver/frame.d.ts +26 -26
  207. package/dist/adapter/zigate/driver/frame.js +172 -172
  208. package/dist/adapter/zigate/driver/frame.js.map +1 -1
  209. package/dist/adapter/zigate/driver/messageType.d.ts +11 -11
  210. package/dist/adapter/zigate/driver/messageType.js +278 -278
  211. package/dist/adapter/zigate/driver/parameterType.d.ts +20 -20
  212. package/dist/adapter/zigate/driver/parameterType.js +23 -23
  213. package/dist/adapter/zigate/driver/ziGateObject.d.ts +23 -23
  214. package/dist/adapter/zigate/driver/ziGateObject.js +106 -106
  215. package/dist/adapter/zigate/driver/zigate.d.ts +49 -49
  216. package/dist/adapter/zigate/driver/zigate.js +303 -303
  217. package/dist/buffalo/buffalo.d.ts +50 -48
  218. package/dist/buffalo/buffalo.d.ts.map +1 -1
  219. package/dist/buffalo/buffalo.js +322 -307
  220. package/dist/buffalo/buffalo.js.map +1 -1
  221. package/dist/buffalo/index.d.ts +3 -3
  222. package/dist/buffalo/index.js +33 -33
  223. package/dist/buffalo/tstype.d.ts +8 -8
  224. package/dist/buffalo/tstype.js +2 -2
  225. package/dist/controller/controller.d.ts +110 -110
  226. package/dist/controller/controller.js +607 -607
  227. package/dist/controller/database.d.ts +18 -18
  228. package/dist/controller/database.js +93 -93
  229. package/dist/controller/events.d.ts +55 -55
  230. package/dist/controller/events.d.ts.map +1 -1
  231. package/dist/controller/events.js +101 -99
  232. package/dist/controller/events.js.map +1 -1
  233. package/dist/controller/greenPower.d.ts +12 -12
  234. package/dist/controller/greenPower.js +220 -220
  235. package/dist/controller/helpers/index.d.ts +2 -2
  236. package/dist/controller/helpers/index.js +28 -28
  237. package/dist/controller/helpers/request.d.ts +23 -0
  238. package/dist/controller/helpers/request.d.ts.map +1 -0
  239. package/dist/controller/helpers/request.js +72 -0
  240. package/dist/controller/helpers/request.js.map +1 -0
  241. package/dist/controller/helpers/zclFrameConverter.d.ts +7 -7
  242. package/dist/controller/helpers/zclFrameConverter.js +31 -31
  243. package/dist/controller/helpers/zclTransactionSequenceNumber.d.ts +5 -5
  244. package/dist/controller/helpers/zclTransactionSequenceNumber.js +13 -13
  245. package/dist/controller/index.d.ts +5 -5
  246. package/dist/controller/index.js +8 -8
  247. package/dist/controller/logger-stub.d.ts +6 -6
  248. package/dist/controller/logger-stub.js +2 -2
  249. package/dist/controller/model/device.d.ts +132 -127
  250. package/dist/controller/model/device.d.ts.map +1 -1
  251. package/dist/controller/model/device.js +708 -681
  252. package/dist/controller/model/device.js.map +1 -1
  253. package/dist/controller/model/endpoint.d.ts +131 -128
  254. package/dist/controller/model/endpoint.d.ts.map +1 -1
  255. package/dist/controller/model/endpoint.js +817 -665
  256. package/dist/controller/model/endpoint.js.map +1 -1
  257. package/dist/controller/model/entity.d.ts +14 -14
  258. package/dist/controller/model/entity.js +26 -26
  259. package/dist/controller/model/group.d.ts +39 -39
  260. package/dist/controller/model/group.js +221 -221
  261. package/dist/controller/model/index.d.ts +5 -5
  262. package/dist/controller/model/index.js +14 -14
  263. package/dist/controller/touchlink.d.ts +19 -19
  264. package/dist/controller/touchlink.js +157 -157
  265. package/dist/controller/tstype.d.ts +21 -20
  266. package/dist/controller/tstype.d.ts.map +1 -1
  267. package/dist/controller/tstype.js +9 -9
  268. package/dist/controller/tstype.js.map +1 -1
  269. package/dist/index.d.ts +3 -3
  270. package/dist/index.js +33 -33
  271. package/dist/models/backup-storage-legacy.d.ts +26 -26
  272. package/dist/models/backup-storage-legacy.js +2 -2
  273. package/dist/models/backup-storage-unified.d.ts +49 -49
  274. package/dist/models/backup-storage-unified.js +2 -2
  275. package/dist/models/backup.d.ts +37 -37
  276. package/dist/models/backup.js +2 -2
  277. package/dist/models/index.d.ts +4 -4
  278. package/dist/models/index.js +20 -20
  279. package/dist/models/network-options.d.ts +12 -12
  280. package/dist/models/network-options.js +2 -2
  281. package/dist/utils/assertString.d.ts +2 -2
  282. package/dist/utils/assertString.js +8 -8
  283. package/dist/utils/backup.d.ts +20 -20
  284. package/dist/utils/backup.js +187 -187
  285. package/dist/utils/equalsPartial.d.ts +2 -2
  286. package/dist/utils/equalsPartial.js +11 -11
  287. package/dist/utils/index.d.ts +9 -9
  288. package/dist/utils/index.js +45 -45
  289. package/dist/utils/isNumberArray.d.ts +2 -2
  290. package/dist/utils/isNumberArray.js +6 -6
  291. package/dist/utils/queue.d.ts +11 -11
  292. package/dist/utils/queue.js +50 -50
  293. package/dist/utils/realpathSync.d.ts +2 -2
  294. package/dist/utils/realpathSync.js +12 -12
  295. package/dist/utils/wait.d.ts +2 -2
  296. package/dist/utils/wait.js +8 -8
  297. package/dist/utils/waitress.d.ts +21 -21
  298. package/dist/utils/waitress.js +61 -61
  299. package/dist/zcl/buffaloZcl.d.ts +41 -41
  300. package/dist/zcl/buffaloZcl.js +591 -591
  301. package/dist/zcl/definition/buffaloZclDataType.d.ts +17 -17
  302. package/dist/zcl/definition/buffaloZclDataType.js +20 -20
  303. package/dist/zcl/definition/cluster.d.ts +29 -29
  304. package/dist/zcl/definition/cluster.d.ts.map +1 -1
  305. package/dist/zcl/definition/cluster.js +5335 -5215
  306. package/dist/zcl/definition/cluster.js.map +1 -1
  307. package/dist/zcl/definition/dataType.d.ts +59 -59
  308. package/dist/zcl/definition/dataType.d.ts.map +1 -1
  309. package/dist/zcl/definition/dataType.js +64 -64
  310. package/dist/zcl/definition/dataType.js.map +1 -1
  311. package/dist/zcl/definition/direction.d.ts +5 -5
  312. package/dist/zcl/definition/direction.js +8 -8
  313. package/dist/zcl/definition/endpointDeviceType.d.ts +4 -4
  314. package/dist/zcl/definition/endpointDeviceType.js +15 -15
  315. package/dist/zcl/definition/foundation.d.ts +11 -11
  316. package/dist/zcl/definition/foundation.js +167 -167
  317. package/dist/zcl/definition/frameControl.d.ts +10 -10
  318. package/dist/zcl/definition/frameControl.js +2 -2
  319. package/dist/zcl/definition/frameType.d.ts +5 -5
  320. package/dist/zcl/definition/frameType.js +8 -8
  321. package/dist/zcl/definition/index.d.ts +13 -13
  322. package/dist/zcl/definition/index.js +51 -51
  323. package/dist/zcl/definition/manufacturerCode.d.ts +1074 -1074
  324. package/dist/zcl/definition/manufacturerCode.js +1079 -1079
  325. package/dist/zcl/definition/powerSource.d.ts +4 -4
  326. package/dist/zcl/definition/powerSource.js +12 -12
  327. package/dist/zcl/definition/status.d.ts +38 -38
  328. package/dist/zcl/definition/status.js +41 -41
  329. package/dist/zcl/definition/tstype.d.ts +16 -16
  330. package/dist/zcl/definition/tstype.js +2 -2
  331. package/dist/zcl/index.d.ts +15 -15
  332. package/dist/zcl/index.js +55 -55
  333. package/dist/zcl/tstype.d.ts +56 -56
  334. package/dist/zcl/tstype.js +10 -10
  335. package/dist/zcl/utils.d.ts +6 -6
  336. package/dist/zcl/utils.js +165 -165
  337. package/dist/zcl/zclFrame.d.ts +45 -45
  338. package/dist/zcl/zclFrame.js +347 -347
  339. package/dist/zcl/zclStatusError.d.ts +5 -5
  340. package/dist/zcl/zclStatusError.js +13 -13
  341. package/package.json +6 -5
  342. package/release-please-config.json +13 -0
  343. package/.github/ISSUE_TEMPLATE/config.yml +0 -5
  344. package/.github/dependabot.yml +0 -6
  345. package/.github/workflows/ci.yml +0 -31
  346. package/.github/workflows/release.yml +0 -56
  347. package/.github/workflows/stale.yml +0 -19
  348. package/.github/workflows/update_deps.yml +0 -24
@@ -1,666 +1,818 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
- Object.defineProperty(exports, "__esModule", { value: true });
29
- const entity_1 = __importDefault(require("./entity"));
30
- const Zcl = __importStar(require("../../zcl"));
31
- const zclTransactionSequenceNumber_1 = __importDefault(require("../helpers/zclTransactionSequenceNumber"));
32
- const ZclFrameConverter = __importStar(require("../helpers/zclFrameConverter"));
33
- const group_1 = __importDefault(require("./group"));
34
- const device_1 = __importDefault(require("./device"));
35
- const debug_1 = __importDefault(require("debug"));
36
- const assert_1 = __importDefault(require("assert"));
37
- const debug = {
38
- info: (0, debug_1.default)('zigbee-herdsman:controller:endpoint'),
39
- error: (0, debug_1.default)('zigbee-herdsman:controller:endpoint'),
40
- };
41
- class Endpoint extends entity_1.default {
42
- // Getters/setters
43
- get binds() {
44
- return this._binds.map((entry) => {
45
- let target = null;
46
- if (entry.type === 'endpoint') {
47
- const device = device_1.default.byIeeeAddr(this.databaseID, entry.deviceIeeeAddress);
48
- if (device) {
49
- target = device.getEndpoint(entry.endpointID);
50
- }
51
- }
52
- else {
53
- target = group_1.default.byGroupID(entry.groupID, this.databaseID);
54
- }
55
- if (target) {
56
- return { target, cluster: Zcl.Utils.getCluster(entry.cluster) };
57
- }
58
- else {
59
- return undefined;
60
- }
61
- }).filter(b => b !== undefined);
62
- }
63
- get configuredReportings() {
64
- return this._configuredReportings.map((entry) => {
65
- const cluster = Zcl.Utils.getCluster(entry.cluster, this.getDevice().manufacturerID);
66
- let attribute;
67
- if (cluster.hasAttribute(entry.attrId)) {
68
- attribute = cluster.getAttribute(entry.attrId);
69
- }
70
- else {
71
- attribute = {
72
- ID: entry.attrId,
73
- name: undefined,
74
- type: undefined,
75
- manufacturerCode: undefined
76
- };
77
- }
78
- return {
79
- cluster, attribute,
80
- minimumReportInterval: entry.minRepIntval,
81
- maximumReportInterval: entry.maxRepIntval,
82
- reportableChange: entry.repChange,
83
- };
84
- });
85
- }
86
- constructor(databaseID, ID, profileID, deviceID, inputClusters, outputClusters, deviceNetworkAddress, deviceIeeeAddress, clusters, binds, configuredReportings, meta) {
87
- super();
88
- this.databaseID = databaseID;
89
- this.ID = ID;
90
- this.profileID = profileID;
91
- this.deviceID = deviceID;
92
- this.inputClusters = inputClusters;
93
- this.outputClusters = outputClusters;
94
- this.deviceNetworkAddress = deviceNetworkAddress;
95
- this.deviceIeeeAddress = deviceIeeeAddress;
96
- this.clusters = clusters;
97
- this._binds = binds;
98
- this._configuredReportings = configuredReportings;
99
- this.meta = meta;
100
- this.pendingRequests = [];
101
- }
102
- /**
103
- * Get device of this endpoint
104
- */
105
- getDevice() {
106
- return device_1.default.byIeeeAddr(this.databaseID, this.deviceIeeeAddress);
107
- }
108
- /**
109
- * @param {number|string} clusterKey
110
- * @returns {boolean}
111
- */
112
- supportsInputCluster(clusterKey) {
113
- const cluster = Zcl.Utils.getCluster(clusterKey);
114
- return this.inputClusters.includes(cluster.ID);
115
- }
116
- /**
117
- * @param {number|string} clusterKey
118
- * @returns {boolean}
119
- */
120
- supportsOutputCluster(clusterKey) {
121
- const cluster = Zcl.Utils.getCluster(clusterKey);
122
- return this.outputClusters.includes(cluster.ID);
123
- }
124
- /**
125
- * @returns {Zcl.TsType.Cluster[]}
126
- */
127
- getInputClusters() {
128
- return this.clusterNumbersToClusters(this.inputClusters);
129
- }
130
- /**
131
- * @returns {Zcl.TsType.Cluster[]}
132
- */
133
- getOutputClusters() {
134
- return this.clusterNumbersToClusters(this.outputClusters);
135
- }
136
- clusterNumbersToClusters(clusterNumbers) {
137
- return clusterNumbers.map((c) => Zcl.Utils.getCluster(c, this.getDevice().manufacturerID));
138
- }
139
- /*
140
- * CRUD
141
- */
142
- static fromDatabaseRecord(record, deviceNetworkAddress, deviceIeeeAddress, databaseID) {
143
- // Migrate attrs to attributes
144
- for (const entry of Object.values(record.clusters).filter((e) => e.hasOwnProperty('attrs'))) {
145
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
146
- // @ts-ignore
147
- entry.attributes = entry.attrs;
148
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
149
- // @ts-ignore
150
- delete entry.attrs;
151
- }
152
- return new Endpoint(databaseID, record.epId, record.profId, record.devId, record.inClusterList, record.outClusterList, deviceNetworkAddress, deviceIeeeAddress, record.clusters, record.binds || [], record.configuredReportings || [], record.meta || {});
153
- }
154
- toDatabaseRecord() {
155
- return {
156
- profId: this.profileID, epId: this.ID, devId: this.deviceID,
157
- inClusterList: this.inputClusters, outClusterList: this.outputClusters, clusters: this.clusters,
158
- binds: this._binds, configuredReportings: this._configuredReportings, meta: this.meta,
159
- };
160
- }
161
- static create(databaseID, ID, profileID, deviceID, inputClusters, outputClusters, deviceNetworkAddress, deviceIeeeAddress) {
162
- return new Endpoint(databaseID, ID, profileID, deviceID, inputClusters, outputClusters, deviceNetworkAddress, deviceIeeeAddress, {}, [], [], {});
163
- }
164
- saveClusterAttributeKeyValue(clusterKey, list) {
165
- const cluster = Zcl.Utils.getCluster(clusterKey);
166
- if (!this.clusters[cluster.name])
167
- this.clusters[cluster.name] = { attributes: {} };
168
- for (const [attribute, value] of Object.entries(list)) {
169
- this.clusters[cluster.name].attributes[attribute] = value;
170
- }
171
- }
172
- getClusterAttributeValue(clusterKey, attributeKey) {
173
- const cluster = Zcl.Utils.getCluster(clusterKey);
174
- const attribute = cluster.getAttribute(attributeKey);
175
- if (this.clusters[cluster.name] && this.clusters[cluster.name].attributes) {
176
- return this.clusters[cluster.name].attributes[attribute.name];
177
- }
178
- return null;
179
- }
180
- hasPendingRequests() {
181
- return this.pendingRequests.length > 0;
182
- }
183
- async sendPendingRequests(fastPolling) {
184
- const handled = [];
185
- for (const request of this.pendingRequests) {
186
- if ((fastPolling && request.sendWhen == 'fastpoll') || request.sendWhen == 'active') {
187
- try {
188
- const result = await request.func();
189
- request.resolve(result);
190
- }
191
- catch (error) {
192
- request.reject(error);
193
- }
194
- handled.push(request);
195
- }
196
- }
197
- this.pendingRequests = this.pendingRequests.filter((r) => !handled.includes(r));
198
- }
199
- async queueRequest(func, sendWhen) {
200
- debug.info(`Sending to ${this.deviceIeeeAddress}/${this.ID} when active`);
201
- return new Promise((resolve, reject) => {
202
- this.pendingRequests.push({ func, resolve, reject, sendWhen });
203
- });
204
- }
205
- async sendRequest(func, sendWhen) {
206
- // If we already have something queued, we queue directly to avoid
207
- // messing up the ordering too much.
208
- if (sendWhen !== 'immediate' && this.pendingRequests.length > 0) {
209
- return this.queueRequest(func, sendWhen);
210
- }
211
- try {
212
- return await func();
213
- }
214
- catch (error) {
215
- if (sendWhen === 'immediate') {
216
- throw (error);
217
- }
218
- }
219
- // If we got a failed transaction, the device is likely sleeping.
220
- // Queue for transmission later.
221
- return this.queueRequest(func, sendWhen);
222
- }
223
- /*
224
- * Zigbee functions
225
- */
226
- checkStatus(payload) {
227
- const codes = Array.isArray(payload) ? payload.map((i) => i.status) : [payload.statusCode];
228
- const invalid = codes.find((c) => c !== Zcl.Status.SUCCESS);
229
- if (invalid)
230
- throw new Zcl.ZclStatusError(invalid);
231
- }
232
- async report(clusterKey, attributes, options) {
233
- var _a;
234
- const cluster = Zcl.Utils.getCluster(clusterKey);
235
- options = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
236
- const payload = [];
237
- for (const [nameOrID, value] of Object.entries(attributes)) {
238
- if (cluster.hasAttribute(nameOrID)) {
239
- const attribute = cluster.getAttribute(nameOrID);
240
- payload.push({ attrId: attribute.ID, attrData: value, dataType: attribute.type });
241
- }
242
- else if (!isNaN(Number(nameOrID))) {
243
- payload.push({ attrId: Number(nameOrID), attrData: value.value, dataType: value.type });
244
- }
245
- else {
246
- throw new Error(`Unknown attribute '${nameOrID}', specify either an existing attribute or a number`);
247
- }
248
- }
249
- const log = `Report to ${this.deviceIeeeAddress}/${this.ID} ` +
250
- `${cluster.name}(${JSON.stringify(attributes)}, ${JSON.stringify(options)})`;
251
- debug.info(log);
252
- try {
253
- const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, (_a = options.transactionSequenceNumber) !== null && _a !== void 0 ? _a : zclTransactionSequenceNumber_1.default.next(), "report", cluster.ID, payload, options.reservedBits);
254
- await this.sendRequest(async () => {
255
- await entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToEndpoint(this.deviceIeeeAddress, this.deviceNetworkAddress, this.ID, frame, options.timeout, options.disableResponse, options.disableRecovery, options.srcEndpoint);
256
- }, options.sendWhen);
257
- }
258
- catch (error) {
259
- error.message = `${log} failed (${error.message})`;
260
- debug.error(error.message);
261
- throw error;
262
- }
263
- }
264
- async write(clusterKey, attributes, options) {
265
- var _a;
266
- const cluster = Zcl.Utils.getCluster(clusterKey);
267
- options = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
268
- const payload = [];
269
- for (const [nameOrID, value] of Object.entries(attributes)) {
270
- if (cluster.hasAttribute(nameOrID)) {
271
- const attribute = cluster.getAttribute(nameOrID);
272
- payload.push({ attrId: attribute.ID, attrData: value, dataType: attribute.type });
273
- }
274
- else if (!isNaN(Number(nameOrID))) {
275
- payload.push({ attrId: Number(nameOrID), attrData: value.value, dataType: value.type });
276
- }
277
- else {
278
- throw new Error(`Unknown attribute '${nameOrID}', specify either an existing attribute or a number`);
279
- }
280
- }
281
- const log = `Write ${this.deviceIeeeAddress}/${this.ID} ` +
282
- `${cluster.name}(${JSON.stringify(attributes)}, ${JSON.stringify(options)})`;
283
- debug.info(log);
284
- try {
285
- const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, (_a = options.transactionSequenceNumber) !== null && _a !== void 0 ? _a : zclTransactionSequenceNumber_1.default.next(), options.writeUndiv ? "writeUndiv" : "write", cluster.ID, payload, options.reservedBits);
286
- const result = await this.sendRequest(async () => {
287
- return entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToEndpoint(this.deviceIeeeAddress, this.deviceNetworkAddress, this.ID, frame, options.timeout, options.disableResponse, options.disableRecovery, options.srcEndpoint);
288
- }, options.sendWhen);
289
- if (!options.disableResponse) {
290
- this.checkStatus(result.frame.Payload);
291
- }
292
- }
293
- catch (error) {
294
- error.message = `${log} failed (${error.message})`;
295
- debug.error(error.message);
296
- throw error;
297
- }
298
- }
299
- async writeResponse(clusterKey, transactionSequenceNumber, attributes, options) {
300
- (0, assert_1.default)(!options || !options.hasOwnProperty('transactionSequenceNumber'), 'Use parameter');
301
- const cluster = Zcl.Utils.getCluster(clusterKey);
302
- options = this.getOptionsWithDefaults(options, true, Zcl.Direction.SERVER_TO_CLIENT, cluster.manufacturerCode);
303
- const payload = [];
304
- for (const [nameOrID, value] of Object.entries(attributes)) {
305
- if (value.hasOwnProperty('status')) {
306
- if (cluster.hasAttribute(nameOrID)) {
307
- const attribute = cluster.getAttribute(nameOrID);
308
- payload.push({ attrId: attribute.ID, status: value.status });
309
- }
310
- else if (!isNaN(Number(nameOrID))) {
311
- payload.push({ attrId: Number(nameOrID), status: value.status });
312
- }
313
- else {
314
- throw new Error(`Unknown attribute '${nameOrID}', specify either an existing attribute or a number`);
315
- }
316
- }
317
- else {
318
- throw new Error(`Missing attribute 'status'`);
319
- }
320
- }
321
- const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, transactionSequenceNumber, 'writeRsp', cluster.ID, payload, options.reservedBits);
322
- const log = `WriteResponse ${this.deviceIeeeAddress}/${this.ID} ` +
323
- `${cluster.name}(${JSON.stringify(attributes)}, ${JSON.stringify(options)})`;
324
- debug.info(log);
325
- try {
326
- await this.sendRequest(async () => {
327
- await entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToEndpoint(this.deviceIeeeAddress, this.deviceNetworkAddress, this.ID, frame, options.timeout, options.disableResponse, options.disableRecovery, options.srcEndpoint);
328
- }, options.sendWhen);
329
- }
330
- catch (error) {
331
- error.message = `${log} failed (${error.message})`;
332
- debug.error(error.message);
333
- throw error;
334
- }
335
- }
336
- async read(clusterKey, attributes, options) {
337
- var _a;
338
- const cluster = Zcl.Utils.getCluster(clusterKey);
339
- options = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
340
- const payload = [];
341
- for (const attribute of attributes) {
342
- payload.push({ attrId: typeof attribute === 'number' ? attribute : cluster.getAttribute(attribute).ID });
343
- }
344
- const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, (_a = options.transactionSequenceNumber) !== null && _a !== void 0 ? _a : zclTransactionSequenceNumber_1.default.next(), 'read', cluster.ID, payload, options.reservedBits);
345
- const log = `Read ${this.deviceIeeeAddress}/${this.ID} ` +
346
- `${cluster.name}(${JSON.stringify(attributes)}, ${JSON.stringify(options)})`;
347
- debug.info(log);
348
- try {
349
- const result = await this.sendRequest(async () => {
350
- return entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToEndpoint(this.deviceIeeeAddress, this.deviceNetworkAddress, this.ID, frame, options.timeout, options.disableResponse, options.disableRecovery, options.srcEndpoint);
351
- }, options.sendWhen);
352
- if (!options.disableResponse) {
353
- this.checkStatus(result.frame.Payload);
354
- return ZclFrameConverter.attributeKeyValue(result.frame);
355
- }
356
- else {
357
- return null;
358
- }
359
- }
360
- catch (error) {
361
- error.message = `${log} failed (${error.message})`;
362
- debug.error(error.message);
363
- throw error;
364
- }
365
- }
366
- async readResponse(clusterKey, transactionSequenceNumber, attributes, options) {
367
- (0, assert_1.default)(!options || !options.hasOwnProperty('transactionSequenceNumber'), 'Use parameter');
368
- const cluster = Zcl.Utils.getCluster(clusterKey);
369
- options = this.getOptionsWithDefaults(options, true, Zcl.Direction.SERVER_TO_CLIENT, cluster.manufacturerCode);
370
- const payload = [];
371
- for (const [nameOrID, value] of Object.entries(attributes)) {
372
- if (cluster.hasAttribute(nameOrID)) {
373
- const attribute = cluster.getAttribute(nameOrID);
374
- payload.push({ attrId: attribute.ID, attrData: value, dataType: attribute.type, status: 0 });
375
- }
376
- else if (!isNaN(Number(nameOrID))) {
377
- payload.push({ attrId: Number(nameOrID), attrData: value.value, dataType: value.type, status: 0 });
378
- }
379
- else {
380
- throw new Error(`Unknown attribute '${nameOrID}', specify either an existing attribute or a number`);
381
- }
382
- }
383
- const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, transactionSequenceNumber, 'readRsp', cluster.ID, payload, options.reservedBits);
384
- const log = `ReadResponse ${this.deviceIeeeAddress}/${this.ID} ` +
385
- `${cluster.name}(${JSON.stringify(attributes)}, ${JSON.stringify(options)})`;
386
- debug.info(log);
387
- try {
388
- await this.sendRequest(async () => {
389
- await entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToEndpoint(this.deviceIeeeAddress, this.deviceNetworkAddress, this.ID, frame, options.timeout, options.disableResponse, options.disableRecovery, options.srcEndpoint);
390
- }, options.sendWhen);
391
- }
392
- catch (error) {
393
- error.message = `${log} failed (${error.message})`;
394
- debug.error(error.message);
395
- throw error;
396
- }
397
- }
398
- addBinding(clusterKey, target) {
399
- const cluster = Zcl.Utils.getCluster(clusterKey);
400
- if (typeof target === 'number') {
401
- target = group_1.default.byGroupID(target, this.databaseID) || group_1.default.create(target, this.databaseID);
402
- }
403
- if (!this.binds.find((b) => b.cluster.ID === cluster.ID && b.target === target)) {
404
- if (target instanceof group_1.default) {
405
- this._binds.push({ cluster: cluster.ID, groupID: target.groupID, type: 'group' });
406
- }
407
- else {
408
- this._binds.push({
409
- cluster: cluster.ID, type: 'endpoint', deviceIeeeAddress: target.deviceIeeeAddress,
410
- endpointID: target.ID
411
- });
412
- }
413
- this.save();
414
- }
415
- }
416
- async bind(clusterKey, target) {
417
- const cluster = Zcl.Utils.getCluster(clusterKey);
418
- const type = target instanceof Endpoint ? 'endpoint' : 'group';
419
- if (typeof target === 'number') {
420
- target = group_1.default.byGroupID(target, this.databaseID) || group_1.default.create(target, this.databaseID);
421
- }
422
- const destinationAddress = target instanceof Endpoint ? target.deviceIeeeAddress : target.groupID;
423
- const log = `Bind ${this.deviceIeeeAddress}/${this.ID} ${cluster.name} from ` +
424
- `'${target instanceof Endpoint ? `${destinationAddress}/${target.ID}` : destinationAddress}'`;
425
- debug.info(log);
426
- try {
427
- await entity_1.default.getAdapterByID(this.databaseID).bind(this.deviceNetworkAddress, this.deviceIeeeAddress, this.ID, cluster.ID, destinationAddress, type, target instanceof Endpoint ? target.ID : null);
428
- this.addBinding(clusterKey, target);
429
- }
430
- catch (error) {
431
- error.message = `${log} failed (${error.message})`;
432
- debug.error(error.message);
433
- throw error;
434
- }
435
- }
436
- save() {
437
- this.getDevice().save();
438
- }
439
- async unbind(clusterKey, target) {
440
- const cluster = Zcl.Utils.getCluster(clusterKey);
441
- const type = target instanceof Endpoint ? 'endpoint' : 'group';
442
- const destinationAddress = target instanceof Endpoint ? target.deviceIeeeAddress : (target instanceof group_1.default ? target.groupID : target);
443
- const log = `Unbind ${this.deviceIeeeAddress}/${this.ID} ${cluster.name} from ` +
444
- `'${target instanceof Endpoint ? `${destinationAddress}/${target.ID}` : destinationAddress}'`;
445
- debug.info(log);
446
- try {
447
- await entity_1.default.getAdapterByID(this.databaseID).unbind(this.deviceNetworkAddress, this.deviceIeeeAddress, this.ID, cluster.ID, destinationAddress, type, target instanceof Endpoint ? target.ID : null);
448
- if (typeof target === 'number' && group_1.default.byGroupID(target, this.databaseID)) {
449
- target = group_1.default.byGroupID(target, this.databaseID);
450
- }
451
- const index = this.binds.findIndex((b) => b.cluster.ID === cluster.ID && b.target === target);
452
- if (index !== -1) {
453
- this._binds.splice(index, 1);
454
- this.save();
455
- }
456
- }
457
- catch (error) {
458
- error.message = `${log} failed (${error.message})`;
459
- debug.error(error.message);
460
- throw error;
461
- }
462
- }
463
- async defaultResponse(commandID, status, clusterID, transactionSequenceNumber, options) {
464
- (0, assert_1.default)(!options || !options.hasOwnProperty('transactionSequenceNumber'), 'Use parameter');
465
- options = this.getOptionsWithDefaults(options, true, Zcl.Direction.SERVER_TO_CLIENT, null);
466
- const payload = { cmdId: commandID, statusCode: status };
467
- const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, transactionSequenceNumber, 'defaultRsp', clusterID, payload, options.reservedBits);
468
- const log = `DefaultResponse ${this.deviceIeeeAddress}/${this.ID} ` +
469
- `${clusterID}(${commandID}, ${JSON.stringify(options)})`;
470
- debug.info(log);
471
- try {
472
- await this.sendRequest(async () => {
473
- await entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToEndpoint(this.deviceIeeeAddress, this.deviceNetworkAddress, this.ID, frame, options.timeout, options.disableResponse, options.disableRecovery, options.srcEndpoint);
474
- }, options.sendWhen);
475
- }
476
- catch (error) {
477
- error.message = `${log} failed (${error.message})`;
478
- debug.error(error.message);
479
- throw error;
480
- }
481
- }
482
- async configureReporting(clusterKey, items, options) {
483
- var _a;
484
- const cluster = Zcl.Utils.getCluster(clusterKey);
485
- options = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
486
- const payload = items.map((item) => {
487
- let dataType, attrId;
488
- if (typeof item.attribute === 'object') {
489
- dataType = item.attribute.type;
490
- attrId = item.attribute.ID;
491
- }
492
- else {
493
- /* istanbul ignore else */
494
- if (cluster.hasAttribute(item.attribute)) {
495
- const attribute = cluster.getAttribute(item.attribute);
496
- dataType = attribute.type;
497
- attrId = attribute.ID;
498
- }
499
- }
500
- return {
501
- direction: Zcl.Direction.CLIENT_TO_SERVER,
502
- attrId, dataType,
503
- minRepIntval: item.minimumReportInterval,
504
- maxRepIntval: item.maximumReportInterval,
505
- repChange: item.reportableChange,
506
- };
507
- });
508
- const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, (_a = options.transactionSequenceNumber) !== null && _a !== void 0 ? _a : zclTransactionSequenceNumber_1.default.next(), 'configReport', cluster.ID, payload, options.reservedBits);
509
- const log = `ConfigureReporting ${this.deviceIeeeAddress}/${this.ID} ` +
510
- `${cluster.name}(${JSON.stringify(items)}, ${JSON.stringify(options)})`;
511
- debug.info(log);
512
- try {
513
- const result = await this.sendRequest(async () => {
514
- return entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToEndpoint(this.deviceIeeeAddress, this.deviceNetworkAddress, this.ID, frame, options.timeout, options.disableResponse, options.disableRecovery, options.srcEndpoint);
515
- }, options.sendWhen);
516
- if (!options.disableResponse) {
517
- this.checkStatus(result.frame.Payload);
518
- }
519
- for (const e of payload) {
520
- const match = this._configuredReportings.find(c => c.attrId === e.attrId && c.cluster === cluster.ID);
521
- if (match) {
522
- this._configuredReportings.splice(this._configuredReportings.indexOf(match), 1);
523
- }
524
- }
525
- for (const entry of payload) {
526
- if (entry.maxRepIntval !== 0xFFFF) {
527
- this._configuredReportings.push({
528
- cluster: cluster.ID, attrId: entry.attrId, minRepIntval: entry.minRepIntval,
529
- maxRepIntval: entry.maxRepIntval, repChange: entry.repChange,
530
- });
531
- }
532
- }
533
- this.save();
534
- }
535
- catch (error) {
536
- error.message = `${log} failed (${error.message})`;
537
- debug.error(error.message);
538
- throw error;
539
- }
540
- }
541
- async writeStructured(clusterKey, payload, options) {
542
- var _a;
543
- const cluster = Zcl.Utils.getCluster(clusterKey);
544
- options = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
545
- const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, (_a = options.transactionSequenceNumber) !== null && _a !== void 0 ? _a : zclTransactionSequenceNumber_1.default.next(), `writeStructured`, cluster.ID, payload, options.reservedBits);
546
- const log = `WriteStructured ${this.deviceIeeeAddress}/${this.ID} ` +
547
- `${cluster.name}(${JSON.stringify(payload)}, ${JSON.stringify(options)})`;
548
- debug.info(log);
549
- try {
550
- await this.sendRequest(async () => {
551
- await entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToEndpoint(this.deviceIeeeAddress, this.deviceNetworkAddress, this.ID, frame, options.timeout, options.disableResponse, options.disableRecovery, options.srcEndpoint);
552
- }, options.sendWhen);
553
- // TODO: support `writeStructuredResponse`
554
- }
555
- catch (error) {
556
- error.message = `${log} failed (${error.message})`;
557
- debug.error(error.message);
558
- throw error;
559
- }
560
- }
561
- async command(clusterKey, commandKey, payload, options) {
562
- var _a;
563
- const cluster = Zcl.Utils.getCluster(clusterKey);
564
- const command = cluster.getCommand(commandKey);
565
- const hasResponse = command.hasOwnProperty('response');
566
- options = this.getOptionsWithDefaults(options, hasResponse, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
567
- const frame = Zcl.ZclFrame.create(Zcl.FrameType.SPECIFIC, options.direction, options.disableDefaultResponse, options.manufacturerCode, (_a = options.transactionSequenceNumber) !== null && _a !== void 0 ? _a : zclTransactionSequenceNumber_1.default.next(), command.name, cluster.name, payload, options.reservedBits);
568
- const log = `Command ${this.deviceIeeeAddress}/${this.ID} ` +
569
- `${cluster.name}.${command.name}(${JSON.stringify(payload)}, ${JSON.stringify(options)})`;
570
- debug.info(log);
571
- try {
572
- const result = await this.sendRequest(async () => {
573
- return entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToEndpoint(this.deviceIeeeAddress, this.deviceNetworkAddress, this.ID, frame, options.timeout, options.disableResponse, options.disableRecovery, options.srcEndpoint);
574
- }, options.sendWhen);
575
- if (result) {
576
- return result.frame.Payload;
577
- }
578
- }
579
- catch (error) {
580
- error.message = `${log} failed (${error.message})`;
581
- debug.error(error.message);
582
- throw error;
583
- }
584
- }
585
- async commandResponse(clusterKey, commandKey, payload, options, transactionSequenceNumber) {
586
- (0, assert_1.default)(!options || !options.hasOwnProperty('transactionSequenceNumber'), 'Use parameter');
587
- const cluster = Zcl.Utils.getCluster(clusterKey);
588
- const command = cluster.getCommandResponse(commandKey);
589
- transactionSequenceNumber = transactionSequenceNumber || zclTransactionSequenceNumber_1.default.next();
590
- options = this.getOptionsWithDefaults(options, true, Zcl.Direction.SERVER_TO_CLIENT, cluster.manufacturerCode);
591
- const frame = Zcl.ZclFrame.create(Zcl.FrameType.SPECIFIC, options.direction, options.disableDefaultResponse, options.manufacturerCode, transactionSequenceNumber, command.name, cluster.name, payload, options.reservedBits);
592
- const log = `CommandResponse ${this.deviceIeeeAddress}/${this.ID} ` +
593
- `${cluster.name}.${command.name}(${JSON.stringify(payload)}, ${JSON.stringify(options)})`;
594
- debug.info(log);
595
- try {
596
- await this.sendRequest(async () => {
597
- // Broadcast Green Power responses
598
- if (this.ID === 242) {
599
- await entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToAll(242, frame, 242);
600
- }
601
- else {
602
- await entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToEndpoint(this.deviceIeeeAddress, this.deviceNetworkAddress, this.ID, frame, options.timeout, options.disableResponse, options.disableRecovery, options.srcEndpoint);
603
- }
604
- }, options.sendWhen);
605
- }
606
- catch (error) {
607
- error.message = `${log} failed (${error.message})`;
608
- debug.error(error.message);
609
- throw error;
610
- }
611
- }
612
- waitForCommand(clusterKey, commandKey, transactionSequenceNumber, timeout) {
613
- const cluster = Zcl.Utils.getCluster(clusterKey);
614
- const command = cluster.getCommand(commandKey);
615
- const waiter = entity_1.default.getAdapterByID(this.databaseID).waitFor(this.deviceNetworkAddress, this.ID, Zcl.FrameType.SPECIFIC, Zcl.Direction.CLIENT_TO_SERVER, transactionSequenceNumber, cluster.ID, command.ID, timeout);
616
- const promise = new Promise((resolve, reject) => {
617
- waiter.promise.then((payload) => resolve({ header: payload.frame.Header, payload: payload.frame.Payload }), (error) => reject(error));
618
- });
619
- return { promise, cancel: waiter.cancel };
620
- }
621
- getOptionsWithDefaults(options, disableDefaultResponse, direction, manufacturerCode) {
622
- const providedOptions = options || {};
623
- return {
624
- sendWhen: this.getDevice().defaultSendRequestWhen,
625
- timeout: 10000,
626
- disableResponse: false,
627
- disableRecovery: false,
628
- disableDefaultResponse,
629
- direction,
630
- srcEndpoint: null,
631
- reservedBits: 0,
632
- manufacturerCode: manufacturerCode ? manufacturerCode : null,
633
- transactionSequenceNumber: null,
634
- writeUndiv: false,
635
- ...providedOptions
636
- };
637
- }
638
- async addToGroup(group) {
639
- await this.command('genGroups', 'add', { groupid: group.groupID, groupname: '' });
640
- group.addMember(this);
641
- }
642
- /**
643
- * Remove endpoint from a group, accepts both a Group and number as parameter.
644
- * The number parameter type should only be used when removing from a group which is not known
645
- * to zigbee-herdsman.
646
- */
647
- async removeFromGroup(group) {
648
- await this.command('genGroups', 'remove', { groupid: group instanceof group_1.default ? group.groupID : group });
649
- if (group instanceof group_1.default) {
650
- group.removeMember(this);
651
- }
652
- }
653
- async removeFromAllGroups() {
654
- await this.command('genGroups', 'removeAll', {}, { disableDefaultResponse: true });
655
- this.removeFromAllGroupsDatabase();
656
- }
657
- removeFromAllGroupsDatabase() {
658
- for (const group of group_1.default.allByDatabaseID(this.databaseID)) {
659
- if (group.hasMember(this)) {
660
- group.removeMember(this);
661
- }
662
- }
663
- }
664
- }
665
- exports.default = Endpoint;
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const entity_1 = __importDefault(require("./entity"));
30
+ const Zcl = __importStar(require("../../zcl"));
31
+ const zclTransactionSequenceNumber_1 = __importDefault(require("../helpers/zclTransactionSequenceNumber"));
32
+ const ZclFrameConverter = __importStar(require("../helpers/zclFrameConverter"));
33
+ const request_1 = __importDefault(require("../helpers/request"));
34
+ const group_1 = __importDefault(require("./group"));
35
+ const device_1 = __importDefault(require("./device"));
36
+ const debug_1 = __importDefault(require("debug"));
37
+ const assert_1 = __importDefault(require("assert"));
38
+ const debug = {
39
+ info: (0, debug_1.default)('zigbee-herdsman:controller:endpoint'),
40
+ error: (0, debug_1.default)('zigbee-herdsman:controller:endpoint'),
41
+ };
42
+ class Endpoint extends entity_1.default {
43
+ // Getters/setters
44
+ get binds() {
45
+ return this._binds
46
+ .map((entry) => {
47
+ let target = null;
48
+ if (entry.type === 'endpoint') {
49
+ const device = device_1.default.byIeeeAddr(this.databaseID, entry.deviceIeeeAddress);
50
+ if (device) {
51
+ target = device.getEndpoint(entry.endpointID);
52
+ }
53
+ }
54
+ else {
55
+ target = group_1.default.byGroupID(entry.groupID, this.databaseID);
56
+ }
57
+ if (target) {
58
+ return { target, cluster: Zcl.Utils.getCluster(entry.cluster) };
59
+ }
60
+ else {
61
+ return undefined;
62
+ }
63
+ })
64
+ .filter((b) => b !== undefined);
65
+ }
66
+ get configuredReportings() {
67
+ return this._configuredReportings.map((entry) => {
68
+ const cluster = Zcl.Utils.getCluster(entry.cluster, this.getDevice().manufacturerID);
69
+ let attribute;
70
+ if (cluster.hasAttribute(entry.attrId)) {
71
+ attribute = cluster.getAttribute(entry.attrId);
72
+ }
73
+ else {
74
+ attribute = {
75
+ ID: entry.attrId,
76
+ name: undefined,
77
+ type: undefined,
78
+ manufacturerCode: undefined,
79
+ };
80
+ }
81
+ return {
82
+ cluster,
83
+ attribute,
84
+ minimumReportInterval: entry.minRepIntval,
85
+ maximumReportInterval: entry.maxRepIntval,
86
+ reportableChange: entry.repChange,
87
+ };
88
+ });
89
+ }
90
+ constructor(databaseID, ID, profileID, deviceID, inputClusters, outputClusters, deviceNetworkAddress, deviceIeeeAddress, clusters, binds, configuredReportings, meta) {
91
+ super();
92
+ this.databaseID = databaseID;
93
+ this.ID = ID;
94
+ this.profileID = profileID;
95
+ this.deviceID = deviceID;
96
+ this.inputClusters = inputClusters;
97
+ this.outputClusters = outputClusters;
98
+ this.deviceNetworkAddress = deviceNetworkAddress;
99
+ this.deviceIeeeAddress = deviceIeeeAddress;
100
+ this.clusters = clusters;
101
+ this._binds = binds;
102
+ this._configuredReportings = configuredReportings;
103
+ this.meta = meta;
104
+ this.pendingRequests = new Set();
105
+ this.sendInProgress = false;
106
+ }
107
+ /**
108
+ * Get device of this endpoint
109
+ */
110
+ getDevice() {
111
+ return device_1.default.byIeeeAddr(this.databaseID, this.deviceIeeeAddress);
112
+ }
113
+ /**
114
+ * @param {number|string} clusterKey
115
+ * @returns {boolean}
116
+ */
117
+ supportsInputCluster(clusterKey) {
118
+ const cluster = Zcl.Utils.getCluster(clusterKey);
119
+ return this.inputClusters.includes(cluster.ID);
120
+ }
121
+ /**
122
+ * @param {number|string} clusterKey
123
+ * @returns {boolean}
124
+ */
125
+ supportsOutputCluster(clusterKey) {
126
+ const cluster = Zcl.Utils.getCluster(clusterKey);
127
+ return this.outputClusters.includes(cluster.ID);
128
+ }
129
+ /**
130
+ * @returns {Zcl.TsType.Cluster[]}
131
+ */
132
+ getInputClusters() {
133
+ return this.clusterNumbersToClusters(this.inputClusters);
134
+ }
135
+ /**
136
+ * @returns {Zcl.TsType.Cluster[]}
137
+ */
138
+ getOutputClusters() {
139
+ return this.clusterNumbersToClusters(this.outputClusters);
140
+ }
141
+ clusterNumbersToClusters(clusterNumbers) {
142
+ return clusterNumbers.map((c) => Zcl.Utils.getCluster(c, this.getDevice().manufacturerID));
143
+ }
144
+ /*
145
+ * CRUD
146
+ */
147
+ static fromDatabaseRecord(record, deviceNetworkAddress, deviceIeeeAddress, databaseID) {
148
+ // Migrate attrs to attributes
149
+ for (const entry of Object.values(record.clusters).filter((e) => e.hasOwnProperty('attrs'))) {
150
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
151
+ // @ts-ignore
152
+ entry.attributes = entry.attrs;
153
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
154
+ // @ts-ignore
155
+ delete entry.attrs;
156
+ }
157
+ return new Endpoint(databaseID, record.epId, record.profId, record.devId, record.inClusterList, record.outClusterList, deviceNetworkAddress, deviceIeeeAddress, record.clusters, record.binds || [], record.configuredReportings || [], record.meta || {});
158
+ }
159
+ toDatabaseRecord() {
160
+ return {
161
+ profId: this.profileID,
162
+ epId: this.ID,
163
+ devId: this.deviceID,
164
+ inClusterList: this.inputClusters,
165
+ outClusterList: this.outputClusters,
166
+ clusters: this.clusters,
167
+ binds: this._binds,
168
+ configuredReportings: this._configuredReportings,
169
+ meta: this.meta,
170
+ };
171
+ }
172
+ static create(databaseID, ID, profileID, deviceID, inputClusters, outputClusters, deviceNetworkAddress, deviceIeeeAddress) {
173
+ return new Endpoint(databaseID, ID, profileID, deviceID, inputClusters, outputClusters, deviceNetworkAddress, deviceIeeeAddress, {}, [], [], {});
174
+ }
175
+ saveClusterAttributeKeyValue(clusterKey, list) {
176
+ const cluster = Zcl.Utils.getCluster(clusterKey);
177
+ if (!this.clusters[cluster.name])
178
+ this.clusters[cluster.name] = { attributes: {} };
179
+ for (const [attribute, value] of Object.entries(list)) {
180
+ this.clusters[cluster.name].attributes[attribute] = value;
181
+ }
182
+ }
183
+ getClusterAttributeValue(clusterKey, attributeKey) {
184
+ const cluster = Zcl.Utils.getCluster(clusterKey);
185
+ const attribute = cluster.getAttribute(attributeKey);
186
+ if (this.clusters[cluster.name] && this.clusters[cluster.name].attributes) {
187
+ return this.clusters[cluster.name].attributes[attribute.name];
188
+ }
189
+ return null;
190
+ }
191
+ hasPendingRequests() {
192
+ return this.pendingRequests.size > 0;
193
+ }
194
+ async sendPendingRequests(fastPolling) {
195
+ if (this.pendingRequests.size === 0)
196
+ return;
197
+ if (this.sendInProgress) {
198
+ debug.info(`Request Queue (${this.deviceIeeeAddress}/${this.ID}): sendPendingRequests already in progress`);
199
+ return;
200
+ }
201
+ this.sendInProgress = true;
202
+ // Remove expired requests first
203
+ const now = Date.now();
204
+ for (const request of this.pendingRequests) {
205
+ if (now > request.expires) {
206
+ debug.info(`Request Queue (${this.deviceIeeeAddress}/${this.ID}): discard after timeout. ` +
207
+ `Size before: ${this.pendingRequests.size}`);
208
+ request.reject();
209
+ this.pendingRequests.delete(request);
210
+ }
211
+ }
212
+ debug.info(`Request Queue (${this.deviceIeeeAddress}/${this.ID}): send pending requests (` +
213
+ `${this.pendingRequests.size}, ${fastPolling})`);
214
+ for (const request of this.pendingRequests) {
215
+ if (fastPolling ||
216
+ (request.sendWhen !== 'fastpoll' && request.sendPolicy !== 'bulk')) {
217
+ try {
218
+ const result = await request.send();
219
+ debug.info(`Request Queue (${this.deviceIeeeAddress}/${this.ID}): send success`);
220
+ request.resolve(result);
221
+ }
222
+ catch (error) {
223
+ debug.info(`Request Queue (${this.deviceIeeeAddress}/${this.ID}): send failed, expires in ` +
224
+ `${(request.expires - now) / 1000} seconds`);
225
+ request.reject(error);
226
+ }
227
+ this.pendingRequests.delete(request);
228
+ }
229
+ }
230
+ this.sendInProgress = false;
231
+ }
232
+ async queueRequest(request) {
233
+ debug.info(`Request Queue (${this.deviceIeeeAddress}/${this.ID}): Sending when active. ` +
234
+ `Timeout ${this.getDevice().pendingRequestTimeout / 1000} seconds`);
235
+ return new Promise((resolve, reject) => {
236
+ request.addCallbacks(resolve, reject);
237
+ this.pendingRequests.add(request);
238
+ });
239
+ }
240
+ filterRequests(newRequest) {
241
+ var _a, _b;
242
+ if (this.pendingRequests.size === 0 ||
243
+ !(typeof newRequest.frame.getCommand === 'function')) {
244
+ return;
245
+ }
246
+ const clusterID = newRequest.frame.Cluster.ID;
247
+ const payload = newRequest.frame.Payload;
248
+ const commandID = newRequest.frame.getCommand().ID;
249
+ debug.info(`Request Queue (${this.deviceIeeeAddress}/${this.ID}): ZCL ${newRequest.frame.getCommand().name} ` + `command, filter requests. Before: ${this.pendingRequests.size}`);
250
+ for (const request of this.pendingRequests) {
251
+ if (((_b = (_a = request === null || request === void 0 ? void 0 : request.frame) === null || _a === void 0 ? void 0 : _a.Cluster) === null || _b === void 0 ? void 0 : _b.ID) === undefined ||
252
+ typeof request.frame.getCommand !== 'function') {
253
+ continue;
254
+ }
255
+ if (['bulk', 'queue', 'immediate'].includes(request.sendPolicy)) {
256
+ continue;
257
+ }
258
+ /* istanbul ignore else */
259
+ if (request.frame.Cluster.ID === clusterID &&
260
+ request.frame.getCommand().ID === commandID) {
261
+ /* istanbul ignore else */
262
+ if (newRequest.sendPolicy === 'keep-payload' &&
263
+ JSON.stringify(request.frame.Payload) === JSON.stringify(payload)) {
264
+ debug.info(`Request Queue (${this.deviceIeeeAddress}/${this.ID}): Merge duplicate request`);
265
+ this.pendingRequests.delete(request);
266
+ newRequest.moveCallbacks(request);
267
+ }
268
+ else if (newRequest.sendPolicy === 'keep-command' ||
269
+ newRequest.sendPolicy === 'keep-cmd-undiv') {
270
+ const filteredPayload = request.frame.Payload.filter((oldEl) => !payload.find((newEl) => oldEl.attrId === newEl.attrId));
271
+ if (filteredPayload.length == 0) {
272
+ debug.info(`Request Queue (${this.deviceIeeeAddress}/${this.ID}): Remove & reject request`);
273
+ if (JSON.stringify(request.frame.Payload) === JSON.stringify(payload)) {
274
+ newRequest.moveCallbacks(request);
275
+ }
276
+ else {
277
+ request.reject();
278
+ }
279
+ this.pendingRequests.delete(request);
280
+ }
281
+ else if (newRequest.sendPolicy !== 'keep-cmd-undiv') {
282
+ // remove all duplicate attributes if we shall not write undivided
283
+ request.frame.Payload = filteredPayload;
284
+ debug.info(`Request Queue (${this.deviceIeeeAddress}/${this.ID}): ` +
285
+ `Remove commands from request`);
286
+ }
287
+ }
288
+ }
289
+ }
290
+ debug.info(`Request Queue (${this.deviceIeeeAddress}/${this.ID}): After: ${this.pendingRequests.size}`);
291
+ }
292
+ async sendRequest(frame, options, func = (d) => {
293
+ return entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToEndpoint(this.deviceIeeeAddress, this.deviceNetworkAddress, this.ID, d, options.timeout, options.disableResponse, options.disableRecovery, options.srcEndpoint);
294
+ }) {
295
+ const logPrefix = `Request Queue (${this.deviceIeeeAddress}/${this.ID}): `;
296
+ const request = new request_1.default(func, frame, this.getDevice().pendingRequestTimeout, options.sendWhen, options.sendPolicy);
297
+ if (request.sendPolicy !== 'bulk') {
298
+ // Check if such a request is already in the queue and remove the old one(s) if necessary
299
+ this.filterRequests(request);
300
+ }
301
+ // send without queueing if sendWhen or sendPolicy is 'immediate' or if the device has no timeout set
302
+ if (request.sendWhen === 'immediate' ||
303
+ request.sendPolicy === 'immediate' ||
304
+ !this.getDevice().pendingRequestTimeout) {
305
+ if (this.getDevice().defaultSendRequestWhen !== 'immediate') {
306
+ debug.info(logPrefix +
307
+ `send ${frame.getCommand().name} request immediately ` +
308
+ `(sendWhen=${options.sendWhen})`);
309
+ }
310
+ return request.send();
311
+ }
312
+ // If this is a bulk message, we queue directly.
313
+ if (request.sendPolicy === 'bulk') {
314
+ debug.info(logPrefix +
315
+ `queue request (${this.pendingRequests.size} / ${this.sendInProgress})))`);
316
+ return this.queueRequest(request);
317
+ }
318
+ try {
319
+ debug.info(logPrefix + `send request`);
320
+ return await request.send();
321
+ }
322
+ catch (error) {
323
+ // If we got a failed transaction, the device is likely sleeping.
324
+ // Queue for transmission later.
325
+ debug.info(logPrefix + `queue request (transaction failed)`);
326
+ return this.queueRequest(request);
327
+ }
328
+ }
329
+ /*
330
+ * Zigbee functions
331
+ */
332
+ checkStatus(payload) {
333
+ const codes = Array.isArray(payload)
334
+ ? payload.map((i) => i.status)
335
+ : [payload.statusCode];
336
+ const invalid = codes.find((c) => c !== Zcl.Status.SUCCESS);
337
+ if (invalid)
338
+ throw new Zcl.ZclStatusError(invalid);
339
+ }
340
+ async report(clusterKey, attributes, options) {
341
+ var _a;
342
+ const cluster = Zcl.Utils.getCluster(clusterKey);
343
+ options = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
344
+ const payload = [];
345
+ for (const [nameOrID, value] of Object.entries(attributes)) {
346
+ if (cluster.hasAttribute(nameOrID)) {
347
+ const attribute = cluster.getAttribute(nameOrID);
348
+ payload.push({
349
+ attrId: attribute.ID,
350
+ attrData: value,
351
+ dataType: attribute.type,
352
+ });
353
+ }
354
+ else if (!isNaN(Number(nameOrID))) {
355
+ payload.push({
356
+ attrId: Number(nameOrID),
357
+ attrData: value.value,
358
+ dataType: value.type,
359
+ });
360
+ }
361
+ else {
362
+ throw new Error(`Unknown attribute '${nameOrID}', specify either an existing attribute or a number`);
363
+ }
364
+ }
365
+ const log = `Report to ${this.deviceIeeeAddress}/${this.ID} ` +
366
+ `${cluster.name}(${JSON.stringify(attributes)}, ${JSON.stringify(options)})`;
367
+ debug.info(log);
368
+ try {
369
+ const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, (_a = options.transactionSequenceNumber) !== null && _a !== void 0 ? _a : zclTransactionSequenceNumber_1.default.next(), 'report', cluster.ID, payload, options.reservedBits);
370
+ await this.sendRequest(frame, options);
371
+ }
372
+ catch (error) {
373
+ error.message = `${log} failed (${error.message})`;
374
+ debug.error(error.message);
375
+ throw error;
376
+ }
377
+ }
378
+ async write(clusterKey, attributes, options) {
379
+ var _a;
380
+ const cluster = Zcl.Utils.getCluster(clusterKey);
381
+ options = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
382
+ const payload = [];
383
+ for (const [nameOrID, value] of Object.entries(attributes)) {
384
+ if (cluster.hasAttribute(nameOrID)) {
385
+ const attribute = cluster.getAttribute(nameOrID);
386
+ payload.push({
387
+ attrId: attribute.ID,
388
+ attrData: value,
389
+ dataType: attribute.type,
390
+ });
391
+ }
392
+ else if (!isNaN(Number(nameOrID))) {
393
+ payload.push({
394
+ attrId: Number(nameOrID),
395
+ attrData: value.value,
396
+ dataType: value.type,
397
+ });
398
+ }
399
+ else {
400
+ throw new Error(`Unknown attribute '${nameOrID}', specify either an existing attribute or a number`);
401
+ }
402
+ }
403
+ const log = `Write ${this.deviceIeeeAddress}/${this.ID} ` +
404
+ `${cluster.name}(${JSON.stringify(attributes)}, ${JSON.stringify(options)})`;
405
+ debug.info(log);
406
+ try {
407
+ const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, (_a = options.transactionSequenceNumber) !== null && _a !== void 0 ? _a : zclTransactionSequenceNumber_1.default.next(), options.writeUndiv ? 'writeUndiv' : 'write', cluster.ID, payload, options.reservedBits);
408
+ const result = await this.sendRequest(frame, options);
409
+ if (!options.disableResponse) {
410
+ this.checkStatus(result.frame.Payload);
411
+ }
412
+ }
413
+ catch (error) {
414
+ error.message = `${log} failed (${error.message})`;
415
+ debug.error(error.message);
416
+ throw error;
417
+ }
418
+ }
419
+ async writeResponse(clusterKey, transactionSequenceNumber, attributes, options) {
420
+ (0, assert_1.default)(!options || !options.hasOwnProperty('transactionSequenceNumber'), 'Use parameter');
421
+ const cluster = Zcl.Utils.getCluster(clusterKey);
422
+ options = this.getOptionsWithDefaults(options, true, Zcl.Direction.SERVER_TO_CLIENT, cluster.manufacturerCode);
423
+ const payload = [];
424
+ for (const [nameOrID, value] of Object.entries(attributes)) {
425
+ if (value.hasOwnProperty('status')) {
426
+ if (cluster.hasAttribute(nameOrID)) {
427
+ const attribute = cluster.getAttribute(nameOrID);
428
+ payload.push({ attrId: attribute.ID, status: value.status });
429
+ }
430
+ else if (!isNaN(Number(nameOrID))) {
431
+ payload.push({ attrId: Number(nameOrID), status: value.status });
432
+ }
433
+ else {
434
+ throw new Error(`Unknown attribute '${nameOrID}', specify either an existing attribute or a number`);
435
+ }
436
+ }
437
+ else {
438
+ throw new Error(`Missing attribute 'status'`);
439
+ }
440
+ }
441
+ const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, transactionSequenceNumber, 'writeRsp', cluster.ID, payload, options.reservedBits);
442
+ const log = `WriteResponse ${this.deviceIeeeAddress}/${this.ID} ` +
443
+ `${cluster.name}(${JSON.stringify(attributes)}, ${JSON.stringify(options)})`;
444
+ debug.info(log);
445
+ try {
446
+ await this.sendRequest(frame, options);
447
+ }
448
+ catch (error) {
449
+ error.message = `${log} failed (${error.message})`;
450
+ debug.error(error.message);
451
+ throw error;
452
+ }
453
+ }
454
+ async read(clusterKey, attributes, options) {
455
+ var _a;
456
+ const cluster = Zcl.Utils.getCluster(clusterKey);
457
+ options = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
458
+ const payload = [];
459
+ for (const attribute of attributes) {
460
+ payload.push({
461
+ attrId: typeof attribute === 'number'
462
+ ? attribute
463
+ : cluster.getAttribute(attribute).ID,
464
+ });
465
+ }
466
+ const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, (_a = options.transactionSequenceNumber) !== null && _a !== void 0 ? _a : zclTransactionSequenceNumber_1.default.next(), 'read', cluster.ID, payload, options.reservedBits);
467
+ const log = `Read ${this.deviceIeeeAddress}/${this.ID} ` +
468
+ `${cluster.name}(${JSON.stringify(attributes)}, ${JSON.stringify(options)})`;
469
+ debug.info(log);
470
+ try {
471
+ const result = await this.sendRequest(frame, options);
472
+ if (!options.disableResponse) {
473
+ this.checkStatus(result.frame.Payload);
474
+ return ZclFrameConverter.attributeKeyValue(result.frame);
475
+ }
476
+ else {
477
+ return null;
478
+ }
479
+ }
480
+ catch (error) {
481
+ error.message = `${log} failed (${error.message})`;
482
+ debug.error(error.message);
483
+ throw error;
484
+ }
485
+ }
486
+ async readResponse(clusterKey, transactionSequenceNumber, attributes, options) {
487
+ (0, assert_1.default)(!options || !options.hasOwnProperty('transactionSequenceNumber'), 'Use parameter');
488
+ const cluster = Zcl.Utils.getCluster(clusterKey);
489
+ options = this.getOptionsWithDefaults(options, true, Zcl.Direction.SERVER_TO_CLIENT, cluster.manufacturerCode);
490
+ const payload = [];
491
+ for (const [nameOrID, value] of Object.entries(attributes)) {
492
+ if (cluster.hasAttribute(nameOrID)) {
493
+ const attribute = cluster.getAttribute(nameOrID);
494
+ payload.push({
495
+ attrId: attribute.ID,
496
+ attrData: value,
497
+ dataType: attribute.type,
498
+ status: 0,
499
+ });
500
+ }
501
+ else if (!isNaN(Number(nameOrID))) {
502
+ payload.push({
503
+ attrId: Number(nameOrID),
504
+ attrData: value.value,
505
+ dataType: value.type,
506
+ status: 0,
507
+ });
508
+ }
509
+ else {
510
+ throw new Error(`Unknown attribute '${nameOrID}', specify either an existing attribute or a number`);
511
+ }
512
+ }
513
+ const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, transactionSequenceNumber, 'readRsp', cluster.ID, payload, options.reservedBits);
514
+ const log = `ReadResponse ${this.deviceIeeeAddress}/${this.ID} ` +
515
+ `${cluster.name}(${JSON.stringify(attributes)}, ${JSON.stringify(options)})`;
516
+ debug.info(log);
517
+ try {
518
+ await this.sendRequest(frame, options);
519
+ }
520
+ catch (error) {
521
+ error.message = `${log} failed (${error.message})`;
522
+ debug.error(error.message);
523
+ throw error;
524
+ }
525
+ }
526
+ addBinding(clusterKey, target) {
527
+ const cluster = Zcl.Utils.getCluster(clusterKey);
528
+ if (typeof target === 'number') {
529
+ target =
530
+ group_1.default.byGroupID(target, this.databaseID) ||
531
+ group_1.default.create(target, this.databaseID);
532
+ }
533
+ if (!this.binds.find((b) => b.cluster.ID === cluster.ID && b.target === target)) {
534
+ if (target instanceof group_1.default) {
535
+ this._binds.push({
536
+ cluster: cluster.ID,
537
+ groupID: target.groupID,
538
+ type: 'group',
539
+ });
540
+ }
541
+ else {
542
+ this._binds.push({
543
+ cluster: cluster.ID,
544
+ type: 'endpoint',
545
+ deviceIeeeAddress: target.deviceIeeeAddress,
546
+ endpointID: target.ID,
547
+ });
548
+ }
549
+ this.save();
550
+ }
551
+ }
552
+ async bind(clusterKey, target) {
553
+ const cluster = Zcl.Utils.getCluster(clusterKey);
554
+ const type = target instanceof Endpoint ? 'endpoint' : 'group';
555
+ if (typeof target === 'number') {
556
+ target =
557
+ group_1.default.byGroupID(target, this.databaseID) ||
558
+ group_1.default.create(target, this.databaseID);
559
+ }
560
+ const destinationAddress = target instanceof Endpoint ? target.deviceIeeeAddress : target.groupID;
561
+ const log = `Bind ${this.deviceIeeeAddress}/${this.ID} ${cluster.name} from ` +
562
+ `'${target instanceof Endpoint
563
+ ? `${destinationAddress}/${target.ID}`
564
+ : destinationAddress}'`;
565
+ debug.info(log);
566
+ try {
567
+ await entity_1.default.getAdapterByID(this.databaseID).bind(this.deviceNetworkAddress, this.deviceIeeeAddress, this.ID, cluster.ID, destinationAddress, type, target instanceof Endpoint ? target.ID : null);
568
+ this.addBinding(clusterKey, target);
569
+ }
570
+ catch (error) {
571
+ error.message = `${log} failed (${error.message})`;
572
+ debug.error(error.message);
573
+ throw error;
574
+ }
575
+ }
576
+ save() {
577
+ this.getDevice().save();
578
+ }
579
+ async unbind(clusterKey, target) {
580
+ const cluster = Zcl.Utils.getCluster(clusterKey);
581
+ const type = target instanceof Endpoint ? 'endpoint' : 'group';
582
+ const destinationAddress = target instanceof Endpoint
583
+ ? target.deviceIeeeAddress
584
+ : target instanceof group_1.default
585
+ ? target.groupID
586
+ : target;
587
+ const log = `Unbind ${this.deviceIeeeAddress}/${this.ID} ${cluster.name} from ` +
588
+ `'${target instanceof Endpoint
589
+ ? `${destinationAddress}/${target.ID}`
590
+ : destinationAddress}'`;
591
+ debug.info(log);
592
+ try {
593
+ await entity_1.default.getAdapterByID(this.databaseID).unbind(this.deviceNetworkAddress, this.deviceIeeeAddress, this.ID, cluster.ID, destinationAddress, type, target instanceof Endpoint ? target.ID : null);
594
+ if (typeof target === 'number' &&
595
+ group_1.default.byGroupID(target, this.databaseID)) {
596
+ target = group_1.default.byGroupID(target, this.databaseID);
597
+ }
598
+ const index = this.binds.findIndex((b) => b.cluster.ID === cluster.ID && b.target === target);
599
+ if (index !== -1) {
600
+ this._binds.splice(index, 1);
601
+ this.save();
602
+ }
603
+ }
604
+ catch (error) {
605
+ error.message = `${log} failed (${error.message})`;
606
+ debug.error(error.message);
607
+ throw error;
608
+ }
609
+ }
610
+ async defaultResponse(commandID, status, clusterID, transactionSequenceNumber, options) {
611
+ (0, assert_1.default)(!options || !options.hasOwnProperty('transactionSequenceNumber'), 'Use parameter');
612
+ options = this.getOptionsWithDefaults(options, true, Zcl.Direction.SERVER_TO_CLIENT, null);
613
+ const payload = { cmdId: commandID, statusCode: status };
614
+ const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, transactionSequenceNumber, 'defaultRsp', clusterID, payload, options.reservedBits);
615
+ const log = `DefaultResponse ${this.deviceIeeeAddress}/${this.ID} ` +
616
+ `${clusterID}(${commandID}, ${JSON.stringify(options)})`;
617
+ debug.info(log);
618
+ try {
619
+ await this.sendRequest(frame, options);
620
+ }
621
+ catch (error) {
622
+ error.message = `${log} failed (${error.message})`;
623
+ debug.error(error.message);
624
+ throw error;
625
+ }
626
+ }
627
+ async configureReporting(clusterKey, items, options) {
628
+ var _a;
629
+ const cluster = Zcl.Utils.getCluster(clusterKey);
630
+ options = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
631
+ const payload = items.map((item) => {
632
+ let dataType, attrId;
633
+ if (typeof item.attribute === 'object') {
634
+ dataType = item.attribute.type;
635
+ attrId = item.attribute.ID;
636
+ }
637
+ else {
638
+ /* istanbul ignore else */
639
+ if (cluster.hasAttribute(item.attribute)) {
640
+ const attribute = cluster.getAttribute(item.attribute);
641
+ dataType = attribute.type;
642
+ attrId = attribute.ID;
643
+ }
644
+ }
645
+ return {
646
+ direction: Zcl.Direction.CLIENT_TO_SERVER,
647
+ attrId,
648
+ dataType,
649
+ minRepIntval: item.minimumReportInterval,
650
+ maxRepIntval: item.maximumReportInterval,
651
+ repChange: item.reportableChange,
652
+ };
653
+ });
654
+ const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, (_a = options.transactionSequenceNumber) !== null && _a !== void 0 ? _a : zclTransactionSequenceNumber_1.default.next(), 'configReport', cluster.ID, payload, options.reservedBits);
655
+ const log = `ConfigureReporting ${this.deviceIeeeAddress}/${this.ID} ` +
656
+ `${cluster.name}(${JSON.stringify(items)}, ${JSON.stringify(options)})`;
657
+ debug.info(log);
658
+ try {
659
+ const result = await this.sendRequest(frame, options);
660
+ if (!options.disableResponse) {
661
+ this.checkStatus(result.frame.Payload);
662
+ }
663
+ for (const e of payload) {
664
+ const match = this._configuredReportings.find((c) => c.attrId === e.attrId && c.cluster === cluster.ID);
665
+ if (match) {
666
+ this._configuredReportings.splice(this._configuredReportings.indexOf(match), 1);
667
+ }
668
+ }
669
+ for (const entry of payload) {
670
+ if (entry.maxRepIntval !== 0xffff) {
671
+ this._configuredReportings.push({
672
+ cluster: cluster.ID,
673
+ attrId: entry.attrId,
674
+ minRepIntval: entry.minRepIntval,
675
+ maxRepIntval: entry.maxRepIntval,
676
+ repChange: entry.repChange,
677
+ });
678
+ }
679
+ }
680
+ this.save();
681
+ }
682
+ catch (error) {
683
+ error.message = `${log} failed (${error.message})`;
684
+ debug.error(error.message);
685
+ throw error;
686
+ }
687
+ }
688
+ async writeStructured(clusterKey, payload, options) {
689
+ var _a;
690
+ const cluster = Zcl.Utils.getCluster(clusterKey);
691
+ options = this.getOptionsWithDefaults(options, true, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
692
+ const frame = Zcl.ZclFrame.create(Zcl.FrameType.GLOBAL, options.direction, options.disableDefaultResponse, options.manufacturerCode, (_a = options.transactionSequenceNumber) !== null && _a !== void 0 ? _a : zclTransactionSequenceNumber_1.default.next(), `writeStructured`, cluster.ID, payload, options.reservedBits);
693
+ const log = `WriteStructured ${this.deviceIeeeAddress}/${this.ID} ` +
694
+ `${cluster.name}(${JSON.stringify(payload)}, ${JSON.stringify(options)})`;
695
+ debug.info(log);
696
+ try {
697
+ await this.sendRequest(frame, options);
698
+ // TODO: support `writeStructuredResponse`
699
+ }
700
+ catch (error) {
701
+ error.message = `${log} failed (${error.message})`;
702
+ debug.error(error.message);
703
+ throw error;
704
+ }
705
+ }
706
+ async command(clusterKey, commandKey, payload, options) {
707
+ var _a;
708
+ const cluster = Zcl.Utils.getCluster(clusterKey);
709
+ const command = cluster.getCommand(commandKey);
710
+ const hasResponse = command.hasOwnProperty('response');
711
+ options = this.getOptionsWithDefaults(options, hasResponse, Zcl.Direction.CLIENT_TO_SERVER, cluster.manufacturerCode);
712
+ const frame = Zcl.ZclFrame.create(Zcl.FrameType.SPECIFIC, options.direction, options.disableDefaultResponse, options.manufacturerCode, (_a = options.transactionSequenceNumber) !== null && _a !== void 0 ? _a : zclTransactionSequenceNumber_1.default.next(), command.name, cluster.name, payload, options.reservedBits);
713
+ const log = `Command ${this.deviceIeeeAddress}/${this.ID} ` +
714
+ `${cluster.name}.${command.name}(${JSON.stringify(payload)}, ${JSON.stringify(options)})`;
715
+ debug.info(log);
716
+ try {
717
+ const result = await this.sendRequest(frame, options);
718
+ if (result) {
719
+ return result.frame.Payload;
720
+ }
721
+ }
722
+ catch (error) {
723
+ error.message = `${log} failed (${error.message})`;
724
+ debug.error(error.message);
725
+ throw error;
726
+ }
727
+ }
728
+ async commandResponse(clusterKey, commandKey, payload, options, transactionSequenceNumber) {
729
+ (0, assert_1.default)(!options || !options.hasOwnProperty('transactionSequenceNumber'), 'Use parameter');
730
+ const cluster = Zcl.Utils.getCluster(clusterKey);
731
+ const command = cluster.getCommandResponse(commandKey);
732
+ transactionSequenceNumber =
733
+ transactionSequenceNumber || zclTransactionSequenceNumber_1.default.next();
734
+ options = this.getOptionsWithDefaults(options, true, Zcl.Direction.SERVER_TO_CLIENT, cluster.manufacturerCode);
735
+ const frame = Zcl.ZclFrame.create(Zcl.FrameType.SPECIFIC, options.direction, options.disableDefaultResponse, options.manufacturerCode, transactionSequenceNumber, command.name, cluster.name, payload, options.reservedBits);
736
+ const log = `CommandResponse ${this.deviceIeeeAddress}/${this.ID} ` +
737
+ `${cluster.name}.${command.name}(${JSON.stringify(payload)}, ${JSON.stringify(options)})`;
738
+ debug.info(log);
739
+ try {
740
+ await this.sendRequest(frame, options, async (f) => {
741
+ // Broadcast Green Power responses
742
+ if (this.ID === 242) {
743
+ await entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToAll(242, f, 242);
744
+ }
745
+ else {
746
+ await entity_1.default.getAdapterByID(this.databaseID).sendZclFrameToEndpoint(this.deviceIeeeAddress, this.deviceNetworkAddress, this.ID, f, options.timeout, options.disableResponse, options.disableRecovery, options.srcEndpoint);
747
+ }
748
+ });
749
+ }
750
+ catch (error) {
751
+ error.message = `${log} failed (${error.message})`;
752
+ debug.error(error.message);
753
+ throw error;
754
+ }
755
+ }
756
+ waitForCommand(clusterKey, commandKey, transactionSequenceNumber, timeout) {
757
+ const cluster = Zcl.Utils.getCluster(clusterKey);
758
+ const command = cluster.getCommand(commandKey);
759
+ const waiter = entity_1.default.getAdapterByID(this.databaseID).waitFor(this.deviceNetworkAddress, this.ID, Zcl.FrameType.SPECIFIC, Zcl.Direction.CLIENT_TO_SERVER, transactionSequenceNumber, cluster.ID, command.ID, timeout);
760
+ const promise = new Promise((resolve, reject) => {
761
+ waiter.promise.then((payload) => resolve({
762
+ header: payload.frame.Header,
763
+ payload: payload.frame.Payload,
764
+ }), (error) => reject(error));
765
+ });
766
+ return { promise, cancel: waiter.cancel };
767
+ }
768
+ getOptionsWithDefaults(options, disableDefaultResponse, direction, manufacturerCode) {
769
+ const providedOptions = options || {};
770
+ return {
771
+ sendWhen: this.getDevice().defaultSendRequestWhen,
772
+ timeout: 10000,
773
+ disableResponse: false,
774
+ disableRecovery: false,
775
+ disableDefaultResponse,
776
+ direction,
777
+ srcEndpoint: null,
778
+ reservedBits: 0,
779
+ manufacturerCode: manufacturerCode ? manufacturerCode : null,
780
+ transactionSequenceNumber: null,
781
+ writeUndiv: false,
782
+ ...providedOptions,
783
+ };
784
+ }
785
+ async addToGroup(group) {
786
+ await this.command('genGroups', 'add', {
787
+ groupid: group.groupID,
788
+ groupname: '',
789
+ });
790
+ group.addMember(this);
791
+ }
792
+ /**
793
+ * Remove endpoint from a group, accepts both a Group and number as parameter.
794
+ * The number parameter type should only be used when removing from a group which is not known
795
+ * to zigbee-herdsman.
796
+ */
797
+ async removeFromGroup(group) {
798
+ await this.command('genGroups', 'remove', {
799
+ groupid: group instanceof group_1.default ? group.groupID : group,
800
+ });
801
+ if (group instanceof group_1.default) {
802
+ group.removeMember(this);
803
+ }
804
+ }
805
+ async removeFromAllGroups() {
806
+ await this.command('genGroups', 'removeAll', {}, { disableDefaultResponse: true });
807
+ this.removeFromAllGroupsDatabase();
808
+ }
809
+ removeFromAllGroupsDatabase() {
810
+ for (const group of group_1.default.allByDatabaseID(this.databaseID)) {
811
+ if (group.hasMember(this)) {
812
+ group.removeMember(this);
813
+ }
814
+ }
815
+ }
816
+ }
817
+ exports.default = Endpoint;
666
818
  //# sourceMappingURL=endpoint.js.map