zigbee-herdsman 6.0.1 → 6.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/adapter/ezsp/driver/uart.js +1 -1
  3. package/dist/adapter/ezsp/driver/uart.js.map +1 -1
  4. package/dist/adapter/z-stack/adapter/zStackAdapter.js +4 -4
  5. package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +1 -1
  6. package/dist/adapter/zigate/adapter/zigateAdapter.js +4 -4
  7. package/dist/adapter/zigate/adapter/zigateAdapter.js.map +1 -1
  8. package/dist/controller/model/device.d.ts.map +1 -1
  9. package/dist/controller/model/device.js +1 -0
  10. package/dist/controller/model/device.js.map +1 -1
  11. package/package.json +14 -6
  12. package/.github/ISSUE_TEMPLATE/config.yml +0 -5
  13. package/.github/dependabot.yml +0 -22
  14. package/.github/workflows/ci.yml +0 -64
  15. package/.github/workflows/release-please.yml +0 -18
  16. package/.github/workflows/stale.yml +0 -20
  17. package/.github/workflows/typedoc.yaml +0 -47
  18. package/.release-please-manifest.json +0 -3
  19. package/.vscode/extensions.json +0 -3
  20. package/.vscode/settings.json +0 -11
  21. package/biome.json +0 -98
  22. package/examples/join-and-log.js +0 -24
  23. package/release-please-config.json +0 -9
  24. package/src/adapter/adapter.ts +0 -189
  25. package/src/adapter/adapterDiscovery.ts +0 -666
  26. package/src/adapter/const.ts +0 -12
  27. package/src/adapter/deconz/adapter/deconzAdapter.ts +0 -877
  28. package/src/adapter/deconz/driver/constants.ts +0 -246
  29. package/src/adapter/deconz/driver/driver.ts +0 -1540
  30. package/src/adapter/deconz/driver/frame.ts +0 -11
  31. package/src/adapter/deconz/driver/frameParser.ts +0 -753
  32. package/src/adapter/deconz/driver/parser.ts +0 -45
  33. package/src/adapter/deconz/driver/writer.ts +0 -22
  34. package/src/adapter/deconz/types.d.ts +0 -13
  35. package/src/adapter/ember/adapter/emberAdapter.ts +0 -2265
  36. package/src/adapter/ember/adapter/endpoints.ts +0 -86
  37. package/src/adapter/ember/adapter/oneWaitress.ts +0 -324
  38. package/src/adapter/ember/adapter/tokensManager.ts +0 -782
  39. package/src/adapter/ember/consts.ts +0 -178
  40. package/src/adapter/ember/enums.ts +0 -1746
  41. package/src/adapter/ember/ezsp/buffalo.ts +0 -1392
  42. package/src/adapter/ember/ezsp/consts.ts +0 -148
  43. package/src/adapter/ember/ezsp/enums.ts +0 -1114
  44. package/src/adapter/ember/ezsp/ezsp.ts +0 -9061
  45. package/src/adapter/ember/ezspError.ts +0 -10
  46. package/src/adapter/ember/types.ts +0 -866
  47. package/src/adapter/ember/uart/ash.ts +0 -1960
  48. package/src/adapter/ember/uart/consts.ts +0 -109
  49. package/src/adapter/ember/uart/enums.ts +0 -192
  50. package/src/adapter/ember/uart/parser.ts +0 -48
  51. package/src/adapter/ember/uart/queues.ts +0 -247
  52. package/src/adapter/ember/uart/writer.ts +0 -53
  53. package/src/adapter/ember/utils/initters.ts +0 -58
  54. package/src/adapter/ember/utils/math.ts +0 -73
  55. package/src/adapter/events.ts +0 -21
  56. package/src/adapter/ezsp/adapter/backup.ts +0 -109
  57. package/src/adapter/ezsp/adapter/ezspAdapter.ts +0 -614
  58. package/src/adapter/ezsp/driver/commands.ts +0 -2497
  59. package/src/adapter/ezsp/driver/consts.ts +0 -11
  60. package/src/adapter/ezsp/driver/driver.ts +0 -1002
  61. package/src/adapter/ezsp/driver/ezsp.ts +0 -802
  62. package/src/adapter/ezsp/driver/frame.ts +0 -101
  63. package/src/adapter/ezsp/driver/index.ts +0 -4
  64. package/src/adapter/ezsp/driver/multicast.ts +0 -78
  65. package/src/adapter/ezsp/driver/parser.ts +0 -81
  66. package/src/adapter/ezsp/driver/types/basic.ts +0 -201
  67. package/src/adapter/ezsp/driver/types/index.ts +0 -239
  68. package/src/adapter/ezsp/driver/types/named.ts +0 -2330
  69. package/src/adapter/ezsp/driver/types/struct.ts +0 -844
  70. package/src/adapter/ezsp/driver/uart.ts +0 -460
  71. package/src/adapter/ezsp/driver/utils/crc16ccitt.ts +0 -44
  72. package/src/adapter/ezsp/driver/utils/index.ts +0 -32
  73. package/src/adapter/ezsp/driver/writer.ts +0 -64
  74. package/src/adapter/index.ts +0 -3
  75. package/src/adapter/serialPort.ts +0 -58
  76. package/src/adapter/socketPortUtils.ts +0 -16
  77. package/src/adapter/tstype.ts +0 -78
  78. package/src/adapter/z-stack/adapter/adapter-backup.ts +0 -519
  79. package/src/adapter/z-stack/adapter/adapter-nv-memory.ts +0 -457
  80. package/src/adapter/z-stack/adapter/endpoints.ts +0 -57
  81. package/src/adapter/z-stack/adapter/manager.ts +0 -543
  82. package/src/adapter/z-stack/adapter/tstype.ts +0 -6
  83. package/src/adapter/z-stack/adapter/zStackAdapter.ts +0 -1190
  84. package/src/adapter/z-stack/constants/af.ts +0 -27
  85. package/src/adapter/z-stack/constants/common.ts +0 -285
  86. package/src/adapter/z-stack/constants/dbg.ts +0 -23
  87. package/src/adapter/z-stack/constants/index.ts +0 -11
  88. package/src/adapter/z-stack/constants/mac.ts +0 -128
  89. package/src/adapter/z-stack/constants/sapi.ts +0 -25
  90. package/src/adapter/z-stack/constants/sys.ts +0 -72
  91. package/src/adapter/z-stack/constants/util.ts +0 -82
  92. package/src/adapter/z-stack/constants/utils.ts +0 -14
  93. package/src/adapter/z-stack/constants/zdo.ts +0 -103
  94. package/src/adapter/z-stack/models/startup-options.ts +0 -13
  95. package/src/adapter/z-stack/structs/entries/address-manager-entry.ts +0 -44
  96. package/src/adapter/z-stack/structs/entries/address-manager-table.ts +0 -19
  97. package/src/adapter/z-stack/structs/entries/aps-link-key-data-entry.ts +0 -12
  98. package/src/adapter/z-stack/structs/entries/aps-link-key-data-table.ts +0 -21
  99. package/src/adapter/z-stack/structs/entries/aps-tc-link-key-entry.ts +0 -19
  100. package/src/adapter/z-stack/structs/entries/aps-tc-link-key-table.ts +0 -21
  101. package/src/adapter/z-stack/structs/entries/channel-list.ts +0 -8
  102. package/src/adapter/z-stack/structs/entries/has-configured.ts +0 -16
  103. package/src/adapter/z-stack/structs/entries/index.ts +0 -16
  104. package/src/adapter/z-stack/structs/entries/nib.ts +0 -66
  105. package/src/adapter/z-stack/structs/entries/nwk-key-descriptor.ts +0 -15
  106. package/src/adapter/z-stack/structs/entries/nwk-key.ts +0 -13
  107. package/src/adapter/z-stack/structs/entries/nwk-pan-id.ts +0 -8
  108. package/src/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.ts +0 -20
  109. package/src/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.ts +0 -19
  110. package/src/adapter/z-stack/structs/entries/security-manager-entry.ts +0 -33
  111. package/src/adapter/z-stack/structs/entries/security-manager-table.ts +0 -22
  112. package/src/adapter/z-stack/structs/index.ts +0 -4
  113. package/src/adapter/z-stack/structs/serializable-memory-object.ts +0 -14
  114. package/src/adapter/z-stack/structs/struct.ts +0 -367
  115. package/src/adapter/z-stack/structs/table.ts +0 -198
  116. package/src/adapter/z-stack/unpi/constants.ts +0 -33
  117. package/src/adapter/z-stack/unpi/frame.ts +0 -62
  118. package/src/adapter/z-stack/unpi/index.ts +0 -4
  119. package/src/adapter/z-stack/unpi/parser.ts +0 -56
  120. package/src/adapter/z-stack/unpi/writer.ts +0 -21
  121. package/src/adapter/z-stack/utils/channel-list.ts +0 -40
  122. package/src/adapter/z-stack/utils/index.ts +0 -2
  123. package/src/adapter/z-stack/utils/network-options.ts +0 -26
  124. package/src/adapter/z-stack/znp/buffaloZnp.ts +0 -175
  125. package/src/adapter/z-stack/znp/definition.ts +0 -2713
  126. package/src/adapter/z-stack/znp/index.ts +0 -2
  127. package/src/adapter/z-stack/znp/parameterType.ts +0 -22
  128. package/src/adapter/z-stack/znp/tstype.ts +0 -44
  129. package/src/adapter/z-stack/znp/utils.ts +0 -10
  130. package/src/adapter/z-stack/znp/znp.ts +0 -342
  131. package/src/adapter/z-stack/znp/zpiObject.ts +0 -148
  132. package/src/adapter/zboss/adapter/zbossAdapter.ts +0 -526
  133. package/src/adapter/zboss/commands.ts +0 -1184
  134. package/src/adapter/zboss/consts.ts +0 -9
  135. package/src/adapter/zboss/driver.ts +0 -422
  136. package/src/adapter/zboss/enums.ts +0 -360
  137. package/src/adapter/zboss/frame.ts +0 -227
  138. package/src/adapter/zboss/reader.ts +0 -65
  139. package/src/adapter/zboss/types.ts +0 -0
  140. package/src/adapter/zboss/uart.ts +0 -428
  141. package/src/adapter/zboss/utils.ts +0 -58
  142. package/src/adapter/zboss/writer.ts +0 -49
  143. package/src/adapter/zigate/adapter/patchZdoBuffaloBE.ts +0 -27
  144. package/src/adapter/zigate/adapter/zigateAdapter.ts +0 -618
  145. package/src/adapter/zigate/driver/LICENSE +0 -17
  146. package/src/adapter/zigate/driver/buffaloZiGate.ts +0 -212
  147. package/src/adapter/zigate/driver/commandType.ts +0 -418
  148. package/src/adapter/zigate/driver/constants.ts +0 -150
  149. package/src/adapter/zigate/driver/frame.ts +0 -197
  150. package/src/adapter/zigate/driver/messageType.ts +0 -287
  151. package/src/adapter/zigate/driver/parameterType.ts +0 -32
  152. package/src/adapter/zigate/driver/ziGateObject.ts +0 -146
  153. package/src/adapter/zigate/driver/zigate.ts +0 -423
  154. package/src/adapter/zoh/adapter/utils.ts +0 -27
  155. package/src/adapter/zoh/adapter/zohAdapter.ts +0 -838
  156. package/src/buffalo/buffalo.ts +0 -342
  157. package/src/buffalo/index.ts +0 -1
  158. package/src/controller/controller.ts +0 -1022
  159. package/src/controller/database.ts +0 -124
  160. package/src/controller/events.ts +0 -52
  161. package/src/controller/greenPower.ts +0 -603
  162. package/src/controller/helpers/index.ts +0 -1
  163. package/src/controller/helpers/installCodes.ts +0 -107
  164. package/src/controller/helpers/request.ts +0 -96
  165. package/src/controller/helpers/requestQueue.ts +0 -125
  166. package/src/controller/helpers/zclFrameConverter.ts +0 -47
  167. package/src/controller/helpers/zclTransactionSequenceNumber.ts +0 -19
  168. package/src/controller/index.ts +0 -6
  169. package/src/controller/model/device.ts +0 -1248
  170. package/src/controller/model/endpoint.ts +0 -1105
  171. package/src/controller/model/entity.ts +0 -23
  172. package/src/controller/model/group.ts +0 -424
  173. package/src/controller/model/index.ts +0 -5
  174. package/src/controller/model/zigbeeEntity.ts +0 -30
  175. package/src/controller/touchlink.ts +0 -189
  176. package/src/controller/tstype.ts +0 -274
  177. package/src/index.ts +0 -12
  178. package/src/models/backup-storage-legacy.ts +0 -48
  179. package/src/models/backup-storage-unified.ts +0 -47
  180. package/src/models/backup.ts +0 -37
  181. package/src/models/index.ts +0 -5
  182. package/src/models/network-options.ts +0 -11
  183. package/src/utils/backup.ts +0 -152
  184. package/src/utils/index.ts +0 -5
  185. package/src/utils/logger.ts +0 -20
  186. package/src/utils/patchBigIntSerialization.ts +0 -8
  187. package/src/utils/queue.ts +0 -76
  188. package/src/utils/types.d.ts +0 -3
  189. package/src/utils/utils.ts +0 -19
  190. package/src/utils/wait.ts +0 -5
  191. package/src/utils/waitress.ts +0 -96
  192. package/src/zspec/consts.ts +0 -84
  193. package/src/zspec/enums.ts +0 -22
  194. package/src/zspec/index.ts +0 -3
  195. package/src/zspec/tstypes.ts +0 -18
  196. package/src/zspec/utils.ts +0 -247
  197. package/src/zspec/zcl/buffaloZcl.ts +0 -1220
  198. package/src/zspec/zcl/definition/cluster.ts +0 -5915
  199. package/src/zspec/zcl/definition/clusters-typegen.ts +0 -588
  200. package/src/zspec/zcl/definition/clusters-types.ts +0 -7331
  201. package/src/zspec/zcl/definition/consts.ts +0 -24
  202. package/src/zspec/zcl/definition/enums.ts +0 -203
  203. package/src/zspec/zcl/definition/foundation.ts +0 -329
  204. package/src/zspec/zcl/definition/manufacturerCode.ts +0 -729
  205. package/src/zspec/zcl/definition/status.ts +0 -69
  206. package/src/zspec/zcl/definition/tstype.ts +0 -377
  207. package/src/zspec/zcl/index.ts +0 -11
  208. package/src/zspec/zcl/utils.ts +0 -321
  209. package/src/zspec/zcl/zclFrame.ts +0 -356
  210. package/src/zspec/zcl/zclHeader.ts +0 -102
  211. package/src/zspec/zcl/zclStatusError.ts +0 -10
  212. package/src/zspec/zdo/buffaloZdo.ts +0 -2336
  213. package/src/zspec/zdo/definition/clusters.ts +0 -722
  214. package/src/zspec/zdo/definition/consts.ts +0 -16
  215. package/src/zspec/zdo/definition/enums.ts +0 -99
  216. package/src/zspec/zdo/definition/status.ts +0 -105
  217. package/src/zspec/zdo/definition/tstypes.ts +0 -1062
  218. package/src/zspec/zdo/index.ts +0 -7
  219. package/src/zspec/zdo/utils.ts +0 -76
  220. package/src/zspec/zdo/zdoStatusError.ts +0 -10
  221. package/test/adapter/adapter.test.ts +0 -1062
  222. package/test/adapter/ember/ash.test.ts +0 -337
  223. package/test/adapter/ember/consts.ts +0 -131
  224. package/test/adapter/ember/emberAdapter.test.ts +0 -3449
  225. package/test/adapter/ember/ezsp.test.ts +0 -385
  226. package/test/adapter/ember/ezspBuffalo.test.ts +0 -93
  227. package/test/adapter/ember/ezspError.test.ts +0 -12
  228. package/test/adapter/ember/math.test.ts +0 -206
  229. package/test/adapter/ezsp/frame.test.ts +0 -30
  230. package/test/adapter/ezsp/uart.test.ts +0 -181
  231. package/test/adapter/z-stack/adapter.test.ts +0 -3984
  232. package/test/adapter/z-stack/constants.test.ts +0 -33
  233. package/test/adapter/z-stack/structs.test.ts +0 -115
  234. package/test/adapter/z-stack/unpi.test.ts +0 -213
  235. package/test/adapter/z-stack/znp.test.ts +0 -1284
  236. package/test/adapter/zboss/fixZdoResponse.test.ts +0 -179
  237. package/test/adapter/zigate/patchZdoBuffaloBE.test.ts +0 -81
  238. package/test/adapter/zigate/zdo.test.ts +0 -187
  239. package/test/adapter/zoh/utils.test.ts +0 -36
  240. package/test/adapter/zoh/zohAdapter.test.ts +0 -1307
  241. package/test/buffalo.test.ts +0 -431
  242. package/test/controller.bench.ts +0 -193
  243. package/test/controller.test.ts +0 -8702
  244. package/test/greenpower.test.ts +0 -1408
  245. package/test/mockAdapters.ts +0 -65
  246. package/test/mockDevices.ts +0 -598
  247. package/test/requests.bench.ts +0 -206
  248. package/test/testUtils.ts +0 -20
  249. package/test/tsconfig.json +0 -9
  250. package/test/utils/math.ts +0 -19
  251. package/test/utils.test.ts +0 -279
  252. package/test/vitest.config.mts +0 -27
  253. package/test/zcl.test.ts +0 -2831
  254. package/test/zspec/utils.test.ts +0 -68
  255. package/test/zspec/zcl/buffalo.test.ts +0 -1374
  256. package/test/zspec/zcl/frame.test.ts +0 -960
  257. package/test/zspec/zcl/utils.test.ts +0 -273
  258. package/test/zspec/zdo/buffalo.test.ts +0 -1850
  259. package/test/zspec/zdo/utils.test.ts +0 -241
  260. package/tsconfig.json +0 -24
@@ -1,666 +0,0 @@
1
- import assert from "node:assert";
2
- import {platform} from "node:os";
3
- import type {PortInfo} from "@serialport/bindings-cpp";
4
- import {Bonjour, type Service} from "bonjour-service";
5
- import {wait} from "../utils";
6
- import {logger} from "../utils/logger";
7
- import {SerialPort} from "./serialPort";
8
- import type {Adapter, DiscoverableUsbAdapter, UsbAdapterFingerprint} from "./tstype";
9
-
10
- const NS = "zh:adapter:discovery";
11
-
12
- const enum UsbFingerprintMatchScore {
13
- None = 0,
14
- VidPid = 1,
15
- VidPidManuf = 2,
16
- VidPidPath = 3,
17
- VidPidManufPath = 4,
18
- }
19
-
20
- /**
21
- * @see https://serialport.io/docs/api-bindings-cpp#list
22
- *
23
- * On Windows, there are occurrences where `manufacturer` is replaced by the OS driver. Example: `ITEAD` => `wch.cn`.
24
- *
25
- * In virtualized environments, the passthrough mechanism can affect the `path`.
26
- * Example:
27
- * Linux: /dev/serial/by-id/usb-ITEAD_SONOFF_Zigbee_3.0_USB_Dongle_Plus_V2_20240122184111-if00
28
- * Windows host => Linux guest: /dev/serial/by-id/usb-1a86_USB_Single_Serial_54DD002111-if00
29
- *
30
- * XXX: vendorId `10c4` + productId `ea60` is a problem on Windows since can't match `path` and possibly can't match `manufacturer` to refine properly
31
- */
32
- const USB_FINGERPRINTS: Record<DiscoverableUsbAdapter, UsbAdapterFingerprint[]> = {
33
- deconz: [
34
- {
35
- // Conbee II
36
- vendorId: "1cf1",
37
- productId: "0030",
38
- manufacturer: "dresden elektronik ingenieurtechnik GmbH",
39
- // /dev/serial/by-id/usb-dresden_elektronik_ingenieurtechnik_GmbH_ConBee_II_DE2132111-if00
40
- pathRegex: ".*conbee.*",
41
- },
42
- {
43
- // Conbee III
44
- vendorId: "0403",
45
- productId: "6015",
46
- manufacturer: "dresden elektronik ingenieurtechnik GmbH",
47
- // /dev/serial/by-id/usb-dresden_elektronik_ConBee_III_DE03188111-if00-port0
48
- pathRegex: ".*conbee.*",
49
- },
50
- ],
51
- ember: [
52
- // {
53
- // // TODO: Easyiot ZB-GW04 (v1.1)
54
- // vendorId: '',
55
- // productId: '',
56
- // manufacturer: '',
57
- // pathRegex: '.*.*',
58
- // },
59
- // {
60
- // // TODO: Easyiot ZB-GW04 (v1.2)
61
- // vendorId: '1a86',
62
- // productId: '',
63
- // manufacturer: '',
64
- // // /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0
65
- // pathRegex: '.*.*',
66
- // },
67
- {
68
- // Home Assistant SkyConnect
69
- vendorId: "10c4",
70
- productId: "ea60",
71
- manufacturer: "Nabu Casa",
72
- // /dev/serial/by-id/usb-Nabu_Casa_SkyConnect_v1.0_3abe54797c91ed118fc3cad13b20a111-if00-port0
73
- pathRegex: ".*Nabu_Casa_SkyConnect.*",
74
- },
75
- // {
76
- // // TODO: Home Assistant Yellow
77
- // vendorId: '',
78
- // productId: '',
79
- // manufacturer: '',
80
- // // /dev/ttyAMA1
81
- // pathRegex: '.*.*',
82
- // },
83
- {
84
- // SMLight slzb-07
85
- vendorId: "10c4",
86
- productId: "ea60",
87
- manufacturer: "SMLIGHT",
88
- // /dev/serial/by-id/usb-SMLIGHT_SMLIGHT_SLZB-07_be9faa0786e1ea11bd68dc2d9a583111-if00-port0
89
- // /dev/serial/by-id/usb-Silicon_Labs_CP2102N_USB_to_UART_Bridge_Controller_a215650c853bec119a079e957a0af111-if00-port0
90
- pathRegex: ".*slzb-07_.*", // `_` to not match 07p7
91
- },
92
- {
93
- // SMLight slzb-07mg24
94
- vendorId: "10c4",
95
- productId: "ea60",
96
- manufacturer: "SMLIGHT",
97
- pathRegex: ".*slzb-07mg24.*",
98
- },
99
- {
100
- // Sonoff ZBDongle-E V2 (CH variant)
101
- vendorId: "1a86",
102
- productId: "55d4",
103
- manufacturer: "ITEAD",
104
- // /dev/serial/by-id/usb-ITEAD_SONOFF_Zigbee_3.0_USB_Dongle_Plus_V2_20240122184111-if00
105
- // /dev/serial/by-id/usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_186ff44314e2ed11b891eb5162c61111-if00-port0
106
- pathRegex: ".*sonoff.*plus.*",
107
- },
108
- {
109
- // Sonoff ZBDongle-E V2 (CP variant)
110
- vendorId: "10c4",
111
- productId: "ea60",
112
- manufacturer: "ITEAD",
113
- // /dev/serial/by-id/usb-Itead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_V2_a6ee897e4d1fef11aa004ad0639e525b-if00-port0
114
- pathRegex: ".*sonoff.*plus_v2_.*",
115
- },
116
- {
117
- // Sonoff ZBDongle-M
118
- vendorId: "10c4",
119
- productId: "ea60",
120
- manufacturer: "SONOFF",
121
- // /dev/serial/by-id/usb-SONOFF_SONOFF_Dongle_Max_MG24_08965d6b0674ef11b2f4e61e313510fd-if00-port0
122
- pathRegex: ".*sonoff.*max.*",
123
- },
124
- {
125
- // SONOFF Dongle Plus MG24
126
- vendorId: "10c4",
127
- productId: "ea60",
128
- manufacturer: "SONOFF",
129
- // /dev/serial/by-id/usb-SONOFF_SONOFF_Dongle_Plus_MG24_b023a583a66bef118e30a3adc169b110-if00-port0
130
- pathRegex: ".*sonoff.*plus.*mg24.*",
131
- },
132
- {
133
- // SONOFF Dongle Lite MG21
134
- vendorId: "10c4",
135
- productId: "ea60",
136
- manufacturer: "SONOFF",
137
- // /dev/serial/by-id/usb-SONOFF_SONOFF_Dongle_Lite_MG21_c82fc0a1a36bef11a026a1adc169b110-if00-port0
138
- pathRegex: ".*sonoff.*lite.*mg21.*",
139
- },
140
- // {
141
- // // TODO: Z-station by z-wave.me (EFR32MG21A020F1024IM32)
142
- // vendorId: '',
143
- // productId: '',
144
- // // manufacturer: '',
145
- // // /dev/serial/by-id/usb-Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_012BA111-if01-port0
146
- // pathRegex: '.*CP2105.*',
147
- // },
148
- ],
149
- zstack: [
150
- {
151
- // ZZH
152
- vendorId: "0403",
153
- productId: "6015",
154
- manufacturer: "Electrolama",
155
- pathRegex: ".*electrolama.*",
156
- },
157
- {
158
- // slae.sh cc2652rb
159
- vendorId: "10c4",
160
- productId: "ea60",
161
- manufacturer: "Silicon Labs",
162
- // /dev/serial/by-id/usb-Silicon_Labs_slae.sh_cc2652rb_stick_-_slaesh_s_iot_stuff_00_12_4B_00_21_A8_EC_79-if00-port0
163
- pathRegex: ".*slae\\.sh_cc2652rb.*",
164
- },
165
- {
166
- // Sonoff ZBDongle-P (CC2652P)
167
- vendorId: "10c4",
168
- productId: "ea60",
169
- manufacturer: "ITEAD",
170
- // /dev/serial/by-id/usb-Silicon_Labs_Sonoff_Zigbee_3.0_USB_Dongle_Plus_0111-if00-port0
171
- // /dev/serial/by-id/usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_b8b49abd27a6ed11a280eba32981d111-if00-port0
172
- pathRegex: ".*sonoff.*plus(?!_v2_).*",
173
- },
174
- {
175
- // CC2538
176
- vendorId: "0451",
177
- productId: "16c8",
178
- manufacturer: "Texas Instruments",
179
- // zStack30x: /dev/serial/by-id/usb-Texas_Instruments_CC2538_USB_CDC-if00
180
- pathRegex: ".*CC2538.*",
181
- },
182
- {
183
- // CC2531
184
- vendorId: "0451",
185
- productId: "16a8",
186
- manufacturer: "Texas Instruments",
187
- // /dev/serial/by-id/usb-Texas_Instruments_TI_CC2531_USB_CDC___0X00124B0018ED1111-if00
188
- pathRegex: ".*CC2531.*",
189
- },
190
- {
191
- // Texas instruments launchpads
192
- vendorId: "0451",
193
- productId: "bef3",
194
- manufacturer: "Texas Instruments",
195
- pathRegex: ".*Texas_Instruments.*",
196
- },
197
- {
198
- // SMLight slzb-07p7
199
- vendorId: "10c4",
200
- productId: "ea60",
201
- manufacturer: "SMLIGHT",
202
- // /dev/serial/by-id/usb-SMLIGHT_SMLIGHT_SLZB-07p7_be9faa0786e1ea11bd68dc2d9a583111-if00-port0
203
- pathRegex: ".*SLZB-07p7.*",
204
- },
205
- {
206
- // SMLight slzb-06p7
207
- vendorId: "10c4",
208
- productId: "ea60",
209
- manufacturer: "SMLIGHT",
210
- // /dev/serial/by-id/usb-SMLIGHT_SMLIGHT_SLZB-06p7_82e43faf9872ed118bb924f3fdf7b791-if00-port0
211
- pathRegex: ".*SMLIGHT_SLZB-06p7_.*",
212
- },
213
- {
214
- // SMLight slzb-06p10
215
- vendorId: "10c4",
216
- productId: "ea60",
217
- manufacturer: "SMLIGHT",
218
- // /dev/serial/by-id/usb-SMLIGHT_SMLIGHT_SLZB-06p10_40df2f3e3977ed11b142f6fafdf7b791-if00-port0
219
- pathRegex: ".*SMLIGHT_SLZB-06p10_.*",
220
- },
221
- {
222
- // TubesZB ?
223
- vendorId: "10c4",
224
- productId: "ea60",
225
- // manufacturer: '',
226
- pathRegex: ".*tubeszb.*",
227
- },
228
- {
229
- // TubesZB ?
230
- vendorId: "1a86",
231
- productId: "7523",
232
- // manufacturer: '',
233
- pathRegex: ".*tubeszb.*",
234
- },
235
- {
236
- // ZigStar
237
- vendorId: "1a86",
238
- productId: "7523",
239
- // manufacturer: '',
240
- pathRegex: ".*zigstar.*",
241
- },
242
- ],
243
- zboss: [
244
- {
245
- // Nordic Zigbee NCP
246
- vendorId: "2fe3",
247
- productId: "0100",
248
- manufacturer: "ZEPHYR",
249
- // /dev/serial/by-id/usb-ZEPHYR_Zigbee_NCP_54ACCFAFA6DAD111-if00
250
- pathRegex: ".*ZEPHYR.*",
251
- },
252
- ],
253
- zigate: [
254
- {
255
- // ZiGate PL2303HX (blue)
256
- vendorId: "067b",
257
- productId: "2303",
258
- manufacturer: "zigate_PL2303",
259
- pathRegex: ".*zigate.*",
260
- },
261
- {
262
- // ZiGate CP2102 (red)
263
- vendorId: "10c4",
264
- productId: "ea60",
265
- manufacturer: "zigate_cp2102",
266
- pathRegex: ".*zigate.*",
267
- },
268
- {
269
- // ZiGate+ V2 CDM_21228
270
- vendorId: "0403",
271
- productId: "6015",
272
- // manufacturer: '',
273
- // /dev/serial/by-id/usb-FTDI_ZiGate_ZIGATE+-if00-port0
274
- pathRegex: ".*zigate.*",
275
- },
276
- ],
277
- };
278
-
279
- /**
280
- * Vendor and Product IDs that are prone to conflict if only matching on vendorId+productId.
281
- */
282
- const USB_FINGERPRINTS_CONFLICT_IDS: ReadonlyArray<string /* vendorId:productId */> = ["10c4:ea60"];
283
-
284
- /** Time allotted for mDNS scanning */
285
- const MDNS_SCAN_TIME = 2000;
286
-
287
- async function getSerialPortList(): Promise<PortInfo[]> {
288
- const portInfos = await SerialPort.list();
289
-
290
- // TODO: can sorting be removed in favor of `path` regex matching?
291
-
292
- // CC1352P_2 and CC26X2R1 lists as 2 USB devices with same manufacturer, productId and vendorId
293
- // one is the actual chip interface, other is the XDS110.
294
- // The chip is always exposed on the first one after alphabetical sorting.
295
- /* v8 ignore next */
296
- portInfos.sort((a, b) => (a.path < b.path ? -1 : 1));
297
-
298
- return portInfos;
299
- }
300
-
301
- /**
302
- * Case insensitive string matching.
303
- * @param str1
304
- * @param str2
305
- * @returns
306
- */
307
- function matchString(str1: string, str2: string): boolean {
308
- return str1.localeCompare(str2, undefined, {sensitivity: "base"}) === 0;
309
- }
310
-
311
- /**
312
- * Case insensitive regex matching.
313
- * @param regexStr Passed to RegExp constructor.
314
- * @param str Always returns false if undefined.
315
- * @returns
316
- */
317
- function matchRegex(regexStr: string, str?: string): boolean {
318
- return str !== undefined && new RegExp(regexStr, "i").test(str);
319
- }
320
-
321
- function matchUsbFingerprint(
322
- portInfo: PortInfo,
323
- entries: UsbAdapterFingerprint[],
324
- isWindows: boolean,
325
- conflictProne: boolean,
326
- ): [path: PortInfo["path"], score: number] | undefined {
327
- if (!portInfo.vendorId || !portInfo.productId) {
328
- // port info is missing essential information for proper matching, ignore it
329
- return undefined;
330
- }
331
-
332
- let match: UsbAdapterFingerprint | undefined;
333
- let score: number = UsbFingerprintMatchScore.None;
334
-
335
- for (const entry of entries) {
336
- if (!matchString(portInfo.vendorId, entry.vendorId) || !matchString(portInfo.productId, entry.productId)) {
337
- continue;
338
- }
339
-
340
- // allow matching on vendorId+productId only on Windows
341
- if (score < UsbFingerprintMatchScore.VidPid && isWindows) {
342
- match = entry;
343
- score = UsbFingerprintMatchScore.VidPid;
344
- }
345
-
346
- if (
347
- score < UsbFingerprintMatchScore.VidPidManuf &&
348
- entry.manufacturer &&
349
- portInfo.manufacturer &&
350
- matchString(portInfo.manufacturer, entry.manufacturer)
351
- ) {
352
- match = entry;
353
- score = UsbFingerprintMatchScore.VidPidManuf;
354
-
355
- if (isWindows && !conflictProne) {
356
- // path will never match on Windows (COMx), assume vendor+product+manufacturer is "exact match"
357
- // except for conflict-prone, since it could easily return a mismatch (better to return no match and force manual config)
358
- return [portInfo.path, score];
359
- }
360
- }
361
-
362
- if (
363
- score < UsbFingerprintMatchScore.VidPidPath &&
364
- entry.pathRegex &&
365
- (matchRegex(entry.pathRegex, portInfo.path) || matchRegex(entry.pathRegex, portInfo.pnpId))
366
- ) {
367
- if (score === UsbFingerprintMatchScore.VidPidManuf) {
368
- // best possible match, return early
369
- return [portInfo.path, UsbFingerprintMatchScore.VidPidManufPath];
370
- }
371
-
372
- match = entry;
373
- score = UsbFingerprintMatchScore.VidPidPath;
374
- }
375
- }
376
-
377
- // poor match only returned if port info not conflict-prone
378
- if (match) {
379
- if (score > UsbFingerprintMatchScore.VidPid) {
380
- // biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
381
- if (conflictProne && score < UsbFingerprintMatchScore.VidPidPath && matchString(match.manufacturer!, "itead")) {
382
- // can't trust metadata "only" on sonoff dongles with conflicts
383
- return undefined;
384
- }
385
-
386
- return [portInfo.path, score];
387
- }
388
-
389
- if (!conflictProne) {
390
- return [portInfo.path, score];
391
- }
392
- }
393
-
394
- return undefined;
395
- }
396
-
397
- export async function matchUsbAdapter(adapter: Adapter, path: string): Promise<boolean> {
398
- // no point in matching this
399
- if (adapter === "zoh") {
400
- return false;
401
- }
402
-
403
- const isWindows = platform() === "win32";
404
- const portList = await getSerialPortList();
405
-
406
- logger.debug(() => `Connected devices: ${JSON.stringify(portList)}`, NS);
407
-
408
- for (const portInfo of portList) {
409
- if (portInfo.path !== path) {
410
- continue;
411
- }
412
-
413
- const conflictProne = USB_FINGERPRINTS_CONFLICT_IDS.includes(`${portInfo.vendorId}:${portInfo.productId}`);
414
- const match = matchUsbFingerprint(portInfo, USB_FINGERPRINTS[adapter === "ezsp" ? "ember" : adapter], isWindows, conflictProne);
415
-
416
- if (match) {
417
- logger.info(() => `Matched adapter: ${JSON.stringify(portInfo)} => ${adapter}: ${JSON.stringify(match[1])}`, NS);
418
- return true;
419
- }
420
- }
421
-
422
- return false;
423
- }
424
-
425
- export function findUsbAdapterBestMatch(
426
- adapter: Adapter | undefined,
427
- portInfo: PortInfo,
428
- isWindows: boolean,
429
- conflictProne: boolean,
430
- ): [DiscoverableUsbAdapter, NonNullable<ReturnType<typeof matchUsbFingerprint>>] | undefined {
431
- let bestMatch: [DiscoverableUsbAdapter, NonNullable<ReturnType<typeof matchUsbFingerprint>>] | undefined;
432
-
433
- for (const key in USB_FINGERPRINTS) {
434
- if (adapter && adapter !== key) {
435
- continue;
436
- }
437
-
438
- // biome-ignore lint/style/noNonNullAssertion: ignored using `--suppress`
439
- const match = matchUsbFingerprint(portInfo, USB_FINGERPRINTS[key as DiscoverableUsbAdapter]!, isWindows, conflictProne);
440
-
441
- // register the match if no previous or better score
442
- if (match && (!bestMatch || bestMatch[1][1] < match[1])) {
443
- bestMatch = [key as DiscoverableUsbAdapter, match];
444
-
445
- if (match[1] === UsbFingerprintMatchScore.VidPidManufPath) {
446
- // got best possible match, exit loop
447
- break;
448
- }
449
- }
450
- }
451
-
452
- return bestMatch;
453
- }
454
-
455
- export async function findUsbAdapter(
456
- adapter?: Adapter,
457
- path?: string,
458
- ): Promise<[adapter: DiscoverableUsbAdapter, path: PortInfo["path"]] | undefined> {
459
- const isWindows = platform() === "win32";
460
- // refine to DiscoverableUSBAdapter
461
- adapter = adapter && adapter === "ezsp" ? "ember" : adapter;
462
- const portList = await getSerialPortList();
463
-
464
- logger.debug(() => `Connected devices: ${JSON.stringify(portList)}`, NS);
465
-
466
- for (const portInfo of portList) {
467
- if (path && portInfo.path !== path) {
468
- continue;
469
- }
470
-
471
- const conflictProne = USB_FINGERPRINTS_CONFLICT_IDS.includes(`${portInfo.vendorId}:${portInfo.productId}`);
472
- const bestMatch = findUsbAdapterBestMatch(adapter, portInfo, isWindows, conflictProne);
473
-
474
- if (bestMatch) {
475
- logger.info(
476
- () => `Matched adapter: ${JSON.stringify(portInfo)} => ${bestMatch[0]}: path=${bestMatch[1][0]}, score=${bestMatch[1][1]}`,
477
- NS,
478
- );
479
- return [bestMatch[0], bestMatch[1][0]];
480
- }
481
- }
482
- }
483
-
484
- function getMdnsRadioAdapter(radio: string): Adapter {
485
- switch (radio) {
486
- case "znp":
487
- return "zstack";
488
- case "ezsp":
489
- return "ember";
490
- default:
491
- return radio as Adapter;
492
- }
493
- }
494
-
495
- export async function findMdnsAdapter(path: string): Promise<[adapter: Adapter, path: string]> {
496
- const mdnsDevice = path.substring(7);
497
-
498
- if (mdnsDevice.length === 0) {
499
- throw new Error("No mdns device specified. You must specify the coordinator mdns service type after mdns://, e.g. mdns://my-adapter");
500
- }
501
-
502
- const bj = new Bonjour();
503
-
504
- logger.info(`Starting mdns discovery for coordinator: ${mdnsDevice}`, NS);
505
-
506
- return await new Promise((resolve, reject) => {
507
- bj.findOne({type: mdnsDevice}, MDNS_SCAN_TIME, (service: Service) => {
508
- if (service) {
509
- if (service.txt?.radio_type && service.port) {
510
- const mdnsAddress = service.addresses?.[0] ?? service.host;
511
- const mdnsPort = service.port;
512
- const mdnsAdapter = getMdnsRadioAdapter(service.txt.radio_type);
513
-
514
- logger.info(`Coordinator Address: ${mdnsAddress}`, NS);
515
- logger.info(`Coordinator Port: ${mdnsPort}`, NS);
516
- logger.info(`Coordinator Radio: ${mdnsAdapter}`, NS);
517
- bj.destroy();
518
-
519
- resolve([mdnsAdapter, `tcp://${mdnsAddress}:${mdnsPort}`]);
520
- } else {
521
- bj.destroy();
522
- reject(
523
- new Error(
524
- `Coordinator returned wrong Zeroconf format! The following values are expected:\ntxt.radio_type, got: ${service.txt?.radio_type}\nport, got: ${service.port}`,
525
- ),
526
- );
527
- }
528
- } else {
529
- bj.destroy();
530
- reject(new Error(`Coordinator [${mdnsDevice}] not found after timeout of ${MDNS_SCAN_TIME}ms!`));
531
- }
532
- });
533
- });
534
- }
535
-
536
- export function findTcpAdapter(path: string, adapter?: Adapter): [adapter: Adapter, path: string] {
537
- try {
538
- const url = new URL(path);
539
- assert(url.port !== "");
540
- } catch {
541
- throw new Error("Invalid TCP path, expected format: tcp://<host>:<port>");
542
- }
543
-
544
- if (!adapter) {
545
- throw new Error(`Cannot discover TCP adapters at this time. Specify valid 'adapter' and 'port' in your configuration.`);
546
- }
547
-
548
- // always use `tcp://` format
549
- return [adapter, path.replace(/^socket/, "tcp")];
550
- }
551
-
552
- /**
553
- * Discover adapter using mDNS, TCP or USB.
554
- *
555
- * @param adapter The adapter type.
556
- * - mDNS: Unused.
557
- * - TCP: Required, cannot discover at this time.
558
- * - USB: Optional, limits the discovery to the specified adapter type.
559
- * @param path The path to the adapter.
560
- * - mDNS: Required, serves to initiate the discovery.
561
- * - TCP: Required, cannot discover at this time.
562
- * - USB: Optional, limits the discovery to the specified path.
563
- * @returns adapter An adapter type supported by Z2M. While result is TS-typed, this should be validated against actual values before use.
564
- * @returns path Path to adapter.
565
- */
566
- export async function discoverAdapter(adapter?: Adapter, path?: string): Promise<[adapter: Adapter, path: string]> {
567
- if (path) {
568
- if (path.startsWith("mdns://")) {
569
- return await findMdnsAdapter(path);
570
- }
571
-
572
- if (path.startsWith("tcp://") || path.startsWith("socket://")) {
573
- return findTcpAdapter(path, adapter);
574
- }
575
-
576
- if (adapter) {
577
- try {
578
- const matched = await matchUsbAdapter(adapter, path);
579
-
580
- if (!matched) {
581
- logger.debug(`Unable to match USB adapter: ${adapter} | ${path}`, NS);
582
- }
583
- } catch (error) {
584
- logger.debug(`Error while trying to match USB adapter (${(error as Error).message}).`, NS);
585
- }
586
-
587
- return [adapter, path];
588
- }
589
- }
590
-
591
- try {
592
- // default to matching USB
593
- const match = await findUsbAdapter(adapter, path);
594
-
595
- if (!match) {
596
- throw new Error("No valid USB adapter found");
597
- }
598
-
599
- // keep adapter if `ezsp` since findUSBAdapter returns DiscoverableUSBAdapter
600
- return adapter && adapter === "ezsp" ? [adapter, match[1]] : match;
601
- } catch (error) {
602
- throw new Error(`USB adapter discovery error (${(error as Error).message}). Specify valid 'adapter' and 'port' in your configuration.`);
603
- }
604
- }
605
-
606
- /**
607
- * @returns List of all serial and mDNS devices found, with matching `adapter` if available
608
- */
609
- export async function findAllDevices(): Promise<{name: string; path: string; adapter?: Adapter}[]> {
610
- const devices: {name: string; path: string; adapter?: Adapter}[] = [];
611
- const isWindows = platform() === "win32";
612
-
613
- try {
614
- const portList = await getSerialPortList();
615
-
616
- for (const portInfo of portList) {
617
- // override matching on Windows, too many chances of mismatch due to lacking data
618
- const bestMatch = isWindows
619
- ? undefined
620
- : findUsbAdapterBestMatch(
621
- undefined,
622
- portInfo,
623
- isWindows,
624
- USB_FINGERPRINTS_CONFLICT_IDS.includes(`${portInfo.vendorId}:${portInfo.productId}`),
625
- );
626
- // @ts-expect-error friendlyName Windows only
627
- const friendlyName = portInfo.friendlyName ?? portInfo.pnpId;
628
-
629
- devices.push({
630
- name: `${friendlyName} (${portInfo.manufacturer})`,
631
- path: portInfo.path,
632
- adapter: bestMatch ? bestMatch[0] : undefined,
633
- });
634
- }
635
- /* v8 ignore start */
636
- } catch (error) {
637
- logger.debug(`Failed to retrieve serial list ${(error as Error).message}.`, NS);
638
- }
639
- /* v8 ignore stop */
640
-
641
- try {
642
- const bonjour = new Bonjour();
643
- const browser = bonjour.find(null, (service) => {
644
- if (service.txt?.radio_type) {
645
- const path = `tcp://${service.addresses?.[0] ?? service.host}:${service.port}`;
646
-
647
- devices.push({
648
- name: `${service.name ?? service.txt.name ?? "Unknown"} (${path})`,
649
- path,
650
- adapter: getMdnsRadioAdapter(service.txt.radio_type),
651
- });
652
- }
653
- });
654
-
655
- browser.start();
656
- await wait(MDNS_SCAN_TIME);
657
- browser.stop();
658
- bonjour.destroy();
659
- /* v8 ignore start */
660
- } catch (error) {
661
- logger.debug(`Failed to retrieve mDNS list ${(error as Error).message}.`, NS);
662
- }
663
- /* v8 ignore stop */
664
-
665
- return devices;
666
- }
@@ -1,12 +0,0 @@
1
- import * as Zcl from "../zspec/zcl";
2
-
3
- /**
4
- * Workaround for devices that require a specific manufacturer code to be reported by coordinator while interviewing...
5
- * - Lumi/Aqara devices do not work properly otherwise (missing features): https://github.com/Koenkk/zigbee2mqtt/issues/9274
6
- */
7
- export const WORKAROUND_JOIN_MANUF_IEEE_PREFIX_TO_CODE: {[ieeePrefix: string]: Zcl.ManufacturerCode} = {
8
- // NOTE: Lumi has a new prefix registered since 2021, in case they start using that one with new devices, it might need to be added here too...
9
- // "0x18c23c" https://maclookup.app/vendors/lumi-united-technology-co-ltd
10
- "0x54ef44": Zcl.ManufacturerCode.LUMI_UNITED_TECHOLOGY_LTD_SHENZHEN,
11
- "0x04cf8c": Zcl.ManufacturerCode.LUMI_UNITED_TECHOLOGY_LTD_SHENZHEN,
12
- };