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.
- package/CHANGELOG.md +16 -0
- package/dist/adapter/ezsp/driver/uart.js +1 -1
- package/dist/adapter/ezsp/driver/uart.js.map +1 -1
- package/dist/adapter/z-stack/adapter/zStackAdapter.js +4 -4
- package/dist/adapter/z-stack/adapter/zStackAdapter.js.map +1 -1
- package/dist/adapter/zigate/adapter/zigateAdapter.js +4 -4
- package/dist/adapter/zigate/adapter/zigateAdapter.js.map +1 -1
- package/dist/controller/model/device.d.ts.map +1 -1
- package/dist/controller/model/device.js +1 -0
- package/dist/controller/model/device.js.map +1 -1
- package/package.json +14 -6
- package/.github/ISSUE_TEMPLATE/config.yml +0 -5
- package/.github/dependabot.yml +0 -22
- package/.github/workflows/ci.yml +0 -64
- package/.github/workflows/release-please.yml +0 -18
- package/.github/workflows/stale.yml +0 -20
- package/.github/workflows/typedoc.yaml +0 -47
- package/.release-please-manifest.json +0 -3
- package/.vscode/extensions.json +0 -3
- package/.vscode/settings.json +0 -11
- package/biome.json +0 -98
- package/examples/join-and-log.js +0 -24
- package/release-please-config.json +0 -9
- package/src/adapter/adapter.ts +0 -189
- package/src/adapter/adapterDiscovery.ts +0 -666
- package/src/adapter/const.ts +0 -12
- package/src/adapter/deconz/adapter/deconzAdapter.ts +0 -877
- package/src/adapter/deconz/driver/constants.ts +0 -246
- package/src/adapter/deconz/driver/driver.ts +0 -1540
- package/src/adapter/deconz/driver/frame.ts +0 -11
- package/src/adapter/deconz/driver/frameParser.ts +0 -753
- package/src/adapter/deconz/driver/parser.ts +0 -45
- package/src/adapter/deconz/driver/writer.ts +0 -22
- package/src/adapter/deconz/types.d.ts +0 -13
- package/src/adapter/ember/adapter/emberAdapter.ts +0 -2265
- package/src/adapter/ember/adapter/endpoints.ts +0 -86
- package/src/adapter/ember/adapter/oneWaitress.ts +0 -324
- package/src/adapter/ember/adapter/tokensManager.ts +0 -782
- package/src/adapter/ember/consts.ts +0 -178
- package/src/adapter/ember/enums.ts +0 -1746
- package/src/adapter/ember/ezsp/buffalo.ts +0 -1392
- package/src/adapter/ember/ezsp/consts.ts +0 -148
- package/src/adapter/ember/ezsp/enums.ts +0 -1114
- package/src/adapter/ember/ezsp/ezsp.ts +0 -9061
- package/src/adapter/ember/ezspError.ts +0 -10
- package/src/adapter/ember/types.ts +0 -866
- package/src/adapter/ember/uart/ash.ts +0 -1960
- package/src/adapter/ember/uart/consts.ts +0 -109
- package/src/adapter/ember/uart/enums.ts +0 -192
- package/src/adapter/ember/uart/parser.ts +0 -48
- package/src/adapter/ember/uart/queues.ts +0 -247
- package/src/adapter/ember/uart/writer.ts +0 -53
- package/src/adapter/ember/utils/initters.ts +0 -58
- package/src/adapter/ember/utils/math.ts +0 -73
- package/src/adapter/events.ts +0 -21
- package/src/adapter/ezsp/adapter/backup.ts +0 -109
- package/src/adapter/ezsp/adapter/ezspAdapter.ts +0 -614
- package/src/adapter/ezsp/driver/commands.ts +0 -2497
- package/src/adapter/ezsp/driver/consts.ts +0 -11
- package/src/adapter/ezsp/driver/driver.ts +0 -1002
- package/src/adapter/ezsp/driver/ezsp.ts +0 -802
- package/src/adapter/ezsp/driver/frame.ts +0 -101
- package/src/adapter/ezsp/driver/index.ts +0 -4
- package/src/adapter/ezsp/driver/multicast.ts +0 -78
- package/src/adapter/ezsp/driver/parser.ts +0 -81
- package/src/adapter/ezsp/driver/types/basic.ts +0 -201
- package/src/adapter/ezsp/driver/types/index.ts +0 -239
- package/src/adapter/ezsp/driver/types/named.ts +0 -2330
- package/src/adapter/ezsp/driver/types/struct.ts +0 -844
- package/src/adapter/ezsp/driver/uart.ts +0 -460
- package/src/adapter/ezsp/driver/utils/crc16ccitt.ts +0 -44
- package/src/adapter/ezsp/driver/utils/index.ts +0 -32
- package/src/adapter/ezsp/driver/writer.ts +0 -64
- package/src/adapter/index.ts +0 -3
- package/src/adapter/serialPort.ts +0 -58
- package/src/adapter/socketPortUtils.ts +0 -16
- package/src/adapter/tstype.ts +0 -78
- package/src/adapter/z-stack/adapter/adapter-backup.ts +0 -519
- package/src/adapter/z-stack/adapter/adapter-nv-memory.ts +0 -457
- package/src/adapter/z-stack/adapter/endpoints.ts +0 -57
- package/src/adapter/z-stack/adapter/manager.ts +0 -543
- package/src/adapter/z-stack/adapter/tstype.ts +0 -6
- package/src/adapter/z-stack/adapter/zStackAdapter.ts +0 -1190
- package/src/adapter/z-stack/constants/af.ts +0 -27
- package/src/adapter/z-stack/constants/common.ts +0 -285
- package/src/adapter/z-stack/constants/dbg.ts +0 -23
- package/src/adapter/z-stack/constants/index.ts +0 -11
- package/src/adapter/z-stack/constants/mac.ts +0 -128
- package/src/adapter/z-stack/constants/sapi.ts +0 -25
- package/src/adapter/z-stack/constants/sys.ts +0 -72
- package/src/adapter/z-stack/constants/util.ts +0 -82
- package/src/adapter/z-stack/constants/utils.ts +0 -14
- package/src/adapter/z-stack/constants/zdo.ts +0 -103
- package/src/adapter/z-stack/models/startup-options.ts +0 -13
- package/src/adapter/z-stack/structs/entries/address-manager-entry.ts +0 -44
- package/src/adapter/z-stack/structs/entries/address-manager-table.ts +0 -19
- package/src/adapter/z-stack/structs/entries/aps-link-key-data-entry.ts +0 -12
- package/src/adapter/z-stack/structs/entries/aps-link-key-data-table.ts +0 -21
- package/src/adapter/z-stack/structs/entries/aps-tc-link-key-entry.ts +0 -19
- package/src/adapter/z-stack/structs/entries/aps-tc-link-key-table.ts +0 -21
- package/src/adapter/z-stack/structs/entries/channel-list.ts +0 -8
- package/src/adapter/z-stack/structs/entries/has-configured.ts +0 -16
- package/src/adapter/z-stack/structs/entries/index.ts +0 -16
- package/src/adapter/z-stack/structs/entries/nib.ts +0 -66
- package/src/adapter/z-stack/structs/entries/nwk-key-descriptor.ts +0 -15
- package/src/adapter/z-stack/structs/entries/nwk-key.ts +0 -13
- package/src/adapter/z-stack/structs/entries/nwk-pan-id.ts +0 -8
- package/src/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.ts +0 -20
- package/src/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.ts +0 -19
- package/src/adapter/z-stack/structs/entries/security-manager-entry.ts +0 -33
- package/src/adapter/z-stack/structs/entries/security-manager-table.ts +0 -22
- package/src/adapter/z-stack/structs/index.ts +0 -4
- package/src/adapter/z-stack/structs/serializable-memory-object.ts +0 -14
- package/src/adapter/z-stack/structs/struct.ts +0 -367
- package/src/adapter/z-stack/structs/table.ts +0 -198
- package/src/adapter/z-stack/unpi/constants.ts +0 -33
- package/src/adapter/z-stack/unpi/frame.ts +0 -62
- package/src/adapter/z-stack/unpi/index.ts +0 -4
- package/src/adapter/z-stack/unpi/parser.ts +0 -56
- package/src/adapter/z-stack/unpi/writer.ts +0 -21
- package/src/adapter/z-stack/utils/channel-list.ts +0 -40
- package/src/adapter/z-stack/utils/index.ts +0 -2
- package/src/adapter/z-stack/utils/network-options.ts +0 -26
- package/src/adapter/z-stack/znp/buffaloZnp.ts +0 -175
- package/src/adapter/z-stack/znp/definition.ts +0 -2713
- package/src/adapter/z-stack/znp/index.ts +0 -2
- package/src/adapter/z-stack/znp/parameterType.ts +0 -22
- package/src/adapter/z-stack/znp/tstype.ts +0 -44
- package/src/adapter/z-stack/znp/utils.ts +0 -10
- package/src/adapter/z-stack/znp/znp.ts +0 -342
- package/src/adapter/z-stack/znp/zpiObject.ts +0 -148
- package/src/adapter/zboss/adapter/zbossAdapter.ts +0 -526
- package/src/adapter/zboss/commands.ts +0 -1184
- package/src/adapter/zboss/consts.ts +0 -9
- package/src/adapter/zboss/driver.ts +0 -422
- package/src/adapter/zboss/enums.ts +0 -360
- package/src/adapter/zboss/frame.ts +0 -227
- package/src/adapter/zboss/reader.ts +0 -65
- package/src/adapter/zboss/types.ts +0 -0
- package/src/adapter/zboss/uart.ts +0 -428
- package/src/adapter/zboss/utils.ts +0 -58
- package/src/adapter/zboss/writer.ts +0 -49
- package/src/adapter/zigate/adapter/patchZdoBuffaloBE.ts +0 -27
- package/src/adapter/zigate/adapter/zigateAdapter.ts +0 -618
- package/src/adapter/zigate/driver/LICENSE +0 -17
- package/src/adapter/zigate/driver/buffaloZiGate.ts +0 -212
- package/src/adapter/zigate/driver/commandType.ts +0 -418
- package/src/adapter/zigate/driver/constants.ts +0 -150
- package/src/adapter/zigate/driver/frame.ts +0 -197
- package/src/adapter/zigate/driver/messageType.ts +0 -287
- package/src/adapter/zigate/driver/parameterType.ts +0 -32
- package/src/adapter/zigate/driver/ziGateObject.ts +0 -146
- package/src/adapter/zigate/driver/zigate.ts +0 -423
- package/src/adapter/zoh/adapter/utils.ts +0 -27
- package/src/adapter/zoh/adapter/zohAdapter.ts +0 -838
- package/src/buffalo/buffalo.ts +0 -342
- package/src/buffalo/index.ts +0 -1
- package/src/controller/controller.ts +0 -1022
- package/src/controller/database.ts +0 -124
- package/src/controller/events.ts +0 -52
- package/src/controller/greenPower.ts +0 -603
- package/src/controller/helpers/index.ts +0 -1
- package/src/controller/helpers/installCodes.ts +0 -107
- package/src/controller/helpers/request.ts +0 -96
- package/src/controller/helpers/requestQueue.ts +0 -125
- package/src/controller/helpers/zclFrameConverter.ts +0 -47
- package/src/controller/helpers/zclTransactionSequenceNumber.ts +0 -19
- package/src/controller/index.ts +0 -6
- package/src/controller/model/device.ts +0 -1248
- package/src/controller/model/endpoint.ts +0 -1105
- package/src/controller/model/entity.ts +0 -23
- package/src/controller/model/group.ts +0 -424
- package/src/controller/model/index.ts +0 -5
- package/src/controller/model/zigbeeEntity.ts +0 -30
- package/src/controller/touchlink.ts +0 -189
- package/src/controller/tstype.ts +0 -274
- package/src/index.ts +0 -12
- package/src/models/backup-storage-legacy.ts +0 -48
- package/src/models/backup-storage-unified.ts +0 -47
- package/src/models/backup.ts +0 -37
- package/src/models/index.ts +0 -5
- package/src/models/network-options.ts +0 -11
- package/src/utils/backup.ts +0 -152
- package/src/utils/index.ts +0 -5
- package/src/utils/logger.ts +0 -20
- package/src/utils/patchBigIntSerialization.ts +0 -8
- package/src/utils/queue.ts +0 -76
- package/src/utils/types.d.ts +0 -3
- package/src/utils/utils.ts +0 -19
- package/src/utils/wait.ts +0 -5
- package/src/utils/waitress.ts +0 -96
- package/src/zspec/consts.ts +0 -84
- package/src/zspec/enums.ts +0 -22
- package/src/zspec/index.ts +0 -3
- package/src/zspec/tstypes.ts +0 -18
- package/src/zspec/utils.ts +0 -247
- package/src/zspec/zcl/buffaloZcl.ts +0 -1220
- package/src/zspec/zcl/definition/cluster.ts +0 -5915
- package/src/zspec/zcl/definition/clusters-typegen.ts +0 -588
- package/src/zspec/zcl/definition/clusters-types.ts +0 -7331
- package/src/zspec/zcl/definition/consts.ts +0 -24
- package/src/zspec/zcl/definition/enums.ts +0 -203
- package/src/zspec/zcl/definition/foundation.ts +0 -329
- package/src/zspec/zcl/definition/manufacturerCode.ts +0 -729
- package/src/zspec/zcl/definition/status.ts +0 -69
- package/src/zspec/zcl/definition/tstype.ts +0 -377
- package/src/zspec/zcl/index.ts +0 -11
- package/src/zspec/zcl/utils.ts +0 -321
- package/src/zspec/zcl/zclFrame.ts +0 -356
- package/src/zspec/zcl/zclHeader.ts +0 -102
- package/src/zspec/zcl/zclStatusError.ts +0 -10
- package/src/zspec/zdo/buffaloZdo.ts +0 -2336
- package/src/zspec/zdo/definition/clusters.ts +0 -722
- package/src/zspec/zdo/definition/consts.ts +0 -16
- package/src/zspec/zdo/definition/enums.ts +0 -99
- package/src/zspec/zdo/definition/status.ts +0 -105
- package/src/zspec/zdo/definition/tstypes.ts +0 -1062
- package/src/zspec/zdo/index.ts +0 -7
- package/src/zspec/zdo/utils.ts +0 -76
- package/src/zspec/zdo/zdoStatusError.ts +0 -10
- package/test/adapter/adapter.test.ts +0 -1062
- package/test/adapter/ember/ash.test.ts +0 -337
- package/test/adapter/ember/consts.ts +0 -131
- package/test/adapter/ember/emberAdapter.test.ts +0 -3449
- package/test/adapter/ember/ezsp.test.ts +0 -385
- package/test/adapter/ember/ezspBuffalo.test.ts +0 -93
- package/test/adapter/ember/ezspError.test.ts +0 -12
- package/test/adapter/ember/math.test.ts +0 -206
- package/test/adapter/ezsp/frame.test.ts +0 -30
- package/test/adapter/ezsp/uart.test.ts +0 -181
- package/test/adapter/z-stack/adapter.test.ts +0 -3984
- package/test/adapter/z-stack/constants.test.ts +0 -33
- package/test/adapter/z-stack/structs.test.ts +0 -115
- package/test/adapter/z-stack/unpi.test.ts +0 -213
- package/test/adapter/z-stack/znp.test.ts +0 -1284
- package/test/adapter/zboss/fixZdoResponse.test.ts +0 -179
- package/test/adapter/zigate/patchZdoBuffaloBE.test.ts +0 -81
- package/test/adapter/zigate/zdo.test.ts +0 -187
- package/test/adapter/zoh/utils.test.ts +0 -36
- package/test/adapter/zoh/zohAdapter.test.ts +0 -1307
- package/test/buffalo.test.ts +0 -431
- package/test/controller.bench.ts +0 -193
- package/test/controller.test.ts +0 -8702
- package/test/greenpower.test.ts +0 -1408
- package/test/mockAdapters.ts +0 -65
- package/test/mockDevices.ts +0 -598
- package/test/requests.bench.ts +0 -206
- package/test/testUtils.ts +0 -20
- package/test/tsconfig.json +0 -9
- package/test/utils/math.ts +0 -19
- package/test/utils.test.ts +0 -279
- package/test/vitest.config.mts +0 -27
- package/test/zcl.test.ts +0 -2831
- package/test/zspec/utils.test.ts +0 -68
- package/test/zspec/zcl/buffalo.test.ts +0 -1374
- package/test/zspec/zcl/frame.test.ts +0 -960
- package/test/zspec/zcl/utils.test.ts +0 -273
- package/test/zspec/zdo/buffalo.test.ts +0 -1850
- package/test/zspec/zdo/utils.test.ts +0 -241
- 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
|
-
}
|
package/src/adapter/const.ts
DELETED
|
@@ -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
|
-
};
|