@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.
- package/.release-please-manifest.json +4 -0
- package/CHANGELOG.md +27 -0
- package/dist/adapter/adapter.d.ts +61 -61
- package/dist/adapter/adapter.d.ts.map +1 -1
- package/dist/adapter/adapter.js +146 -100
- package/dist/adapter/adapter.js.map +1 -1
- package/dist/adapter/deconz/adapter/deconzAdapter.d.ts +68 -68
- package/dist/adapter/deconz/adapter/deconzAdapter.d.ts.map +1 -1
- package/dist/adapter/deconz/adapter/deconzAdapter.js +1060 -1063
- package/dist/adapter/deconz/adapter/deconzAdapter.js.map +1 -1
- package/dist/adapter/deconz/adapter/index.d.ts +2 -2
- package/dist/adapter/deconz/adapter/index.js +10 -10
- package/dist/adapter/deconz/driver/constants.d.ts +104 -104
- package/dist/adapter/deconz/driver/constants.js +55 -55
- package/dist/adapter/deconz/driver/driver.d.ts +81 -81
- package/dist/adapter/deconz/driver/driver.js +732 -732
- package/dist/adapter/deconz/driver/frame.d.ts +6 -6
- package/dist/adapter/deconz/driver/frame.js +13 -13
- package/dist/adapter/deconz/driver/frameParser.d.ts +2 -2
- package/dist/adapter/deconz/driver/frameParser.js +443 -443
- package/dist/adapter/deconz/driver/parser.d.ts +12 -12
- package/dist/adapter/deconz/driver/parser.js +61 -61
- package/dist/adapter/deconz/driver/writer.d.ts +8 -8
- package/dist/adapter/deconz/driver/writer.js +44 -44
- package/dist/adapter/events.d.ts +47 -47
- package/dist/adapter/events.js +14 -14
- package/dist/adapter/ezsp/adapter/backup.d.ts +9 -9
- package/dist/adapter/ezsp/adapter/backup.js +53 -53
- package/dist/adapter/ezsp/adapter/ezspAdapter.d.ts +59 -59
- package/dist/adapter/ezsp/adapter/ezspAdapter.js +585 -585
- package/dist/adapter/ezsp/adapter/index.d.ts +2 -2
- package/dist/adapter/ezsp/adapter/index.js +10 -10
- package/dist/adapter/ezsp/driver/commands.d.ts +36 -34
- package/dist/adapter/ezsp/driver/commands.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/commands.js +2359 -2357
- package/dist/adapter/ezsp/driver/commands.js.map +1 -1
- package/dist/adapter/ezsp/driver/consts.d.ts +10 -10
- package/dist/adapter/ezsp/driver/consts.js +13 -13
- package/dist/adapter/ezsp/driver/driver.d.ts +103 -103
- package/dist/adapter/ezsp/driver/driver.js +639 -639
- package/dist/adapter/ezsp/driver/driver.js.map +1 -1
- package/dist/adapter/ezsp/driver/ezsp.d.ts +96 -96
- package/dist/adapter/ezsp/driver/ezsp.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/ezsp.js +586 -577
- package/dist/adapter/ezsp/driver/ezsp.js.map +1 -1
- package/dist/adapter/ezsp/driver/index.d.ts +3 -3
- package/dist/adapter/ezsp/driver/index.js +8 -8
- package/dist/adapter/ezsp/driver/multicast.d.ts +12 -12
- package/dist/adapter/ezsp/driver/multicast.js +74 -74
- package/dist/adapter/ezsp/driver/parser.d.ts +12 -12
- package/dist/adapter/ezsp/driver/parser.js +111 -111
- package/dist/adapter/ezsp/driver/types/basic.d.ts +62 -62
- package/dist/adapter/ezsp/driver/types/basic.js +208 -208
- package/dist/adapter/ezsp/driver/types/basic.js.map +1 -1
- package/dist/adapter/ezsp/driver/types/index.d.ts +9 -9
- package/dist/adapter/ezsp/driver/types/index.js +133 -133
- package/dist/adapter/ezsp/driver/types/named.d.ts +697 -697
- package/dist/adapter/ezsp/driver/types/named.js +1726 -1726
- package/dist/adapter/ezsp/driver/types/named.js.map +1 -1
- package/dist/adapter/ezsp/driver/types/struct.d.ts +251 -251
- package/dist/adapter/ezsp/driver/types/struct.js +708 -708
- package/dist/adapter/ezsp/driver/types/struct.js.map +1 -1
- package/dist/adapter/ezsp/driver/uart.d.ts +44 -44
- package/dist/adapter/ezsp/driver/uart.d.ts.map +1 -1
- package/dist/adapter/ezsp/driver/uart.js +368 -366
- package/dist/adapter/ezsp/driver/uart.js.map +1 -1
- package/dist/adapter/ezsp/driver/utils/crc16ccitt.d.ts +2 -2
- package/dist/adapter/ezsp/driver/utils/crc16ccitt.js +55 -55
- package/dist/adapter/ezsp/driver/utils/index.d.ts +18 -18
- package/dist/adapter/ezsp/driver/utils/index.js +67 -67
- package/dist/adapter/ezsp/driver/writer.d.ts +13 -13
- package/dist/adapter/ezsp/driver/writer.js +88 -88
- package/dist/adapter/index.d.ts +4 -4
- package/dist/adapter/index.js +35 -35
- package/dist/adapter/serialPort.d.ts +8 -8
- package/dist/adapter/serialPort.js +22 -22
- package/dist/adapter/serialPort.js.map +1 -1
- package/dist/adapter/serialPortUtils.d.ts +12 -12
- package/dist/adapter/serialPortUtils.js +18 -18
- package/dist/adapter/socketPortUtils.d.ts +10 -10
- package/dist/adapter/socketPortUtils.js +16 -16
- package/dist/adapter/tstype.d.ts +85 -85
- package/dist/adapter/tstype.js +2 -2
- package/dist/adapter/z-stack/adapter/adapter-backup.d.ts +62 -62
- package/dist/adapter/z-stack/adapter/adapter-backup.js +441 -441
- package/dist/adapter/z-stack/adapter/adapter-nv-memory.d.ts +150 -150
- package/dist/adapter/z-stack/adapter/adapter-nv-memory.js +258 -258
- package/dist/adapter/z-stack/adapter/endpoints.d.ts +11 -11
- package/dist/adapter/z-stack/adapter/endpoints.js +73 -73
- package/dist/adapter/z-stack/adapter/index.d.ts +2 -2
- package/dist/adapter/z-stack/adapter/index.js +8 -8
- package/dist/adapter/z-stack/adapter/manager.d.ts +86 -86
- package/dist/adapter/z-stack/adapter/manager.js +476 -476
- package/dist/adapter/z-stack/adapter/tstype.d.ts +6 -6
- package/dist/adapter/z-stack/adapter/tstype.js +10 -10
- package/dist/adapter/z-stack/adapter/zStackAdapter.d.ts +81 -81
- package/dist/adapter/z-stack/adapter/zStackAdapter.js +868 -868
- package/dist/adapter/z-stack/constants/af.d.ts +23 -23
- package/dist/adapter/z-stack/constants/af.js +27 -27
- package/dist/adapter/z-stack/constants/common.d.ts +278 -278
- package/dist/adapter/z-stack/constants/common.js +289 -289
- package/dist/adapter/z-stack/constants/dbg.d.ts +22 -22
- package/dist/adapter/z-stack/constants/dbg.js +24 -24
- package/dist/adapter/z-stack/constants/index.d.ts +10 -10
- package/dist/adapter/z-stack/constants/index.js +47 -47
- package/dist/adapter/z-stack/constants/mac.d.ts +127 -127
- package/dist/adapter/z-stack/constants/mac.js +129 -129
- package/dist/adapter/z-stack/constants/sapi.d.ts +24 -24
- package/dist/adapter/z-stack/constants/sapi.js +26 -26
- package/dist/adapter/z-stack/constants/sys.d.ts +71 -71
- package/dist/adapter/z-stack/constants/sys.js +73 -73
- package/dist/adapter/z-stack/constants/util.d.ts +81 -81
- package/dist/adapter/z-stack/constants/util.js +83 -83
- package/dist/adapter/z-stack/constants/utils.d.ts +4 -4
- package/dist/adapter/z-stack/constants/utils.js +14 -14
- package/dist/adapter/z-stack/constants/zdo.d.ts +102 -102
- package/dist/adapter/z-stack/constants/zdo.js +104 -104
- package/dist/adapter/z-stack/models/index.d.ts +1 -1
- package/dist/adapter/z-stack/models/index.js +17 -17
- package/dist/adapter/z-stack/models/startup-options.d.ts +12 -12
- package/dist/adapter/z-stack/models/startup-options.js +2 -2
- package/dist/adapter/z-stack/structs/entries/address-manager-entry.d.ts +23 -23
- package/dist/adapter/z-stack/structs/entries/address-manager-entry.js +45 -45
- package/dist/adapter/z-stack/structs/entries/address-manager-table.d.ts +10 -10
- package/dist/adapter/z-stack/structs/entries/address-manager-table.js +22 -22
- package/dist/adapter/z-stack/structs/entries/aps-link-key-data-entry.d.ts +10 -10
- package/dist/adapter/z-stack/structs/entries/aps-link-key-data-entry.js +21 -21
- package/dist/adapter/z-stack/structs/entries/aps-link-key-data-table.d.ts +10 -10
- package/dist/adapter/z-stack/structs/entries/aps-link-key-data-table.js +23 -23
- package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-entry.d.ts +10 -10
- package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-entry.js +24 -24
- package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-table.d.ts +10 -10
- package/dist/adapter/z-stack/structs/entries/aps-tc-link-key-table.js +23 -23
- package/dist/adapter/z-stack/structs/entries/channel-list.d.ts +8 -8
- package/dist/adapter/z-stack/structs/entries/channel-list.js +15 -15
- package/dist/adapter/z-stack/structs/entries/has-configured.d.ts +8 -8
- package/dist/adapter/z-stack/structs/entries/has-configured.js +16 -16
- package/dist/adapter/z-stack/structs/entries/index.d.ts +16 -16
- package/dist/adapter/z-stack/structs/entries/index.js +32 -32
- package/dist/adapter/z-stack/structs/entries/nib.d.ts +10 -10
- package/dist/adapter/z-stack/structs/entries/nib.js +68 -68
- package/dist/adapter/z-stack/structs/entries/nwk-key-descriptor.d.ts +10 -10
- package/dist/adapter/z-stack/structs/entries/nwk-key-descriptor.js +18 -18
- package/dist/adapter/z-stack/structs/entries/nwk-key.d.ts +8 -8
- package/dist/adapter/z-stack/structs/entries/nwk-key.js +15 -15
- package/dist/adapter/z-stack/structs/entries/nwk-pan-id.d.ts +8 -8
- package/dist/adapter/z-stack/structs/entries/nwk-pan-id.js +15 -15
- package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.d.ts +13 -13
- package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-entry.js +23 -23
- package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.d.ts +10 -10
- package/dist/adapter/z-stack/structs/entries/nwk-sec-material-descriptor-table.js +22 -22
- package/dist/adapter/z-stack/structs/entries/security-manager-entry.d.ts +20 -20
- package/dist/adapter/z-stack/structs/entries/security-manager-entry.js +36 -36
- package/dist/adapter/z-stack/structs/entries/security-manager-table.d.ts +10 -10
- package/dist/adapter/z-stack/structs/entries/security-manager-table.js +24 -24
- package/dist/adapter/z-stack/structs/index.d.ts +4 -4
- package/dist/adapter/z-stack/structs/index.js +20 -20
- package/dist/adapter/z-stack/structs/serializable-memory-object.d.ts +13 -13
- package/dist/adapter/z-stack/structs/serializable-memory-object.js +2 -2
- package/dist/adapter/z-stack/structs/struct.d.ts +99 -99
- package/dist/adapter/z-stack/structs/struct.js +295 -295
- package/dist/adapter/z-stack/structs/table.d.ts +94 -94
- package/dist/adapter/z-stack/structs/table.js +161 -161
- package/dist/adapter/z-stack/unpi/constants.d.ts +28 -28
- package/dist/adapter/z-stack/unpi/constants.js +41 -41
- package/dist/adapter/z-stack/unpi/frame.d.ts +16 -16
- package/dist/adapter/z-stack/unpi/frame.js +48 -48
- package/dist/adapter/z-stack/unpi/index.d.ts +5 -5
- package/dist/adapter/z-stack/unpi/index.js +37 -37
- package/dist/adapter/z-stack/unpi/parser.d.ts +10 -10
- package/dist/adapter/z-stack/unpi/parser.js +74 -74
- package/dist/adapter/z-stack/unpi/writer.d.ts +10 -10
- package/dist/adapter/z-stack/unpi/writer.js +44 -44
- package/dist/adapter/z-stack/utils/channel-list.d.ts +20 -20
- package/dist/adapter/z-stack/utils/channel-list.js +40 -40
- package/dist/adapter/z-stack/utils/index.d.ts +2 -2
- package/dist/adapter/z-stack/utils/index.js +18 -18
- package/dist/adapter/z-stack/utils/network-options.d.ts +8 -8
- package/dist/adapter/z-stack/utils/network-options.js +22 -22
- package/dist/adapter/z-stack/znp/buffaloZnp.d.ts +11 -11
- package/dist/adapter/z-stack/znp/buffaloZnp.js +113 -113
- package/dist/adapter/z-stack/znp/definition.d.ts +5 -5
- package/dist/adapter/z-stack/znp/definition.js +3050 -3050
- package/dist/adapter/z-stack/znp/index.d.ts +3 -3
- package/dist/adapter/z-stack/znp/index.js +10 -10
- package/dist/adapter/z-stack/znp/parameterType.d.ts +22 -22
- package/dist/adapter/z-stack/znp/parameterType.js +25 -25
- package/dist/adapter/z-stack/znp/tstype.d.ts +21 -21
- package/dist/adapter/z-stack/znp/tstype.js +2 -2
- package/dist/adapter/z-stack/znp/znp.d.ts +43 -43
- package/dist/adapter/z-stack/znp/znp.js +325 -325
- package/dist/adapter/z-stack/znp/zpiObject.d.ts +19 -19
- package/dist/adapter/z-stack/znp/zpiObject.js +96 -96
- package/dist/adapter/zigate/adapter/index.d.ts +2 -2
- package/dist/adapter/zigate/adapter/index.js +10 -10
- package/dist/adapter/zigate/adapter/zigateAdapter.d.ts +69 -69
- package/dist/adapter/zigate/adapter/zigateAdapter.js +678 -678
- package/dist/adapter/zigate/debug.d.ts +7 -7
- package/dist/adapter/zigate/debug.js +22 -22
- package/dist/adapter/zigate/driver/buffaloZiGate.d.ts +18 -18
- package/dist/adapter/zigate/driver/buffaloZiGate.js +139 -139
- package/dist/adapter/zigate/driver/commandType.d.ts +41 -41
- package/dist/adapter/zigate/driver/commandType.js +385 -385
- package/dist/adapter/zigate/driver/constants.d.ts +276 -276
- package/dist/adapter/zigate/driver/constants.js +371 -371
- package/dist/adapter/zigate/driver/frame.d.ts +26 -26
- package/dist/adapter/zigate/driver/frame.js +172 -172
- package/dist/adapter/zigate/driver/frame.js.map +1 -1
- package/dist/adapter/zigate/driver/messageType.d.ts +11 -11
- package/dist/adapter/zigate/driver/messageType.js +278 -278
- package/dist/adapter/zigate/driver/parameterType.d.ts +20 -20
- package/dist/adapter/zigate/driver/parameterType.js +23 -23
- package/dist/adapter/zigate/driver/ziGateObject.d.ts +23 -23
- package/dist/adapter/zigate/driver/ziGateObject.js +106 -106
- package/dist/adapter/zigate/driver/zigate.d.ts +49 -49
- package/dist/adapter/zigate/driver/zigate.js +303 -303
- package/dist/buffalo/buffalo.d.ts +50 -48
- package/dist/buffalo/buffalo.d.ts.map +1 -1
- package/dist/buffalo/buffalo.js +322 -307
- package/dist/buffalo/buffalo.js.map +1 -1
- package/dist/buffalo/index.d.ts +3 -3
- package/dist/buffalo/index.js +33 -33
- package/dist/buffalo/tstype.d.ts +8 -8
- package/dist/buffalo/tstype.js +2 -2
- package/dist/controller/controller.d.ts +110 -110
- package/dist/controller/controller.js +607 -607
- package/dist/controller/database.d.ts +18 -18
- package/dist/controller/database.js +93 -93
- package/dist/controller/events.d.ts +55 -55
- package/dist/controller/events.d.ts.map +1 -1
- package/dist/controller/events.js +101 -99
- package/dist/controller/events.js.map +1 -1
- package/dist/controller/greenPower.d.ts +12 -12
- package/dist/controller/greenPower.js +220 -220
- package/dist/controller/helpers/index.d.ts +2 -2
- package/dist/controller/helpers/index.js +28 -28
- package/dist/controller/helpers/request.d.ts +23 -0
- package/dist/controller/helpers/request.d.ts.map +1 -0
- package/dist/controller/helpers/request.js +72 -0
- package/dist/controller/helpers/request.js.map +1 -0
- package/dist/controller/helpers/zclFrameConverter.d.ts +7 -7
- package/dist/controller/helpers/zclFrameConverter.js +31 -31
- package/dist/controller/helpers/zclTransactionSequenceNumber.d.ts +5 -5
- package/dist/controller/helpers/zclTransactionSequenceNumber.js +13 -13
- package/dist/controller/index.d.ts +5 -5
- package/dist/controller/index.js +8 -8
- package/dist/controller/logger-stub.d.ts +6 -6
- package/dist/controller/logger-stub.js +2 -2
- package/dist/controller/model/device.d.ts +132 -127
- package/dist/controller/model/device.d.ts.map +1 -1
- package/dist/controller/model/device.js +708 -681
- package/dist/controller/model/device.js.map +1 -1
- package/dist/controller/model/endpoint.d.ts +131 -128
- package/dist/controller/model/endpoint.d.ts.map +1 -1
- package/dist/controller/model/endpoint.js +817 -665
- package/dist/controller/model/endpoint.js.map +1 -1
- package/dist/controller/model/entity.d.ts +14 -14
- package/dist/controller/model/entity.js +26 -26
- package/dist/controller/model/group.d.ts +39 -39
- package/dist/controller/model/group.js +221 -221
- package/dist/controller/model/index.d.ts +5 -5
- package/dist/controller/model/index.js +14 -14
- package/dist/controller/touchlink.d.ts +19 -19
- package/dist/controller/touchlink.js +157 -157
- package/dist/controller/tstype.d.ts +21 -20
- package/dist/controller/tstype.d.ts.map +1 -1
- package/dist/controller/tstype.js +9 -9
- package/dist/controller/tstype.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +33 -33
- package/dist/models/backup-storage-legacy.d.ts +26 -26
- package/dist/models/backup-storage-legacy.js +2 -2
- package/dist/models/backup-storage-unified.d.ts +49 -49
- package/dist/models/backup-storage-unified.js +2 -2
- package/dist/models/backup.d.ts +37 -37
- package/dist/models/backup.js +2 -2
- package/dist/models/index.d.ts +4 -4
- package/dist/models/index.js +20 -20
- package/dist/models/network-options.d.ts +12 -12
- package/dist/models/network-options.js +2 -2
- package/dist/utils/assertString.d.ts +2 -2
- package/dist/utils/assertString.js +8 -8
- package/dist/utils/backup.d.ts +20 -20
- package/dist/utils/backup.js +187 -187
- package/dist/utils/equalsPartial.d.ts +2 -2
- package/dist/utils/equalsPartial.js +11 -11
- package/dist/utils/index.d.ts +9 -9
- package/dist/utils/index.js +45 -45
- package/dist/utils/isNumberArray.d.ts +2 -2
- package/dist/utils/isNumberArray.js +6 -6
- package/dist/utils/queue.d.ts +11 -11
- package/dist/utils/queue.js +50 -50
- package/dist/utils/realpathSync.d.ts +2 -2
- package/dist/utils/realpathSync.js +12 -12
- package/dist/utils/wait.d.ts +2 -2
- package/dist/utils/wait.js +8 -8
- package/dist/utils/waitress.d.ts +21 -21
- package/dist/utils/waitress.js +61 -61
- package/dist/zcl/buffaloZcl.d.ts +41 -41
- package/dist/zcl/buffaloZcl.js +591 -591
- package/dist/zcl/definition/buffaloZclDataType.d.ts +17 -17
- package/dist/zcl/definition/buffaloZclDataType.js +20 -20
- package/dist/zcl/definition/cluster.d.ts +29 -29
- package/dist/zcl/definition/cluster.d.ts.map +1 -1
- package/dist/zcl/definition/cluster.js +5335 -5215
- package/dist/zcl/definition/cluster.js.map +1 -1
- package/dist/zcl/definition/dataType.d.ts +59 -59
- package/dist/zcl/definition/dataType.d.ts.map +1 -1
- package/dist/zcl/definition/dataType.js +64 -64
- package/dist/zcl/definition/dataType.js.map +1 -1
- package/dist/zcl/definition/direction.d.ts +5 -5
- package/dist/zcl/definition/direction.js +8 -8
- package/dist/zcl/definition/endpointDeviceType.d.ts +4 -4
- package/dist/zcl/definition/endpointDeviceType.js +15 -15
- package/dist/zcl/definition/foundation.d.ts +11 -11
- package/dist/zcl/definition/foundation.js +167 -167
- package/dist/zcl/definition/frameControl.d.ts +10 -10
- package/dist/zcl/definition/frameControl.js +2 -2
- package/dist/zcl/definition/frameType.d.ts +5 -5
- package/dist/zcl/definition/frameType.js +8 -8
- package/dist/zcl/definition/index.d.ts +13 -13
- package/dist/zcl/definition/index.js +51 -51
- package/dist/zcl/definition/manufacturerCode.d.ts +1074 -1074
- package/dist/zcl/definition/manufacturerCode.js +1079 -1079
- package/dist/zcl/definition/powerSource.d.ts +4 -4
- package/dist/zcl/definition/powerSource.js +12 -12
- package/dist/zcl/definition/status.d.ts +38 -38
- package/dist/zcl/definition/status.js +41 -41
- package/dist/zcl/definition/tstype.d.ts +16 -16
- package/dist/zcl/definition/tstype.js +2 -2
- package/dist/zcl/index.d.ts +15 -15
- package/dist/zcl/index.js +55 -55
- package/dist/zcl/tstype.d.ts +56 -56
- package/dist/zcl/tstype.js +10 -10
- package/dist/zcl/utils.d.ts +6 -6
- package/dist/zcl/utils.js +165 -165
- package/dist/zcl/zclFrame.d.ts +45 -45
- package/dist/zcl/zclFrame.js +347 -347
- package/dist/zcl/zclStatusError.d.ts +5 -5
- package/dist/zcl/zclStatusError.js +13 -13
- package/package.json +6 -5
- package/release-please-config.json +13 -0
- package/.github/ISSUE_TEMPLATE/config.yml +0 -5
- package/.github/dependabot.yml +0 -6
- package/.github/workflows/ci.yml +0 -31
- package/.github/workflows/release.yml +0 -56
- package/.github/workflows/stale.yml +0 -19
- package/.github/workflows/update_deps.yml +0 -24
|
@@ -1,1064 +1,1061 @@
|
|
|
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 debug_1 = __importDefault(require("debug"));
|
|
30
|
-
const adapter_1 = __importDefault(require("../../adapter"));
|
|
31
|
-
const debug = (0, debug_1.default)("zigbee-herdsman:deconz:adapter");
|
|
32
|
-
const driver_1 = __importDefault(require("../driver/driver"));
|
|
33
|
-
const zcl_1 = require("../../../zcl");
|
|
34
|
-
const Events = __importStar(require("../../events"));
|
|
35
|
-
const frameParser_1 = __importDefault(require("../driver/frameParser"));
|
|
36
|
-
const utils_1 = require("../../../utils");
|
|
37
|
-
const constants_1 = __importDefault(require("../driver/constants"));
|
|
38
|
-
var frameParser = require('../driver/frameParser');
|
|
39
|
-
;
|
|
40
|
-
class DeconzAdapter extends adapter_1.default {
|
|
41
|
-
constructor(networkOptions, serialPortOptions, backupPath, adapterOptions, logger) {
|
|
42
|
-
super(networkOptions, serialPortOptions, backupPath, adapterOptions, logger);
|
|
43
|
-
this.frameParserEvent = frameParser.frameParserEvents;
|
|
44
|
-
this.TX_OPTIONS = 0x00; // No APS ACKS
|
|
45
|
-
const concurrent = this.adapterOptions && this.adapterOptions.concurrent ?
|
|
46
|
-
this.adapterOptions.concurrent : 2;
|
|
47
|
-
// TODO: https://github.com/Koenkk/zigbee2mqtt/issues/4884#issuecomment-728903121
|
|
48
|
-
const delay = this.adapterOptions && typeof this.adapterOptions.delay === 'number' ?
|
|
49
|
-
this.adapterOptions.delay : 0;
|
|
50
|
-
this.waitress = new utils_1.Waitress(this.waitressValidator, this.waitressTimeoutFormatter);
|
|
51
|
-
this.driver = new driver_1.default(serialPortOptions.path);
|
|
52
|
-
this.driver.setDelay(delay);
|
|
53
|
-
if (delay >= 200) {
|
|
54
|
-
this.TX_OPTIONS = 0x04; // activate APS ACKS
|
|
55
|
-
}
|
|
56
|
-
this.driver.on('rxFrame', (frame) => { (0, frameParser_1.default)(frame); });
|
|
57
|
-
this.queue = new utils_1.Queue(concurrent);
|
|
58
|
-
this.transactionID = 0;
|
|
59
|
-
this.openRequestsQueue = [];
|
|
60
|
-
this.joinPermitted = false;
|
|
61
|
-
this.fwVersion = null;
|
|
62
|
-
this.frameParserEvent.on('receivedDataPayload', (data) => { this.checkReceivedDataPayload(data); });
|
|
63
|
-
this.frameParserEvent.on('receivedGreenPowerIndication', (data) => { this.checkReceivedGreenPowerIndication(data); });
|
|
64
|
-
const that = this;
|
|
65
|
-
setInterval(() => { that.checkReceivedDataPayload(null); }, 1000);
|
|
66
|
-
setTimeout(() => { that.checkCoordinatorSimpleDescriptor(false); }, 3000);
|
|
67
|
-
}
|
|
68
|
-
static async isValidPath(path) {
|
|
69
|
-
return driver_1.default.isValidPath(path);
|
|
70
|
-
}
|
|
71
|
-
static async autoDetectPath() {
|
|
72
|
-
return driver_1.default.autoDetectPath();
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Adapter methods
|
|
76
|
-
*/
|
|
77
|
-
async start() {
|
|
78
|
-
await this.driver.open();
|
|
79
|
-
return "resumed";
|
|
80
|
-
}
|
|
81
|
-
async stop() {
|
|
82
|
-
await this.driver.close();
|
|
83
|
-
}
|
|
84
|
-
async getCoordinator() {
|
|
85
|
-
const ieeeAddr = await this.driver.readParameterRequest(constants_1.default.PARAM.Network.MAC);
|
|
86
|
-
const nwkAddr = await this.driver.readParameterRequest(constants_1.default.PARAM.Network.NWK_ADDRESS);
|
|
87
|
-
const endpoints = [{
|
|
88
|
-
ID: 0x01,
|
|
89
|
-
profileID: 0x0104,
|
|
90
|
-
deviceID: 0x0005,
|
|
91
|
-
inputClusters: [0x0000, 0x000A, 0x0019],
|
|
92
|
-
outputClusters: [0x0001, 0x0020, 0x0500]
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
ID: 0xF2,
|
|
96
|
-
profileID: 0xA1E0,
|
|
97
|
-
deviceID: 0x0064,
|
|
98
|
-
inputClusters: [],
|
|
99
|
-
outputClusters: [0x0021]
|
|
100
|
-
}];
|
|
101
|
-
return {
|
|
102
|
-
networkAddress: nwkAddr,
|
|
103
|
-
manufacturerID: 0x1135,
|
|
104
|
-
ieeeAddr: ieeeAddr,
|
|
105
|
-
endpoints,
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
async permitJoin(seconds, networkAddress) {
|
|
109
|
-
const transactionID = this.nextTransactionID();
|
|
110
|
-
const request = {};
|
|
111
|
-
const zdpFrame = [transactionID, seconds, 0]; // tc_significance 1 or 0 ?
|
|
112
|
-
request.requestId = transactionID;
|
|
113
|
-
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
114
|
-
request.destAddr16 = networkAddress || 0xFFFC;
|
|
115
|
-
request.destEndpoint = 0;
|
|
116
|
-
request.profileId = 0;
|
|
117
|
-
request.clusterId = 0x36; // permit join
|
|
118
|
-
request.srcEndpoint = 0;
|
|
119
|
-
request.asduLength = 3;
|
|
120
|
-
request.asduPayload = zdpFrame;
|
|
121
|
-
request.txOptions = 0;
|
|
122
|
-
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
123
|
-
request.timeout = 5;
|
|
124
|
-
try {
|
|
125
|
-
await this.driver.enqueueSendDataRequest(request);
|
|
126
|
-
if (seconds === 0) {
|
|
127
|
-
this.joinPermitted = false;
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
this.joinPermitted = true;
|
|
131
|
-
}
|
|
132
|
-
this.driver.writeParameterRequest(constants_1.default.PARAM.Network.PERMIT_JOIN, seconds);
|
|
133
|
-
debug("PERMIT_JOIN - " + seconds + " seconds");
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
const msg = "PERMIT_JOIN FAILED - " + error;
|
|
137
|
-
debug(msg);
|
|
138
|
-
// try again
|
|
139
|
-
this.permitJoin(seconds, networkAddress);
|
|
140
|
-
//return Promise.reject(new Error(msg)); // do not reject
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
async getCoordinatorVersion() {
|
|
144
|
-
// product: number; transportrev: number; majorrel: number; minorrel: number; maintrel: number; revision: string;
|
|
145
|
-
if (this.fwVersion != null) {
|
|
146
|
-
return this.fwVersion;
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
try {
|
|
150
|
-
const fw = await this.driver.readFirmwareVersionRequest();
|
|
151
|
-
const buf = Buffer.from(fw);
|
|
152
|
-
let fwString = "0x" + buf.readUInt32LE(0).toString(16);
|
|
153
|
-
const type = (fw[1] === 5) ? "ConBee/RaspBee" : "ConBee2/RaspBee2";
|
|
154
|
-
const meta = { "transportrev": 0, "product": 0, "majorrel": fw[3], "minorrel": fw[2], "maintrel": 0, "revision": fwString };
|
|
155
|
-
this.fwVersion = { type: type, meta: meta };
|
|
156
|
-
return { type: type, meta: meta };
|
|
157
|
-
}
|
|
158
|
-
catch (error) {
|
|
159
|
-
debug("Get coordinator version Error: " + error);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
async addInstallCode(ieeeAddress, key) {
|
|
164
|
-
return Promise.reject(new Error('Add install code is not supported'));
|
|
165
|
-
}
|
|
166
|
-
async reset(type) {
|
|
167
|
-
return Promise.reject(new Error('Reset is not supported'));
|
|
168
|
-
}
|
|
169
|
-
async lqi(networkAddress) {
|
|
170
|
-
const neighbors = [];
|
|
171
|
-
const add = (list) => {
|
|
172
|
-
for (const entry of list) {
|
|
173
|
-
const relationByte = entry.readUInt8(18);
|
|
174
|
-
const extAddr = [];
|
|
175
|
-
for (let i = 8; i < 16; i++) {
|
|
176
|
-
extAddr.push(entry[i]);
|
|
177
|
-
}
|
|
178
|
-
neighbors.push({
|
|
179
|
-
linkquality: entry.readUInt8(21),
|
|
180
|
-
networkAddress: entry.readUInt16LE(16),
|
|
181
|
-
ieeeAddr: this.driver.macAddrArrayToString(extAddr),
|
|
182
|
-
relationship: (relationByte >> 1) & ((1 << 3) - 1),
|
|
183
|
-
depth: entry.readUInt8(20)
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
const request = async (startIndex) => {
|
|
188
|
-
const transactionID = this.nextTransactionID();
|
|
189
|
-
const req = {};
|
|
190
|
-
req.requestId = transactionID;
|
|
191
|
-
req.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
192
|
-
req.destAddr16 = networkAddress;
|
|
193
|
-
req.destEndpoint = 0;
|
|
194
|
-
req.profileId = 0;
|
|
195
|
-
req.clusterId = 0x31; // mgmt_lqi_request
|
|
196
|
-
req.srcEndpoint = 0;
|
|
197
|
-
req.asduLength = 2;
|
|
198
|
-
req.asduPayload = [transactionID, startIndex];
|
|
199
|
-
req.txOptions = 0;
|
|
200
|
-
req.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
201
|
-
this.driver.enqueueSendDataRequest(req)
|
|
202
|
-
.then(result => { })
|
|
203
|
-
.catch(error => { });
|
|
204
|
-
try {
|
|
205
|
-
const d = await this.waitForData(networkAddress, 0, 0x8031);
|
|
206
|
-
const data = d.asduPayload;
|
|
207
|
-
if (data[1] !== 0) { // status
|
|
208
|
-
throw new Error(`LQI for '${networkAddress}' failed`);
|
|
209
|
-
}
|
|
210
|
-
const tableList = [];
|
|
211
|
-
const response = {
|
|
212
|
-
status: data[1],
|
|
213
|
-
tableEntrys: data[2],
|
|
214
|
-
startIndex: data[3],
|
|
215
|
-
tableListCount: data[4],
|
|
216
|
-
tableList: tableList
|
|
217
|
-
};
|
|
218
|
-
let tableEntry = [];
|
|
219
|
-
let counter = 0;
|
|
220
|
-
for (let i = 5; i < ((response.tableListCount * 22) + 5); i++) { // one tableentry = 22 bytes
|
|
221
|
-
tableEntry.push(data[i]);
|
|
222
|
-
counter++;
|
|
223
|
-
if (counter === 22) {
|
|
224
|
-
response.tableList.push(Buffer.from(tableEntry));
|
|
225
|
-
tableEntry = [];
|
|
226
|
-
counter = 0;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
debug("LQI RESPONSE - addr: 0x" + networkAddress.toString(16) + " status: " + response.status + " read " + (response.tableListCount + response.startIndex) + "/" + response.tableEntrys + " entrys");
|
|
230
|
-
return response;
|
|
231
|
-
}
|
|
232
|
-
catch (error) {
|
|
233
|
-
const msg = "LQI REQUEST FAILED - addr: 0x" + networkAddress.toString(16) + " " + error;
|
|
234
|
-
debug(msg);
|
|
235
|
-
return Promise.reject(new Error(msg));
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
|
-
let response = await request(0);
|
|
239
|
-
add(response.tableList);
|
|
240
|
-
let nextStartIndex = response.tableListCount;
|
|
241
|
-
while (neighbors.length < response.tableEntrys) {
|
|
242
|
-
response = await request(nextStartIndex);
|
|
243
|
-
add(response.tableList);
|
|
244
|
-
nextStartIndex += response.tableListCount;
|
|
245
|
-
}
|
|
246
|
-
return { neighbors };
|
|
247
|
-
}
|
|
248
|
-
async routingTable(networkAddress) {
|
|
249
|
-
const table = [];
|
|
250
|
-
const statusLookup = {
|
|
251
|
-
0: 'ACTIVE',
|
|
252
|
-
1: 'DISCOVERY_UNDERWAY',
|
|
253
|
-
2: 'DISCOVERY_FAILED',
|
|
254
|
-
3: 'INACTIVE',
|
|
255
|
-
};
|
|
256
|
-
const add = (list) => {
|
|
257
|
-
for (const entry of list) {
|
|
258
|
-
const statusByte = entry.readUInt8(2);
|
|
259
|
-
const extAddr = [];
|
|
260
|
-
for (let i = 8; i < 16; i++) {
|
|
261
|
-
extAddr.push(entry[i]);
|
|
262
|
-
}
|
|
263
|
-
table.push({
|
|
264
|
-
destinationAddress: entry.readUInt16LE(0),
|
|
265
|
-
status: statusLookup[(statusByte >> 5) & ((1 << 3) - 1)],
|
|
266
|
-
nextHop: entry.readUInt16LE(3)
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
};
|
|
270
|
-
const request = async (startIndex) => {
|
|
271
|
-
const transactionID = this.nextTransactionID();
|
|
272
|
-
const req = {};
|
|
273
|
-
req.requestId = transactionID;
|
|
274
|
-
req.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
275
|
-
req.destAddr16 = networkAddress;
|
|
276
|
-
req.destEndpoint = 0;
|
|
277
|
-
req.profileId = 0;
|
|
278
|
-
req.clusterId = 0x32; // mgmt_rtg_request
|
|
279
|
-
req.srcEndpoint = 0;
|
|
280
|
-
req.asduLength = 2;
|
|
281
|
-
req.asduPayload = [transactionID, startIndex];
|
|
282
|
-
req.txOptions = 0;
|
|
283
|
-
req.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
284
|
-
req.timeout = 30;
|
|
285
|
-
this.driver.enqueueSendDataRequest(req)
|
|
286
|
-
.then(result => { })
|
|
287
|
-
.catch(error => { });
|
|
288
|
-
try {
|
|
289
|
-
const d = await this.waitForData(networkAddress, 0, 0x8032);
|
|
290
|
-
const data = d.asduPayload;
|
|
291
|
-
if (data[1] !== 0) { // status
|
|
292
|
-
throw new Error(`Routingtables for '${networkAddress}' failed`);
|
|
293
|
-
}
|
|
294
|
-
const tableList = [];
|
|
295
|
-
const response = {
|
|
296
|
-
status: data[1],
|
|
297
|
-
tableEntrys: data[2],
|
|
298
|
-
startIndex: data[3],
|
|
299
|
-
tableListCount: data[4],
|
|
300
|
-
tableList: tableList
|
|
301
|
-
};
|
|
302
|
-
let tableEntry = [];
|
|
303
|
-
let counter = 0;
|
|
304
|
-
for (let i = 5; i < ((response.tableListCount * 5) + 5); i++) { // one tableentry = 5 bytes
|
|
305
|
-
tableEntry.push(data[i]);
|
|
306
|
-
counter++;
|
|
307
|
-
if (counter === 5) {
|
|
308
|
-
response.tableList.push(Buffer.from(tableEntry));
|
|
309
|
-
tableEntry = [];
|
|
310
|
-
counter = 0;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
debug("ROUTING_TABLE RESPONSE - addr: 0x" + networkAddress.toString(16) + " status: " + response.status + " read " + (response.tableListCount + response.startIndex) + "/" + response.tableEntrys + " entrys");
|
|
314
|
-
return response;
|
|
315
|
-
}
|
|
316
|
-
catch (error) {
|
|
317
|
-
const msg = "ROUTING_TABLE REQUEST FAILED - addr: 0x" + networkAddress.toString(16) + " " + error;
|
|
318
|
-
debug(msg);
|
|
319
|
-
return Promise.reject(new Error(msg));
|
|
320
|
-
}
|
|
321
|
-
};
|
|
322
|
-
let response = await request(0);
|
|
323
|
-
add(response.tableList);
|
|
324
|
-
let nextStartIndex = response.tableListCount;
|
|
325
|
-
while (table.length < response.tableEntrys) {
|
|
326
|
-
response = await request(nextStartIndex);
|
|
327
|
-
add(response.tableList);
|
|
328
|
-
nextStartIndex += response.tableListCount;
|
|
329
|
-
}
|
|
330
|
-
return { table };
|
|
331
|
-
}
|
|
332
|
-
async nodeDescriptor(networkAddress) {
|
|
333
|
-
const transactionID = this.nextTransactionID();
|
|
334
|
-
const nwk1 = networkAddress & 0xff;
|
|
335
|
-
const nwk2 = (networkAddress >> 8) & 0xff;
|
|
336
|
-
const request = {};
|
|
337
|
-
const zdpFrame = [transactionID, nwk1, nwk2];
|
|
338
|
-
request.requestId = transactionID;
|
|
339
|
-
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
340
|
-
request.destAddr16 = networkAddress;
|
|
341
|
-
request.destEndpoint = 0;
|
|
342
|
-
request.profileId = 0;
|
|
343
|
-
request.clusterId = 0x02; // node descriptor
|
|
344
|
-
request.srcEndpoint = 0;
|
|
345
|
-
request.asduLength = 3;
|
|
346
|
-
request.asduPayload = zdpFrame;
|
|
347
|
-
request.txOptions = 0;
|
|
348
|
-
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
349
|
-
request.timeout = 30;
|
|
350
|
-
this.driver.enqueueSendDataRequest(request)
|
|
351
|
-
.then(result => { })
|
|
352
|
-
.catch(error => { });
|
|
353
|
-
try {
|
|
354
|
-
const d = await this.waitForData(networkAddress, 0, 0x8002);
|
|
355
|
-
const data = d.asduPayload;
|
|
356
|
-
const buf = Buffer.from(data);
|
|
357
|
-
const logicaltype = (data[4] & 7);
|
|
358
|
-
const type = (logicaltype === 1) ? 'Router' : (logicaltype === 2) ? 'EndDevice' : (logicaltype === 0) ? 'Coordinator' : 'Unknown';
|
|
359
|
-
const manufacturer = buf.readUInt16LE(7);
|
|
360
|
-
debug("RECEIVING NODE_DESCRIPTOR - addr: 0x" + networkAddress.toString(16) + " type: " + type + " manufacturer: 0x" + manufacturer.toString(16));
|
|
361
|
-
return { manufacturerCode: manufacturer, type };
|
|
362
|
-
}
|
|
363
|
-
catch (error) {
|
|
364
|
-
const msg = "RECEIVING NODE_DESCRIPTOR FAILED - addr: 0x" + networkAddress.toString(16) + " " + error;
|
|
365
|
-
debug(msg);
|
|
366
|
-
return Promise.reject(new Error(msg));
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
async activeEndpoints(networkAddress) {
|
|
370
|
-
const transactionID = this.nextTransactionID();
|
|
371
|
-
const nwk1 = networkAddress & 0xff;
|
|
372
|
-
const nwk2 = (networkAddress >> 8) & 0xff;
|
|
373
|
-
const request = {};
|
|
374
|
-
const zdpFrame = [transactionID, nwk1, nwk2];
|
|
375
|
-
request.requestId = transactionID;
|
|
376
|
-
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
377
|
-
request.destAddr16 = networkAddress;
|
|
378
|
-
request.destEndpoint = 0;
|
|
379
|
-
request.profileId = 0;
|
|
380
|
-
request.clusterId = 0x05; // active endpoints
|
|
381
|
-
request.srcEndpoint = 0;
|
|
382
|
-
request.asduLength = 3;
|
|
383
|
-
request.asduPayload = zdpFrame;
|
|
384
|
-
request.txOptions = 0;
|
|
385
|
-
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
386
|
-
request.timeout = 30;
|
|
387
|
-
this.driver.enqueueSendDataRequest(request)
|
|
388
|
-
.then(result => { })
|
|
389
|
-
.catch(error => { });
|
|
390
|
-
try {
|
|
391
|
-
const d = await this.waitForData(networkAddress, 0, 0x8005);
|
|
392
|
-
const data = d.asduPayload;
|
|
393
|
-
const buf = Buffer.from(data);
|
|
394
|
-
const epCount = buf.readUInt8(4);
|
|
395
|
-
const epList = [];
|
|
396
|
-
for (let i = 5; i < (epCount + 5); i++) {
|
|
397
|
-
epList.push(buf.readUInt8(i));
|
|
398
|
-
}
|
|
399
|
-
debug("ACTIVE_ENDPOINTS - addr: 0x" + networkAddress.toString(16) + " EP list: " + epList);
|
|
400
|
-
return { endpoints: epList };
|
|
401
|
-
}
|
|
402
|
-
catch (error) {
|
|
403
|
-
const msg = "READING ACTIVE_ENDPOINTS FAILED - addr: 0x" + networkAddress.toString(16) + " " + error;
|
|
404
|
-
debug(msg);
|
|
405
|
-
return Promise.reject(new Error(msg));
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
async simpleDescriptor(networkAddress, endpointID) {
|
|
409
|
-
const transactionID = this.nextTransactionID();
|
|
410
|
-
const nwk1 = networkAddress & 0xff;
|
|
411
|
-
const nwk2 = (networkAddress >> 8) & 0xff;
|
|
412
|
-
const request = {};
|
|
413
|
-
const zdpFrame = [transactionID, nwk1, nwk2, endpointID];
|
|
414
|
-
request.requestId = transactionID;
|
|
415
|
-
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
416
|
-
request.destAddr16 = networkAddress;
|
|
417
|
-
request.destEndpoint = 0;
|
|
418
|
-
request.profileId = 0;
|
|
419
|
-
request.clusterId = 0x04; // simple descriptor
|
|
420
|
-
request.srcEndpoint = 0;
|
|
421
|
-
request.asduLength = 4;
|
|
422
|
-
request.asduPayload = zdpFrame;
|
|
423
|
-
request.txOptions = 0;
|
|
424
|
-
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
425
|
-
request.timeout = 30;
|
|
426
|
-
this.driver.enqueueSendDataRequest(request)
|
|
427
|
-
.then(result => { })
|
|
428
|
-
.catch(error => { });
|
|
429
|
-
try {
|
|
430
|
-
const d = await this.waitForData(networkAddress, 0, 0x8004);
|
|
431
|
-
const data = d.asduPayload;
|
|
432
|
-
const buf = Buffer.from(data);
|
|
433
|
-
const inCount = buf.readUInt8(11);
|
|
434
|
-
const inClusters = [];
|
|
435
|
-
let cIndex = 12;
|
|
436
|
-
for (let i = 0; i < inCount; i++) {
|
|
437
|
-
inClusters[i] = buf.readUInt16LE(cIndex);
|
|
438
|
-
cIndex += 2;
|
|
439
|
-
}
|
|
440
|
-
const outCount = buf.readUInt8(12 + (inCount * 2));
|
|
441
|
-
const outClusters = [];
|
|
442
|
-
cIndex = 13 + (inCount * 2);
|
|
443
|
-
for (let l = 0; l < outCount; l++) {
|
|
444
|
-
outClusters[l] = buf.readUInt16LE(cIndex);
|
|
445
|
-
cIndex += 2;
|
|
446
|
-
}
|
|
447
|
-
const simpleDesc = {
|
|
448
|
-
profileID: buf.readUInt16LE(6),
|
|
449
|
-
endpointID: buf.readUInt8(5),
|
|
450
|
-
deviceID: buf.readUInt16LE(8),
|
|
451
|
-
inputClusters: inClusters,
|
|
452
|
-
outputClusters: outClusters
|
|
453
|
-
};
|
|
454
|
-
debug("RECEIVING SIMPLE_DESCRIPTOR - addr: 0x" + networkAddress.toString(16) + " EP:" + simpleDesc.endpointID + " inClusters: " + inClusters + " outClusters: " + outClusters);
|
|
455
|
-
return simpleDesc;
|
|
456
|
-
}
|
|
457
|
-
catch (error) {
|
|
458
|
-
const msg = "RECEIVING SIMPLE_DESCRIPTOR FAILED - addr: 0x" + networkAddress.toString(16) + " " + error;
|
|
459
|
-
debug(msg);
|
|
460
|
-
return Promise.reject(new Error(msg));
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
async checkCoordinatorSimpleDescriptor(skip) {
|
|
464
|
-
debug("checking coordinator simple descriptor");
|
|
465
|
-
var simpleDesc = null;
|
|
466
|
-
if (skip === false) {
|
|
467
|
-
try {
|
|
468
|
-
simpleDesc = await this.simpleDescriptor(0x0, 1);
|
|
469
|
-
}
|
|
470
|
-
catch (error) {
|
|
471
|
-
}
|
|
472
|
-
if (simpleDesc === null) {
|
|
473
|
-
this.checkCoordinatorSimpleDescriptor(false);
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
debug("EP: " + simpleDesc.endpointID);
|
|
477
|
-
debug("profile ID: " + simpleDesc.profileID);
|
|
478
|
-
debug("device ID: " + simpleDesc.deviceID);
|
|
479
|
-
for (let i = 0; i < simpleDesc.inputClusters.length; i++) {
|
|
480
|
-
debug("input cluster: 0x" + simpleDesc.inputClusters[i].toString(16));
|
|
481
|
-
}
|
|
482
|
-
for (let o = 0; o < simpleDesc.outputClusters.length; o++) {
|
|
483
|
-
debug("output cluster: 0x" + simpleDesc.outputClusters[o].toString(16));
|
|
484
|
-
}
|
|
485
|
-
let ok = true;
|
|
486
|
-
if (simpleDesc.endpointID === 0x1) {
|
|
487
|
-
if (!simpleDesc.inputClusters.includes(0x0) || !simpleDesc.inputClusters.includes(0x0A) || !simpleDesc.inputClusters.includes(0x19) ||
|
|
488
|
-
!simpleDesc.outputClusters.includes(0x01) || !simpleDesc.outputClusters.includes(0x20) || !simpleDesc.outputClusters.includes(0x500)) {
|
|
489
|
-
debug("missing cluster");
|
|
490
|
-
ok = false;
|
|
491
|
-
}
|
|
492
|
-
if (ok === true) {
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
debug("setting new simple descriptor");
|
|
498
|
-
try { //[ sd1 ep proId devId vers #inCl iCl1 iCl2 iCl3 #outC oCl1 oCl2 oCl3 ]
|
|
499
|
-
const sd = [0x00, 0x01, 0x04, 0x01, 0x05, 0x00, 0x01, 0x03, 0x00, 0x00, 0x0A, 0x00, 0x19, 0x00, 0x03, 0x01, 0x00, 0x20, 0x00, 0x00, 0x05];
|
|
500
|
-
const sd1 = sd.reverse();
|
|
501
|
-
await this.driver.writeParameterRequest(constants_1.default.PARAM.STK.Endpoint, sd1);
|
|
502
|
-
}
|
|
503
|
-
catch (error) {
|
|
504
|
-
debug("error setting simple descriptor - try again");
|
|
505
|
-
this.checkCoordinatorSimpleDescriptor(true);
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
|
-
debug("success setting simple descriptor");
|
|
509
|
-
}
|
|
510
|
-
waitFor(networkAddress, endpoint, frameType, direction, transactionSequenceNumber, clusterID, commandIdentifier, timeout) {
|
|
511
|
-
const payload = {
|
|
512
|
-
address: networkAddress, endpoint, clusterID, commandIdentifier, frameType, direction,
|
|
513
|
-
transactionSequenceNumber,
|
|
514
|
-
};
|
|
515
|
-
const waiter = this.waitress.waitFor(payload, timeout);
|
|
516
|
-
const cancel = () => this.waitress.remove(waiter.ID);
|
|
517
|
-
return { promise: waiter.start().promise, cancel };
|
|
518
|
-
}
|
|
519
|
-
async sendZclFrameToEndpoint(ieeeAddr, networkAddress, endpoint, zclFrame, timeout, disableResponse, disableRecovery, sourceEndpoint) {
|
|
520
|
-
const transactionID = this.nextTransactionID();
|
|
521
|
-
const request = {};
|
|
522
|
-
let pay = zclFrame.toBuffer();
|
|
523
|
-
//console.log("zclFramte.toBuffer:");
|
|
524
|
-
//console.log(pay);
|
|
525
|
-
request.requestId = transactionID;
|
|
526
|
-
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
527
|
-
request.destAddr16 = networkAddress;
|
|
528
|
-
request.destEndpoint = endpoint;
|
|
529
|
-
request.profileId = sourceEndpoint === 242 && endpoint === 242 ? 0xa1e0 : 0x104;
|
|
530
|
-
request.clusterId = zclFrame.Cluster.ID;
|
|
531
|
-
request.srcEndpoint = sourceEndpoint || 1;
|
|
532
|
-
request.asduLength = pay.length;
|
|
533
|
-
request.asduPayload = [...pay];
|
|
534
|
-
request.txOptions = this.TX_OPTIONS; // 0x00 normal; 0x04 APS ACK
|
|
535
|
-
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
536
|
-
request.timeout = timeout;
|
|
537
|
-
const command = zclFrame.getCommand();
|
|
538
|
-
this.driver.enqueueSendDataRequest(request)
|
|
539
|
-
.then(result => {
|
|
540
|
-
debug(`sendZclFrameToEndpoint - message send with transSeq Nr.: ${zclFrame.Header.transactionSequenceNumber}`);
|
|
541
|
-
debug(command.hasOwnProperty('response') + ", " + zclFrame.Header.frameControl.disableDefaultResponse + ", " + disableResponse);
|
|
542
|
-
if (!command.hasOwnProperty('response') || zclFrame.Header.frameControl.disableDefaultResponse || !disableResponse) {
|
|
543
|
-
debug(
|
|
544
|
-
return Promise.resolve();
|
|
545
|
-
}
|
|
546
|
-
})
|
|
547
|
-
.catch(error => {
|
|
548
|
-
debug(`sendZclFrameToEndpoint ERROR`);
|
|
549
|
-
debug(error);
|
|
550
|
-
//return Promise.reject(new Error("sendZclFrameToEndpoint ERROR " + error));
|
|
551
|
-
});
|
|
552
|
-
try {
|
|
553
|
-
let data = null;
|
|
554
|
-
if (command.hasOwnProperty('response') && !disableResponse) {
|
|
555
|
-
data = await this.waitForData(networkAddress, 0x104, zclFrame.Cluster.ID, zclFrame.Header.transactionSequenceNumber, request.timeout);
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
const
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
request.
|
|
594
|
-
request.
|
|
595
|
-
request.
|
|
596
|
-
request.
|
|
597
|
-
request.
|
|
598
|
-
request.
|
|
599
|
-
request.
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
request.
|
|
619
|
-
request.
|
|
620
|
-
request.
|
|
621
|
-
request.
|
|
622
|
-
request.
|
|
623
|
-
request.
|
|
624
|
-
request.
|
|
625
|
-
request.
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
const
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
destArray =
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
request.
|
|
654
|
-
request.
|
|
655
|
-
request.
|
|
656
|
-
request.
|
|
657
|
-
request.
|
|
658
|
-
request.
|
|
659
|
-
request.
|
|
660
|
-
request.
|
|
661
|
-
request.
|
|
662
|
-
request
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
.
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
const
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
destArray =
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
request.
|
|
697
|
-
request.
|
|
698
|
-
request.
|
|
699
|
-
request.
|
|
700
|
-
request.
|
|
701
|
-
request.
|
|
702
|
-
request.
|
|
703
|
-
request.
|
|
704
|
-
request.
|
|
705
|
-
request
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
.
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
const
|
|
726
|
-
const
|
|
727
|
-
const
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
request.
|
|
732
|
-
request.
|
|
733
|
-
request.
|
|
734
|
-
request.
|
|
735
|
-
request.
|
|
736
|
-
request.
|
|
737
|
-
request.
|
|
738
|
-
request.
|
|
739
|
-
request
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
.
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
const
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
}
|
|
763
|
-
async
|
|
764
|
-
|
|
765
|
-
}
|
|
766
|
-
async
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
let
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
case
|
|
781
|
-
setChannelMask =
|
|
782
|
-
break;
|
|
783
|
-
case
|
|
784
|
-
setChannelMask =
|
|
785
|
-
break;
|
|
786
|
-
case
|
|
787
|
-
setChannelMask =
|
|
788
|
-
break;
|
|
789
|
-
case
|
|
790
|
-
setChannelMask =
|
|
791
|
-
break;
|
|
792
|
-
case
|
|
793
|
-
setChannelMask =
|
|
794
|
-
break;
|
|
795
|
-
case
|
|
796
|
-
setChannelMask =
|
|
797
|
-
break;
|
|
798
|
-
case
|
|
799
|
-
setChannelMask =
|
|
800
|
-
break;
|
|
801
|
-
case
|
|
802
|
-
setChannelMask =
|
|
803
|
-
break;
|
|
804
|
-
case
|
|
805
|
-
setChannelMask =
|
|
806
|
-
break;
|
|
807
|
-
case
|
|
808
|
-
setChannelMask =
|
|
809
|
-
break;
|
|
810
|
-
case
|
|
811
|
-
setChannelMask =
|
|
812
|
-
break;
|
|
813
|
-
case
|
|
814
|
-
setChannelMask =
|
|
815
|
-
break;
|
|
816
|
-
case
|
|
817
|
-
setChannelMask =
|
|
818
|
-
break;
|
|
819
|
-
case
|
|
820
|
-
setChannelMask =
|
|
821
|
-
break;
|
|
822
|
-
case
|
|
823
|
-
setChannelMask =
|
|
824
|
-
break;
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
await this.
|
|
833
|
-
await this.driver.
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
channel
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
await this.
|
|
847
|
-
await this.driver.
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
panid
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
await this.
|
|
862
|
-
await this.driver.
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
await this.
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
}
|
|
896
|
-
async
|
|
897
|
-
throw new Error("not supported");
|
|
898
|
-
}
|
|
899
|
-
async
|
|
900
|
-
throw new Error("not supported");
|
|
901
|
-
}
|
|
902
|
-
async
|
|
903
|
-
throw new Error("not supported");
|
|
904
|
-
}
|
|
905
|
-
async
|
|
906
|
-
throw new Error("not supported");
|
|
907
|
-
}
|
|
908
|
-
async
|
|
909
|
-
throw new Error("not supported");
|
|
910
|
-
}
|
|
911
|
-
async
|
|
912
|
-
throw new Error("not supported");
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
return new Promise(
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
}
|
|
1003
|
-
|
|
1004
|
-
this.emit(Events.Events.
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
return
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
payload.frame.
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
exports.default = DeconzAdapter;
|
|
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 debug_1 = __importDefault(require("debug"));
|
|
30
|
+
const adapter_1 = __importDefault(require("../../adapter"));
|
|
31
|
+
const debug = (0, debug_1.default)("zigbee-herdsman:deconz:adapter");
|
|
32
|
+
const driver_1 = __importDefault(require("../driver/driver"));
|
|
33
|
+
const zcl_1 = require("../../../zcl");
|
|
34
|
+
const Events = __importStar(require("../../events"));
|
|
35
|
+
const frameParser_1 = __importDefault(require("../driver/frameParser"));
|
|
36
|
+
const utils_1 = require("../../../utils");
|
|
37
|
+
const constants_1 = __importDefault(require("../driver/constants"));
|
|
38
|
+
var frameParser = require('../driver/frameParser');
|
|
39
|
+
;
|
|
40
|
+
class DeconzAdapter extends adapter_1.default {
|
|
41
|
+
constructor(networkOptions, serialPortOptions, backupPath, adapterOptions, logger) {
|
|
42
|
+
super(networkOptions, serialPortOptions, backupPath, adapterOptions, logger);
|
|
43
|
+
this.frameParserEvent = frameParser.frameParserEvents;
|
|
44
|
+
this.TX_OPTIONS = 0x00; // No APS ACKS
|
|
45
|
+
const concurrent = this.adapterOptions && this.adapterOptions.concurrent ?
|
|
46
|
+
this.adapterOptions.concurrent : 2;
|
|
47
|
+
// TODO: https://github.com/Koenkk/zigbee2mqtt/issues/4884#issuecomment-728903121
|
|
48
|
+
const delay = this.adapterOptions && typeof this.adapterOptions.delay === 'number' ?
|
|
49
|
+
this.adapterOptions.delay : 0;
|
|
50
|
+
this.waitress = new utils_1.Waitress(this.waitressValidator, this.waitressTimeoutFormatter);
|
|
51
|
+
this.driver = new driver_1.default(serialPortOptions.path);
|
|
52
|
+
this.driver.setDelay(delay);
|
|
53
|
+
if (delay >= 200) {
|
|
54
|
+
this.TX_OPTIONS = 0x04; // activate APS ACKS
|
|
55
|
+
}
|
|
56
|
+
this.driver.on('rxFrame', (frame) => { (0, frameParser_1.default)(frame); });
|
|
57
|
+
this.queue = new utils_1.Queue(concurrent);
|
|
58
|
+
this.transactionID = 0;
|
|
59
|
+
this.openRequestsQueue = [];
|
|
60
|
+
this.joinPermitted = false;
|
|
61
|
+
this.fwVersion = null;
|
|
62
|
+
this.frameParserEvent.on('receivedDataPayload', (data) => { this.checkReceivedDataPayload(data); });
|
|
63
|
+
this.frameParserEvent.on('receivedGreenPowerIndication', (data) => { this.checkReceivedGreenPowerIndication(data); });
|
|
64
|
+
const that = this;
|
|
65
|
+
setInterval(() => { that.checkReceivedDataPayload(null); }, 1000);
|
|
66
|
+
setTimeout(() => { that.checkCoordinatorSimpleDescriptor(false); }, 3000);
|
|
67
|
+
}
|
|
68
|
+
static async isValidPath(path) {
|
|
69
|
+
return driver_1.default.isValidPath(path);
|
|
70
|
+
}
|
|
71
|
+
static async autoDetectPath() {
|
|
72
|
+
return driver_1.default.autoDetectPath();
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Adapter methods
|
|
76
|
+
*/
|
|
77
|
+
async start() {
|
|
78
|
+
await this.driver.open();
|
|
79
|
+
return "resumed";
|
|
80
|
+
}
|
|
81
|
+
async stop() {
|
|
82
|
+
await this.driver.close();
|
|
83
|
+
}
|
|
84
|
+
async getCoordinator() {
|
|
85
|
+
const ieeeAddr = await this.driver.readParameterRequest(constants_1.default.PARAM.Network.MAC);
|
|
86
|
+
const nwkAddr = await this.driver.readParameterRequest(constants_1.default.PARAM.Network.NWK_ADDRESS);
|
|
87
|
+
const endpoints = [{
|
|
88
|
+
ID: 0x01,
|
|
89
|
+
profileID: 0x0104,
|
|
90
|
+
deviceID: 0x0005,
|
|
91
|
+
inputClusters: [0x0000, 0x000A, 0x0019],
|
|
92
|
+
outputClusters: [0x0001, 0x0020, 0x0500]
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
ID: 0xF2,
|
|
96
|
+
profileID: 0xA1E0,
|
|
97
|
+
deviceID: 0x0064,
|
|
98
|
+
inputClusters: [],
|
|
99
|
+
outputClusters: [0x0021]
|
|
100
|
+
}];
|
|
101
|
+
return {
|
|
102
|
+
networkAddress: nwkAddr,
|
|
103
|
+
manufacturerID: 0x1135,
|
|
104
|
+
ieeeAddr: ieeeAddr,
|
|
105
|
+
endpoints,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async permitJoin(seconds, networkAddress) {
|
|
109
|
+
const transactionID = this.nextTransactionID();
|
|
110
|
+
const request = {};
|
|
111
|
+
const zdpFrame = [transactionID, seconds, 0]; // tc_significance 1 or 0 ?
|
|
112
|
+
request.requestId = transactionID;
|
|
113
|
+
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
114
|
+
request.destAddr16 = networkAddress || 0xFFFC;
|
|
115
|
+
request.destEndpoint = 0;
|
|
116
|
+
request.profileId = 0;
|
|
117
|
+
request.clusterId = 0x36; // permit join
|
|
118
|
+
request.srcEndpoint = 0;
|
|
119
|
+
request.asduLength = 3;
|
|
120
|
+
request.asduPayload = zdpFrame;
|
|
121
|
+
request.txOptions = 0;
|
|
122
|
+
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
123
|
+
request.timeout = 5;
|
|
124
|
+
try {
|
|
125
|
+
await this.driver.enqueueSendDataRequest(request);
|
|
126
|
+
if (seconds === 0) {
|
|
127
|
+
this.joinPermitted = false;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
this.joinPermitted = true;
|
|
131
|
+
}
|
|
132
|
+
this.driver.writeParameterRequest(constants_1.default.PARAM.Network.PERMIT_JOIN, seconds);
|
|
133
|
+
debug("PERMIT_JOIN - " + seconds + " seconds");
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
const msg = "PERMIT_JOIN FAILED - " + error;
|
|
137
|
+
debug(msg);
|
|
138
|
+
// try again
|
|
139
|
+
this.permitJoin(seconds, networkAddress);
|
|
140
|
+
//return Promise.reject(new Error(msg)); // do not reject
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async getCoordinatorVersion() {
|
|
144
|
+
// product: number; transportrev: number; majorrel: number; minorrel: number; maintrel: number; revision: string;
|
|
145
|
+
if (this.fwVersion != null) {
|
|
146
|
+
return this.fwVersion;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
try {
|
|
150
|
+
const fw = await this.driver.readFirmwareVersionRequest();
|
|
151
|
+
const buf = Buffer.from(fw);
|
|
152
|
+
let fwString = "0x" + buf.readUInt32LE(0).toString(16);
|
|
153
|
+
const type = (fw[1] === 5) ? "ConBee/RaspBee" : "ConBee2/RaspBee2";
|
|
154
|
+
const meta = { "transportrev": 0, "product": 0, "majorrel": fw[3], "minorrel": fw[2], "maintrel": 0, "revision": fwString };
|
|
155
|
+
this.fwVersion = { type: type, meta: meta };
|
|
156
|
+
return { type: type, meta: meta };
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
debug("Get coordinator version Error: " + error);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async addInstallCode(ieeeAddress, key) {
|
|
164
|
+
return Promise.reject(new Error('Add install code is not supported'));
|
|
165
|
+
}
|
|
166
|
+
async reset(type) {
|
|
167
|
+
return Promise.reject(new Error('Reset is not supported'));
|
|
168
|
+
}
|
|
169
|
+
async lqi(networkAddress) {
|
|
170
|
+
const neighbors = [];
|
|
171
|
+
const add = (list) => {
|
|
172
|
+
for (const entry of list) {
|
|
173
|
+
const relationByte = entry.readUInt8(18);
|
|
174
|
+
const extAddr = [];
|
|
175
|
+
for (let i = 8; i < 16; i++) {
|
|
176
|
+
extAddr.push(entry[i]);
|
|
177
|
+
}
|
|
178
|
+
neighbors.push({
|
|
179
|
+
linkquality: entry.readUInt8(21),
|
|
180
|
+
networkAddress: entry.readUInt16LE(16),
|
|
181
|
+
ieeeAddr: this.driver.macAddrArrayToString(extAddr),
|
|
182
|
+
relationship: (relationByte >> 1) & ((1 << 3) - 1),
|
|
183
|
+
depth: entry.readUInt8(20)
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const request = async (startIndex) => {
|
|
188
|
+
const transactionID = this.nextTransactionID();
|
|
189
|
+
const req = {};
|
|
190
|
+
req.requestId = transactionID;
|
|
191
|
+
req.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
192
|
+
req.destAddr16 = networkAddress;
|
|
193
|
+
req.destEndpoint = 0;
|
|
194
|
+
req.profileId = 0;
|
|
195
|
+
req.clusterId = 0x31; // mgmt_lqi_request
|
|
196
|
+
req.srcEndpoint = 0;
|
|
197
|
+
req.asduLength = 2;
|
|
198
|
+
req.asduPayload = [transactionID, startIndex];
|
|
199
|
+
req.txOptions = 0;
|
|
200
|
+
req.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
201
|
+
this.driver.enqueueSendDataRequest(req)
|
|
202
|
+
.then(result => { })
|
|
203
|
+
.catch(error => { });
|
|
204
|
+
try {
|
|
205
|
+
const d = await this.waitForData(networkAddress, 0, 0x8031);
|
|
206
|
+
const data = d.asduPayload;
|
|
207
|
+
if (data[1] !== 0) { // status
|
|
208
|
+
throw new Error(`LQI for '${networkAddress}' failed`);
|
|
209
|
+
}
|
|
210
|
+
const tableList = [];
|
|
211
|
+
const response = {
|
|
212
|
+
status: data[1],
|
|
213
|
+
tableEntrys: data[2],
|
|
214
|
+
startIndex: data[3],
|
|
215
|
+
tableListCount: data[4],
|
|
216
|
+
tableList: tableList
|
|
217
|
+
};
|
|
218
|
+
let tableEntry = [];
|
|
219
|
+
let counter = 0;
|
|
220
|
+
for (let i = 5; i < ((response.tableListCount * 22) + 5); i++) { // one tableentry = 22 bytes
|
|
221
|
+
tableEntry.push(data[i]);
|
|
222
|
+
counter++;
|
|
223
|
+
if (counter === 22) {
|
|
224
|
+
response.tableList.push(Buffer.from(tableEntry));
|
|
225
|
+
tableEntry = [];
|
|
226
|
+
counter = 0;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
debug("LQI RESPONSE - addr: 0x" + networkAddress.toString(16) + " status: " + response.status + " read " + (response.tableListCount + response.startIndex) + "/" + response.tableEntrys + " entrys");
|
|
230
|
+
return response;
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
const msg = "LQI REQUEST FAILED - addr: 0x" + networkAddress.toString(16) + " " + error;
|
|
234
|
+
debug(msg);
|
|
235
|
+
return Promise.reject(new Error(msg));
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
let response = await request(0);
|
|
239
|
+
add(response.tableList);
|
|
240
|
+
let nextStartIndex = response.tableListCount;
|
|
241
|
+
while (neighbors.length < response.tableEntrys) {
|
|
242
|
+
response = await request(nextStartIndex);
|
|
243
|
+
add(response.tableList);
|
|
244
|
+
nextStartIndex += response.tableListCount;
|
|
245
|
+
}
|
|
246
|
+
return { neighbors };
|
|
247
|
+
}
|
|
248
|
+
async routingTable(networkAddress) {
|
|
249
|
+
const table = [];
|
|
250
|
+
const statusLookup = {
|
|
251
|
+
0: 'ACTIVE',
|
|
252
|
+
1: 'DISCOVERY_UNDERWAY',
|
|
253
|
+
2: 'DISCOVERY_FAILED',
|
|
254
|
+
3: 'INACTIVE',
|
|
255
|
+
};
|
|
256
|
+
const add = (list) => {
|
|
257
|
+
for (const entry of list) {
|
|
258
|
+
const statusByte = entry.readUInt8(2);
|
|
259
|
+
const extAddr = [];
|
|
260
|
+
for (let i = 8; i < 16; i++) {
|
|
261
|
+
extAddr.push(entry[i]);
|
|
262
|
+
}
|
|
263
|
+
table.push({
|
|
264
|
+
destinationAddress: entry.readUInt16LE(0),
|
|
265
|
+
status: statusLookup[(statusByte >> 5) & ((1 << 3) - 1)],
|
|
266
|
+
nextHop: entry.readUInt16LE(3)
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
const request = async (startIndex) => {
|
|
271
|
+
const transactionID = this.nextTransactionID();
|
|
272
|
+
const req = {};
|
|
273
|
+
req.requestId = transactionID;
|
|
274
|
+
req.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
275
|
+
req.destAddr16 = networkAddress;
|
|
276
|
+
req.destEndpoint = 0;
|
|
277
|
+
req.profileId = 0;
|
|
278
|
+
req.clusterId = 0x32; // mgmt_rtg_request
|
|
279
|
+
req.srcEndpoint = 0;
|
|
280
|
+
req.asduLength = 2;
|
|
281
|
+
req.asduPayload = [transactionID, startIndex];
|
|
282
|
+
req.txOptions = 0;
|
|
283
|
+
req.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
284
|
+
req.timeout = 30;
|
|
285
|
+
this.driver.enqueueSendDataRequest(req)
|
|
286
|
+
.then(result => { })
|
|
287
|
+
.catch(error => { });
|
|
288
|
+
try {
|
|
289
|
+
const d = await this.waitForData(networkAddress, 0, 0x8032);
|
|
290
|
+
const data = d.asduPayload;
|
|
291
|
+
if (data[1] !== 0) { // status
|
|
292
|
+
throw new Error(`Routingtables for '${networkAddress}' failed`);
|
|
293
|
+
}
|
|
294
|
+
const tableList = [];
|
|
295
|
+
const response = {
|
|
296
|
+
status: data[1],
|
|
297
|
+
tableEntrys: data[2],
|
|
298
|
+
startIndex: data[3],
|
|
299
|
+
tableListCount: data[4],
|
|
300
|
+
tableList: tableList
|
|
301
|
+
};
|
|
302
|
+
let tableEntry = [];
|
|
303
|
+
let counter = 0;
|
|
304
|
+
for (let i = 5; i < ((response.tableListCount * 5) + 5); i++) { // one tableentry = 5 bytes
|
|
305
|
+
tableEntry.push(data[i]);
|
|
306
|
+
counter++;
|
|
307
|
+
if (counter === 5) {
|
|
308
|
+
response.tableList.push(Buffer.from(tableEntry));
|
|
309
|
+
tableEntry = [];
|
|
310
|
+
counter = 0;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
debug("ROUTING_TABLE RESPONSE - addr: 0x" + networkAddress.toString(16) + " status: " + response.status + " read " + (response.tableListCount + response.startIndex) + "/" + response.tableEntrys + " entrys");
|
|
314
|
+
return response;
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
const msg = "ROUTING_TABLE REQUEST FAILED - addr: 0x" + networkAddress.toString(16) + " " + error;
|
|
318
|
+
debug(msg);
|
|
319
|
+
return Promise.reject(new Error(msg));
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
let response = await request(0);
|
|
323
|
+
add(response.tableList);
|
|
324
|
+
let nextStartIndex = response.tableListCount;
|
|
325
|
+
while (table.length < response.tableEntrys) {
|
|
326
|
+
response = await request(nextStartIndex);
|
|
327
|
+
add(response.tableList);
|
|
328
|
+
nextStartIndex += response.tableListCount;
|
|
329
|
+
}
|
|
330
|
+
return { table };
|
|
331
|
+
}
|
|
332
|
+
async nodeDescriptor(networkAddress) {
|
|
333
|
+
const transactionID = this.nextTransactionID();
|
|
334
|
+
const nwk1 = networkAddress & 0xff;
|
|
335
|
+
const nwk2 = (networkAddress >> 8) & 0xff;
|
|
336
|
+
const request = {};
|
|
337
|
+
const zdpFrame = [transactionID, nwk1, nwk2];
|
|
338
|
+
request.requestId = transactionID;
|
|
339
|
+
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
340
|
+
request.destAddr16 = networkAddress;
|
|
341
|
+
request.destEndpoint = 0;
|
|
342
|
+
request.profileId = 0;
|
|
343
|
+
request.clusterId = 0x02; // node descriptor
|
|
344
|
+
request.srcEndpoint = 0;
|
|
345
|
+
request.asduLength = 3;
|
|
346
|
+
request.asduPayload = zdpFrame;
|
|
347
|
+
request.txOptions = 0;
|
|
348
|
+
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
349
|
+
request.timeout = 30;
|
|
350
|
+
this.driver.enqueueSendDataRequest(request)
|
|
351
|
+
.then(result => { })
|
|
352
|
+
.catch(error => { });
|
|
353
|
+
try {
|
|
354
|
+
const d = await this.waitForData(networkAddress, 0, 0x8002);
|
|
355
|
+
const data = d.asduPayload;
|
|
356
|
+
const buf = Buffer.from(data);
|
|
357
|
+
const logicaltype = (data[4] & 7);
|
|
358
|
+
const type = (logicaltype === 1) ? 'Router' : (logicaltype === 2) ? 'EndDevice' : (logicaltype === 0) ? 'Coordinator' : 'Unknown';
|
|
359
|
+
const manufacturer = buf.readUInt16LE(7);
|
|
360
|
+
debug("RECEIVING NODE_DESCRIPTOR - addr: 0x" + networkAddress.toString(16) + " type: " + type + " manufacturer: 0x" + manufacturer.toString(16));
|
|
361
|
+
return { manufacturerCode: manufacturer, type };
|
|
362
|
+
}
|
|
363
|
+
catch (error) {
|
|
364
|
+
const msg = "RECEIVING NODE_DESCRIPTOR FAILED - addr: 0x" + networkAddress.toString(16) + " " + error;
|
|
365
|
+
debug(msg);
|
|
366
|
+
return Promise.reject(new Error(msg));
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
async activeEndpoints(networkAddress) {
|
|
370
|
+
const transactionID = this.nextTransactionID();
|
|
371
|
+
const nwk1 = networkAddress & 0xff;
|
|
372
|
+
const nwk2 = (networkAddress >> 8) & 0xff;
|
|
373
|
+
const request = {};
|
|
374
|
+
const zdpFrame = [transactionID, nwk1, nwk2];
|
|
375
|
+
request.requestId = transactionID;
|
|
376
|
+
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
377
|
+
request.destAddr16 = networkAddress;
|
|
378
|
+
request.destEndpoint = 0;
|
|
379
|
+
request.profileId = 0;
|
|
380
|
+
request.clusterId = 0x05; // active endpoints
|
|
381
|
+
request.srcEndpoint = 0;
|
|
382
|
+
request.asduLength = 3;
|
|
383
|
+
request.asduPayload = zdpFrame;
|
|
384
|
+
request.txOptions = 0;
|
|
385
|
+
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
386
|
+
request.timeout = 30;
|
|
387
|
+
this.driver.enqueueSendDataRequest(request)
|
|
388
|
+
.then(result => { })
|
|
389
|
+
.catch(error => { });
|
|
390
|
+
try {
|
|
391
|
+
const d = await this.waitForData(networkAddress, 0, 0x8005);
|
|
392
|
+
const data = d.asduPayload;
|
|
393
|
+
const buf = Buffer.from(data);
|
|
394
|
+
const epCount = buf.readUInt8(4);
|
|
395
|
+
const epList = [];
|
|
396
|
+
for (let i = 5; i < (epCount + 5); i++) {
|
|
397
|
+
epList.push(buf.readUInt8(i));
|
|
398
|
+
}
|
|
399
|
+
debug("ACTIVE_ENDPOINTS - addr: 0x" + networkAddress.toString(16) + " EP list: " + epList);
|
|
400
|
+
return { endpoints: epList };
|
|
401
|
+
}
|
|
402
|
+
catch (error) {
|
|
403
|
+
const msg = "READING ACTIVE_ENDPOINTS FAILED - addr: 0x" + networkAddress.toString(16) + " " + error;
|
|
404
|
+
debug(msg);
|
|
405
|
+
return Promise.reject(new Error(msg));
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
async simpleDescriptor(networkAddress, endpointID) {
|
|
409
|
+
const transactionID = this.nextTransactionID();
|
|
410
|
+
const nwk1 = networkAddress & 0xff;
|
|
411
|
+
const nwk2 = (networkAddress >> 8) & 0xff;
|
|
412
|
+
const request = {};
|
|
413
|
+
const zdpFrame = [transactionID, nwk1, nwk2, endpointID];
|
|
414
|
+
request.requestId = transactionID;
|
|
415
|
+
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
416
|
+
request.destAddr16 = networkAddress;
|
|
417
|
+
request.destEndpoint = 0;
|
|
418
|
+
request.profileId = 0;
|
|
419
|
+
request.clusterId = 0x04; // simple descriptor
|
|
420
|
+
request.srcEndpoint = 0;
|
|
421
|
+
request.asduLength = 4;
|
|
422
|
+
request.asduPayload = zdpFrame;
|
|
423
|
+
request.txOptions = 0;
|
|
424
|
+
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
425
|
+
request.timeout = 30;
|
|
426
|
+
this.driver.enqueueSendDataRequest(request)
|
|
427
|
+
.then(result => { })
|
|
428
|
+
.catch(error => { });
|
|
429
|
+
try {
|
|
430
|
+
const d = await this.waitForData(networkAddress, 0, 0x8004);
|
|
431
|
+
const data = d.asduPayload;
|
|
432
|
+
const buf = Buffer.from(data);
|
|
433
|
+
const inCount = buf.readUInt8(11);
|
|
434
|
+
const inClusters = [];
|
|
435
|
+
let cIndex = 12;
|
|
436
|
+
for (let i = 0; i < inCount; i++) {
|
|
437
|
+
inClusters[i] = buf.readUInt16LE(cIndex);
|
|
438
|
+
cIndex += 2;
|
|
439
|
+
}
|
|
440
|
+
const outCount = buf.readUInt8(12 + (inCount * 2));
|
|
441
|
+
const outClusters = [];
|
|
442
|
+
cIndex = 13 + (inCount * 2);
|
|
443
|
+
for (let l = 0; l < outCount; l++) {
|
|
444
|
+
outClusters[l] = buf.readUInt16LE(cIndex);
|
|
445
|
+
cIndex += 2;
|
|
446
|
+
}
|
|
447
|
+
const simpleDesc = {
|
|
448
|
+
profileID: buf.readUInt16LE(6),
|
|
449
|
+
endpointID: buf.readUInt8(5),
|
|
450
|
+
deviceID: buf.readUInt16LE(8),
|
|
451
|
+
inputClusters: inClusters,
|
|
452
|
+
outputClusters: outClusters
|
|
453
|
+
};
|
|
454
|
+
debug("RECEIVING SIMPLE_DESCRIPTOR - addr: 0x" + networkAddress.toString(16) + " EP:" + simpleDesc.endpointID + " inClusters: " + inClusters + " outClusters: " + outClusters);
|
|
455
|
+
return simpleDesc;
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
const msg = "RECEIVING SIMPLE_DESCRIPTOR FAILED - addr: 0x" + networkAddress.toString(16) + " " + error;
|
|
459
|
+
debug(msg);
|
|
460
|
+
return Promise.reject(new Error(msg));
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
async checkCoordinatorSimpleDescriptor(skip) {
|
|
464
|
+
debug("checking coordinator simple descriptor");
|
|
465
|
+
var simpleDesc = null;
|
|
466
|
+
if (skip === false) {
|
|
467
|
+
try {
|
|
468
|
+
simpleDesc = await this.simpleDescriptor(0x0, 1);
|
|
469
|
+
}
|
|
470
|
+
catch (error) {
|
|
471
|
+
}
|
|
472
|
+
if (simpleDesc === null) {
|
|
473
|
+
this.checkCoordinatorSimpleDescriptor(false);
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
debug("EP: " + simpleDesc.endpointID);
|
|
477
|
+
debug("profile ID: " + simpleDesc.profileID);
|
|
478
|
+
debug("device ID: " + simpleDesc.deviceID);
|
|
479
|
+
for (let i = 0; i < simpleDesc.inputClusters.length; i++) {
|
|
480
|
+
debug("input cluster: 0x" + simpleDesc.inputClusters[i].toString(16));
|
|
481
|
+
}
|
|
482
|
+
for (let o = 0; o < simpleDesc.outputClusters.length; o++) {
|
|
483
|
+
debug("output cluster: 0x" + simpleDesc.outputClusters[o].toString(16));
|
|
484
|
+
}
|
|
485
|
+
let ok = true;
|
|
486
|
+
if (simpleDesc.endpointID === 0x1) {
|
|
487
|
+
if (!simpleDesc.inputClusters.includes(0x0) || !simpleDesc.inputClusters.includes(0x0A) || !simpleDesc.inputClusters.includes(0x19) ||
|
|
488
|
+
!simpleDesc.outputClusters.includes(0x01) || !simpleDesc.outputClusters.includes(0x20) || !simpleDesc.outputClusters.includes(0x500)) {
|
|
489
|
+
debug("missing cluster");
|
|
490
|
+
ok = false;
|
|
491
|
+
}
|
|
492
|
+
if (ok === true) {
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
debug("setting new simple descriptor");
|
|
498
|
+
try { //[ sd1 ep proId devId vers #inCl iCl1 iCl2 iCl3 #outC oCl1 oCl2 oCl3 ]
|
|
499
|
+
const sd = [0x00, 0x01, 0x04, 0x01, 0x05, 0x00, 0x01, 0x03, 0x00, 0x00, 0x0A, 0x00, 0x19, 0x00, 0x03, 0x01, 0x00, 0x20, 0x00, 0x00, 0x05];
|
|
500
|
+
const sd1 = sd.reverse();
|
|
501
|
+
await this.driver.writeParameterRequest(constants_1.default.PARAM.STK.Endpoint, sd1);
|
|
502
|
+
}
|
|
503
|
+
catch (error) {
|
|
504
|
+
debug("error setting simple descriptor - try again");
|
|
505
|
+
this.checkCoordinatorSimpleDescriptor(true);
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
debug("success setting simple descriptor");
|
|
509
|
+
}
|
|
510
|
+
waitFor(networkAddress, endpoint, frameType, direction, transactionSequenceNumber, clusterID, commandIdentifier, timeout) {
|
|
511
|
+
const payload = {
|
|
512
|
+
address: networkAddress, endpoint, clusterID, commandIdentifier, frameType, direction,
|
|
513
|
+
transactionSequenceNumber,
|
|
514
|
+
};
|
|
515
|
+
const waiter = this.waitress.waitFor(payload, timeout);
|
|
516
|
+
const cancel = () => this.waitress.remove(waiter.ID);
|
|
517
|
+
return { promise: waiter.start().promise, cancel };
|
|
518
|
+
}
|
|
519
|
+
async sendZclFrameToEndpoint(ieeeAddr, networkAddress, endpoint, zclFrame, timeout, disableResponse, disableRecovery, sourceEndpoint) {
|
|
520
|
+
const transactionID = this.nextTransactionID();
|
|
521
|
+
const request = {};
|
|
522
|
+
let pay = zclFrame.toBuffer();
|
|
523
|
+
//console.log("zclFramte.toBuffer:");
|
|
524
|
+
//console.log(pay);
|
|
525
|
+
request.requestId = transactionID;
|
|
526
|
+
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
527
|
+
request.destAddr16 = networkAddress;
|
|
528
|
+
request.destEndpoint = endpoint;
|
|
529
|
+
request.profileId = sourceEndpoint === 242 && endpoint === 242 ? 0xa1e0 : 0x104;
|
|
530
|
+
request.clusterId = zclFrame.Cluster.ID;
|
|
531
|
+
request.srcEndpoint = sourceEndpoint || 1;
|
|
532
|
+
request.asduLength = pay.length;
|
|
533
|
+
request.asduPayload = [...pay];
|
|
534
|
+
request.txOptions = this.TX_OPTIONS; // 0x00 normal; 0x04 APS ACK
|
|
535
|
+
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
536
|
+
request.timeout = timeout;
|
|
537
|
+
const command = zclFrame.getCommand();
|
|
538
|
+
this.driver.enqueueSendDataRequest(request)
|
|
539
|
+
.then(result => {
|
|
540
|
+
debug(`sendZclFrameToEndpoint - message send with transSeq Nr.: ${zclFrame.Header.transactionSequenceNumber}`);
|
|
541
|
+
debug(command.hasOwnProperty('response') + ", " + zclFrame.Header.frameControl.disableDefaultResponse + ", " + disableResponse + ", " + request.timeout);
|
|
542
|
+
if (!command.hasOwnProperty('response') || zclFrame.Header.frameControl.disableDefaultResponse || !disableResponse) {
|
|
543
|
+
debug(`resolve request (${zclFrame.Header.transactionSequenceNumber})`);
|
|
544
|
+
return Promise.resolve();
|
|
545
|
+
}
|
|
546
|
+
})
|
|
547
|
+
.catch(error => {
|
|
548
|
+
debug(`sendZclFrameToEndpoint ERROR (${zclFrame.Header.transactionSequenceNumber})`);
|
|
549
|
+
debug(error);
|
|
550
|
+
//return Promise.reject(new Error("sendZclFrameToEndpoint ERROR " + error));
|
|
551
|
+
});
|
|
552
|
+
try {
|
|
553
|
+
let data = null;
|
|
554
|
+
if ((command.hasOwnProperty('response') && !disableResponse) || !zclFrame.Header.frameControl.disableDefaultResponse) {
|
|
555
|
+
data = await this.waitForData(networkAddress, 0x104, zclFrame.Cluster.ID, zclFrame.Header.transactionSequenceNumber, request.timeout);
|
|
556
|
+
}
|
|
557
|
+
if (data !== null) {
|
|
558
|
+
const asdu = data.asduPayload;
|
|
559
|
+
const buffer = Buffer.from(asdu);
|
|
560
|
+
const frame = zcl_1.ZclFrame.fromBuffer(zclFrame.Cluster.ID, buffer);
|
|
561
|
+
const response = {
|
|
562
|
+
address: (data.srcAddrMode === 0x02) ? data.srcAddr16 : null,
|
|
563
|
+
frame: frame,
|
|
564
|
+
endpoint: data.srcEndpoint,
|
|
565
|
+
linkquality: data.lqi,
|
|
566
|
+
groupID: (data.srcAddrMode === 0x01) ? data.srcAddr16 : null,
|
|
567
|
+
wasBroadcast: data.srcAddrMode === 0x01 || data.srcAddrMode === 0xF,
|
|
568
|
+
destinationEndpoint: data.destEndpoint,
|
|
569
|
+
};
|
|
570
|
+
debug(`response received (${zclFrame.Header.transactionSequenceNumber})`);
|
|
571
|
+
return response;
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
debug(`no response expected (${zclFrame.Header.transactionSequenceNumber})`);
|
|
575
|
+
return null;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
catch (error) {
|
|
579
|
+
throw new Error(`no response received (${zclFrame.Header.transactionSequenceNumber})`);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
async sendZclFrameToGroup(groupID, zclFrame) {
|
|
583
|
+
const transactionID = this.nextTransactionID();
|
|
584
|
+
const request = {};
|
|
585
|
+
let pay = zclFrame.toBuffer();
|
|
586
|
+
debug("zclFrame to group - zclFrame.payload:");
|
|
587
|
+
debug(zclFrame.Payload);
|
|
588
|
+
//console.log("zclFramte.toBuffer:");
|
|
589
|
+
//console.log(pay);
|
|
590
|
+
request.requestId = transactionID;
|
|
591
|
+
request.destAddrMode = constants_1.default.PARAM.addressMode.GROUP_ADDR;
|
|
592
|
+
request.destAddr16 = groupID;
|
|
593
|
+
request.profileId = 0x104;
|
|
594
|
+
request.clusterId = zclFrame.Cluster.ID;
|
|
595
|
+
request.srcEndpoint = 1;
|
|
596
|
+
request.asduLength = pay.length;
|
|
597
|
+
request.asduPayload = [...pay];
|
|
598
|
+
request.txOptions = 0;
|
|
599
|
+
request.radius = constants_1.default.PARAM.txRadius.UNLIMITED;
|
|
600
|
+
try {
|
|
601
|
+
debug(`sendZclFrameToGroup - message send`);
|
|
602
|
+
return this.driver.enqueueSendDataRequest(request);
|
|
603
|
+
}
|
|
604
|
+
catch (error) {
|
|
605
|
+
//debug(`sendZclFrameToGroup ERROR: ${error}`);
|
|
606
|
+
throw new Error(error);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
async sendZclFrameToAll(endpoint, zclFrame, sourceEndpoint) {
|
|
610
|
+
const transactionID = this.nextTransactionID();
|
|
611
|
+
const request = {};
|
|
612
|
+
let pay = zclFrame.toBuffer();
|
|
613
|
+
debug("zclFrame to all - zclFrame.payload:");
|
|
614
|
+
debug(zclFrame.Payload);
|
|
615
|
+
request.requestId = transactionID;
|
|
616
|
+
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
617
|
+
request.destAddr16 = 0xFFFD;
|
|
618
|
+
request.destEndpoint = endpoint;
|
|
619
|
+
request.profileId = sourceEndpoint === 242 && endpoint === 242 ? 0xa1e0 : 0x104;
|
|
620
|
+
request.clusterId = zclFrame.Cluster.ID;
|
|
621
|
+
request.srcEndpoint = sourceEndpoint;
|
|
622
|
+
request.asduLength = pay.length;
|
|
623
|
+
request.asduPayload = [...pay];
|
|
624
|
+
request.txOptions = 0;
|
|
625
|
+
request.radius = constants_1.default.PARAM.txRadius.UNLIMITED;
|
|
626
|
+
try {
|
|
627
|
+
debug(`sendZclFrameToAll - message send`);
|
|
628
|
+
return this.driver.enqueueSendDataRequest(request);
|
|
629
|
+
}
|
|
630
|
+
catch (error) {
|
|
631
|
+
//debug(`sendZclFrameToAll ERROR: ${error}`);
|
|
632
|
+
throw new Error(error);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
async bind(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, destinationAddressOrGroup, type, destinationEndpoint) {
|
|
636
|
+
const transactionID = this.nextTransactionID();
|
|
637
|
+
const clid1 = clusterID & 0xff;
|
|
638
|
+
const clid2 = (clusterID >> 8) & 0xff;
|
|
639
|
+
const destAddrMode = (type === 'group') ? constants_1.default.PARAM.addressMode.GROUP_ADDR : constants_1.default.PARAM.addressMode.IEEE_ADDR;
|
|
640
|
+
let destArray;
|
|
641
|
+
if (type === 'endpoint') {
|
|
642
|
+
destArray = this.driver.macAddrStringToArray(destinationAddressOrGroup);
|
|
643
|
+
destArray = destArray.concat([destinationEndpoint]);
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
destArray = [destinationAddressOrGroup, (destinationAddressOrGroup >> 8) & 0xff];
|
|
647
|
+
}
|
|
648
|
+
const request = {};
|
|
649
|
+
const zdpFrame = [transactionID].concat(this.driver.macAddrStringToArray(sourceIeeeAddress)).concat([sourceEndpoint, clid1, clid2, destAddrMode]).concat(destArray);
|
|
650
|
+
request.requestId = transactionID;
|
|
651
|
+
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
652
|
+
request.destAddr16 = destinationNetworkAddress;
|
|
653
|
+
request.destEndpoint = 0;
|
|
654
|
+
request.profileId = 0;
|
|
655
|
+
request.clusterId = 0x21; // bind_request
|
|
656
|
+
request.srcEndpoint = 0;
|
|
657
|
+
request.asduLength = zdpFrame.length;
|
|
658
|
+
request.asduPayload = zdpFrame;
|
|
659
|
+
request.txOptions = 0x04; // 0x04 use APS ACKS
|
|
660
|
+
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
661
|
+
request.timeout = 30;
|
|
662
|
+
this.driver.enqueueSendDataRequest(request)
|
|
663
|
+
.then(result => { })
|
|
664
|
+
.catch(error => { });
|
|
665
|
+
try {
|
|
666
|
+
const d = await this.waitForData(destinationNetworkAddress, 0, 0x8021);
|
|
667
|
+
const data = d.asduPayload;
|
|
668
|
+
debug("BIND RESPONSE - addr: 0x" + destinationNetworkAddress.toString(16) + " status: " + data[1]);
|
|
669
|
+
if (data[1] !== 0) {
|
|
670
|
+
throw new Error("status: " + data[1]);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
catch (error) {
|
|
674
|
+
debug("BIND FAILED - addr: 0x" + destinationNetworkAddress.toString(16) + " " + error);
|
|
675
|
+
throw new Error(error);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
async unbind(destinationNetworkAddress, sourceIeeeAddress, sourceEndpoint, clusterID, destinationAddressOrGroup, type, destinationEndpoint) {
|
|
679
|
+
const transactionID = this.nextTransactionID();
|
|
680
|
+
const clid1 = clusterID & 0xff;
|
|
681
|
+
const clid2 = (clusterID >> 8) & 0xff;
|
|
682
|
+
const destAddrMode = (type === 'group') ? constants_1.default.PARAM.addressMode.GROUP_ADDR : constants_1.default.PARAM.addressMode.IEEE_ADDR;
|
|
683
|
+
let destArray;
|
|
684
|
+
if (type === 'endpoint') {
|
|
685
|
+
destArray = this.driver.macAddrStringToArray(destinationAddressOrGroup);
|
|
686
|
+
destArray = destArray.concat([destinationEndpoint]);
|
|
687
|
+
}
|
|
688
|
+
else {
|
|
689
|
+
destArray = [destinationAddressOrGroup, (destinationAddressOrGroup >> 8) & 0xff];
|
|
690
|
+
}
|
|
691
|
+
const request = {};
|
|
692
|
+
const zdpFrame = [transactionID].concat(this.driver.macAddrStringToArray(sourceIeeeAddress)).concat([sourceEndpoint, clid1, clid2, destAddrMode]).concat(destArray);
|
|
693
|
+
request.requestId = transactionID;
|
|
694
|
+
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
695
|
+
request.destAddr16 = destinationNetworkAddress;
|
|
696
|
+
request.destEndpoint = 0;
|
|
697
|
+
request.profileId = 0;
|
|
698
|
+
request.clusterId = 0x22; // unbind_request
|
|
699
|
+
request.srcEndpoint = 0;
|
|
700
|
+
request.asduLength = zdpFrame.length;
|
|
701
|
+
request.asduPayload = zdpFrame;
|
|
702
|
+
request.txOptions = 0x04; // 0x04 use APS ACKS
|
|
703
|
+
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
704
|
+
request.timeout = 30;
|
|
705
|
+
this.driver.enqueueSendDataRequest(request)
|
|
706
|
+
.then(result => { })
|
|
707
|
+
.catch(error => { });
|
|
708
|
+
try {
|
|
709
|
+
const d = await this.waitForData(destinationNetworkAddress, 0, 0x8022);
|
|
710
|
+
const data = d.asduPayload;
|
|
711
|
+
debug("UNBIND RESPONSE - addr: 0x" + destinationNetworkAddress.toString(16) + " status: " + data[1]);
|
|
712
|
+
if (data[1] !== 0) {
|
|
713
|
+
throw new Error("status: " + data[1]);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
catch (error) {
|
|
717
|
+
debug("UNBIND FAILED - addr: 0x" + destinationNetworkAddress.toString(16) + " " + error);
|
|
718
|
+
throw new Error(error);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
async removeDevice(networkAddress, ieeeAddr) {
|
|
722
|
+
const transactionID = this.nextTransactionID();
|
|
723
|
+
const nwk1 = networkAddress & 0xff;
|
|
724
|
+
const nwk2 = (networkAddress >> 8) & 0xff;
|
|
725
|
+
const request = {};
|
|
726
|
+
//const zdpFrame = [transactionID].concat(this.driver.macAddrStringToArray(ieeeAddr)).concat([0]);
|
|
727
|
+
const zdpFrame = [transactionID].concat([0, 0, 0, 0, 0, 0, 0, 0]).concat([0]);
|
|
728
|
+
request.requestId = transactionID;
|
|
729
|
+
request.destAddrMode = constants_1.default.PARAM.addressMode.NWK_ADDR;
|
|
730
|
+
request.destAddr16 = networkAddress;
|
|
731
|
+
request.destEndpoint = 0;
|
|
732
|
+
request.profileId = 0;
|
|
733
|
+
request.clusterId = 0x34; // mgmt_leave_request
|
|
734
|
+
request.srcEndpoint = 0;
|
|
735
|
+
request.asduLength = 10;
|
|
736
|
+
request.asduPayload = zdpFrame;
|
|
737
|
+
request.txOptions = 0;
|
|
738
|
+
request.radius = constants_1.default.PARAM.txRadius.DEFAULT_RADIUS;
|
|
739
|
+
this.driver.enqueueSendDataRequest(request)
|
|
740
|
+
.then(result => { })
|
|
741
|
+
.catch(error => { });
|
|
742
|
+
try {
|
|
743
|
+
const d = await this.waitForData(networkAddress, 0, 0x8034);
|
|
744
|
+
const data = d.asduPayload;
|
|
745
|
+
debug("REMOVE_DEVICE - addr: 0x" + networkAddress.toString(16) + " status: " + data[1]);
|
|
746
|
+
const payload = {
|
|
747
|
+
networkAddress: networkAddress,
|
|
748
|
+
ieeeAddr: ieeeAddr,
|
|
749
|
+
};
|
|
750
|
+
if (data[1] !== 0) {
|
|
751
|
+
throw new Error("status: " + data[1]);
|
|
752
|
+
}
|
|
753
|
+
this.emit(Events.Events.deviceLeave, payload);
|
|
754
|
+
}
|
|
755
|
+
catch (error) {
|
|
756
|
+
debug("REMOVE_DEVICE FAILED - addr: 0x" + networkAddress.toString(16) + " " + error);
|
|
757
|
+
throw new Error(error);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
async supportsBackup() {
|
|
761
|
+
return false;
|
|
762
|
+
}
|
|
763
|
+
async backup() {
|
|
764
|
+
throw new Error("This adapter does not support backup");
|
|
765
|
+
}
|
|
766
|
+
async getNetworkParameters() {
|
|
767
|
+
try {
|
|
768
|
+
let panid = await this.driver.readParameterRequest(constants_1.default.PARAM.Network.PAN_ID);
|
|
769
|
+
let expanid = await this.driver.readParameterRequest(constants_1.default.PARAM.Network.APS_EXT_PAN_ID);
|
|
770
|
+
let channel = await this.driver.readParameterRequest(constants_1.default.PARAM.Network.CHANNEL);
|
|
771
|
+
let networkKey = await this.driver.readParameterRequest(constants_1.default.PARAM.Network.NETWORK_KEY);
|
|
772
|
+
// check current channel against configuration.yaml
|
|
773
|
+
if (this.networkOptions.channelList[0] !== channel) {
|
|
774
|
+
debug("Channel in configuration.yaml (" + this.networkOptions.channelList[0] + ") differs from current channel (" + channel + "). Changing channel.");
|
|
775
|
+
let setChannelMask = 0;
|
|
776
|
+
switch (this.networkOptions.channelList[0]) {
|
|
777
|
+
case 11:
|
|
778
|
+
setChannelMask = 0x800;
|
|
779
|
+
break;
|
|
780
|
+
case 12:
|
|
781
|
+
setChannelMask = 0x1000;
|
|
782
|
+
break;
|
|
783
|
+
case 13:
|
|
784
|
+
setChannelMask = 0x2000;
|
|
785
|
+
break;
|
|
786
|
+
case 14:
|
|
787
|
+
setChannelMask = 0x4000;
|
|
788
|
+
break;
|
|
789
|
+
case 15:
|
|
790
|
+
setChannelMask = 0x8000;
|
|
791
|
+
break;
|
|
792
|
+
case 16:
|
|
793
|
+
setChannelMask = 0x10000;
|
|
794
|
+
break;
|
|
795
|
+
case 17:
|
|
796
|
+
setChannelMask = 0x20000;
|
|
797
|
+
break;
|
|
798
|
+
case 18:
|
|
799
|
+
setChannelMask = 0x40000;
|
|
800
|
+
break;
|
|
801
|
+
case 19:
|
|
802
|
+
setChannelMask = 0x80000;
|
|
803
|
+
break;
|
|
804
|
+
case 20:
|
|
805
|
+
setChannelMask = 0x100000;
|
|
806
|
+
break;
|
|
807
|
+
case 21:
|
|
808
|
+
setChannelMask = 0x200000;
|
|
809
|
+
break;
|
|
810
|
+
case 22:
|
|
811
|
+
setChannelMask = 0x400000;
|
|
812
|
+
break;
|
|
813
|
+
case 23:
|
|
814
|
+
setChannelMask = 0x800000;
|
|
815
|
+
break;
|
|
816
|
+
case 24:
|
|
817
|
+
setChannelMask = 0x1000000;
|
|
818
|
+
break;
|
|
819
|
+
case 25:
|
|
820
|
+
setChannelMask = 0x2000000;
|
|
821
|
+
break;
|
|
822
|
+
case 26:
|
|
823
|
+
setChannelMask = 0x4000000;
|
|
824
|
+
break;
|
|
825
|
+
default:
|
|
826
|
+
break;
|
|
827
|
+
}
|
|
828
|
+
try {
|
|
829
|
+
await this.driver.writeParameterRequest(constants_1.default.PARAM.Network.CHANNEL_MASK, setChannelMask);
|
|
830
|
+
await this.driver.changeNetworkStateRequest(constants_1.default.PARAM.Network.NET_OFFLINE);
|
|
831
|
+
await this.driver.changeNetworkStateRequest(constants_1.default.PARAM.Network.NET_CONNECTED);
|
|
832
|
+
await this.sleep(3000);
|
|
833
|
+
channel = await this.driver.readParameterRequest(constants_1.default.PARAM.Network.CHANNEL);
|
|
834
|
+
}
|
|
835
|
+
catch (error) {
|
|
836
|
+
debug("Could not set channel: " + error);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
// check current panid against configuration.yaml
|
|
840
|
+
if (this.networkOptions.panID !== panid) {
|
|
841
|
+
debug("panid in configuration.yaml (" + this.networkOptions.panID + ") differs from current panid (" + panid + "). Changing panid.");
|
|
842
|
+
try {
|
|
843
|
+
await this.driver.writeParameterRequest(constants_1.default.PARAM.Network.PAN_ID, this.networkOptions.panID);
|
|
844
|
+
await this.driver.changeNetworkStateRequest(constants_1.default.PARAM.Network.NET_OFFLINE);
|
|
845
|
+
await this.driver.changeNetworkStateRequest(constants_1.default.PARAM.Network.NET_CONNECTED);
|
|
846
|
+
await this.sleep(3000);
|
|
847
|
+
panid = await this.driver.readParameterRequest(constants_1.default.PARAM.Network.PAN_ID);
|
|
848
|
+
}
|
|
849
|
+
catch (error) {
|
|
850
|
+
debug("Could not set panid: " + error);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
// check current extended_panid against configuration.yaml
|
|
854
|
+
if (this.driver.generalArrayToString(this.networkOptions.extendedPanID, 8) !== expanid) {
|
|
855
|
+
debug("extended panid in configuration.yaml (" + this.driver.macAddrArrayToString(this.networkOptions.extendedPanID) + ") differs from current extended panid (" + expanid + "). Changing extended panid.");
|
|
856
|
+
try {
|
|
857
|
+
//await this.driver.writeParameterRequest(PARAM.PARAM.Network.USE_APS_EXT_PAN_ID, 1);
|
|
858
|
+
await this.driver.writeParameterRequest(constants_1.default.PARAM.Network.APS_EXT_PAN_ID, this.networkOptions.extendedPanID);
|
|
859
|
+
await this.driver.changeNetworkStateRequest(constants_1.default.PARAM.Network.NET_OFFLINE);
|
|
860
|
+
await this.driver.changeNetworkStateRequest(constants_1.default.PARAM.Network.NET_CONNECTED);
|
|
861
|
+
await this.sleep(3000);
|
|
862
|
+
expanid = await this.driver.readParameterRequest(constants_1.default.PARAM.Network.APS_EXT_PAN_ID);
|
|
863
|
+
}
|
|
864
|
+
catch (error) {
|
|
865
|
+
debug("Could not set extended panid: " + error);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
// check current network key against configuration.yaml
|
|
869
|
+
if (this.driver.generalArrayToString(this.networkOptions.networkKey, 16) !== networkKey) {
|
|
870
|
+
debug("network key in configuration.yaml (hidden) differs from current network key (" + networkKey + "). Changing network key.");
|
|
871
|
+
try {
|
|
872
|
+
await this.driver.writeParameterRequest(constants_1.default.PARAM.Network.NETWORK_KEY, this.networkOptions.networkKey);
|
|
873
|
+
await this.driver.changeNetworkStateRequest(constants_1.default.PARAM.Network.NET_OFFLINE);
|
|
874
|
+
await this.driver.changeNetworkStateRequest(constants_1.default.PARAM.Network.NET_CONNECTED);
|
|
875
|
+
await this.sleep(3000);
|
|
876
|
+
}
|
|
877
|
+
catch (error) {
|
|
878
|
+
debug("Could not set network key: " + error);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
return {
|
|
882
|
+
panID: panid,
|
|
883
|
+
extendedPanID: expanid,
|
|
884
|
+
channel: channel
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
catch (error) {
|
|
888
|
+
const msg = "get network parameters Error:" + error;
|
|
889
|
+
debug(msg);
|
|
890
|
+
return Promise.reject(new Error(msg));
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
async restoreChannelInterPAN() {
|
|
894
|
+
throw new Error("not supported");
|
|
895
|
+
}
|
|
896
|
+
async sendZclFrameInterPANToIeeeAddr(zclFrame, ieeeAddr) {
|
|
897
|
+
throw new Error("not supported");
|
|
898
|
+
}
|
|
899
|
+
async sendZclFrameInterPANBroadcast(zclFrame, timeout) {
|
|
900
|
+
throw new Error("not supported");
|
|
901
|
+
}
|
|
902
|
+
async sendZclFrameInterPANBroadcastWithResponse(zclFrame, timeout) {
|
|
903
|
+
throw new Error("not supported");
|
|
904
|
+
}
|
|
905
|
+
async setChannelInterPAN(channel) {
|
|
906
|
+
throw new Error("not supported");
|
|
907
|
+
}
|
|
908
|
+
async setTransmitPower(value) {
|
|
909
|
+
throw new Error("not supported");
|
|
910
|
+
}
|
|
911
|
+
async sendZclFrameInterPANIeeeAddr(zclFrame, ieeeAddr) {
|
|
912
|
+
throw new Error("not supported");
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Private methods
|
|
916
|
+
*/
|
|
917
|
+
sleep(ms) {
|
|
918
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
919
|
+
}
|
|
920
|
+
waitForData(addr, profileId, clusterId, transactionSequenceNumber, timeout) {
|
|
921
|
+
return new Promise((resolve, reject) => {
|
|
922
|
+
const ts = Date.now();
|
|
923
|
+
const commandId = constants_1.default.PARAM.APS.DATA_INDICATION;
|
|
924
|
+
const req = { addr, profileId, clusterId, transactionSequenceNumber, resolve, reject, ts, timeout };
|
|
925
|
+
this.openRequestsQueue.push(req);
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
checkReceivedGreenPowerIndication(ind) {
|
|
929
|
+
ind.clusterId = 0x21;
|
|
930
|
+
let gpFrame = [ind.rspId, ind.seqNr, ind.id,
|
|
931
|
+
0, 0,
|
|
932
|
+
// ind.options & 0xff, (ind.options >> 8) & 0xff,
|
|
933
|
+
ind.srcId & 0xff, (ind.srcId >> 8) & 0xff, (ind.srcId >> 16) & 0xff, (ind.srcId >> 24) & 0xff,
|
|
934
|
+
ind.frameCounter & 0xff, (ind.frameCounter >> 8) & 0xff, (ind.frameCounter >> 16) & 0xff, (ind.frameCounter >> 24) & 0xff,
|
|
935
|
+
ind.commandId, ind.commandFrameSize].concat(ind.commandFrame);
|
|
936
|
+
const payBuf = Buffer.from(gpFrame);
|
|
937
|
+
const payload = {
|
|
938
|
+
frame: zcl_1.ZclFrame.fromBuffer(ind.clusterId, payBuf),
|
|
939
|
+
address: ind.srcId,
|
|
940
|
+
endpoint: 242,
|
|
941
|
+
linkquality: 127,
|
|
942
|
+
groupID: 0x0b84,
|
|
943
|
+
wasBroadcast: false,
|
|
944
|
+
destinationEndpoint: 1,
|
|
945
|
+
};
|
|
946
|
+
this.waitress.resolve(payload);
|
|
947
|
+
this.emit(Events.Events.zclData, payload);
|
|
948
|
+
}
|
|
949
|
+
checkReceivedDataPayload(resp) {
|
|
950
|
+
var _a;
|
|
951
|
+
let srcAddr = null;
|
|
952
|
+
let frame = null;
|
|
953
|
+
if (resp != null) {
|
|
954
|
+
srcAddr = (resp.srcAddr16 != null) ? resp.srcAddr16 : resp.srcAddr64;
|
|
955
|
+
if (resp.profileId != 0x00) {
|
|
956
|
+
try {
|
|
957
|
+
frame = zcl_1.ZclFrame.fromBuffer(resp.clusterId, Buffer.from(resp.asduPayload));
|
|
958
|
+
}
|
|
959
|
+
catch (error) {
|
|
960
|
+
debug("could not parse zclFrame: " + error);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
let i = this.openRequestsQueue.length;
|
|
965
|
+
while (i--) {
|
|
966
|
+
const req = this.openRequestsQueue[i];
|
|
967
|
+
if (srcAddr != null && req.addr === srcAddr && req.clusterId === resp.clusterId &&
|
|
968
|
+
req.profileId === resp.profileId) {
|
|
969
|
+
if (frame !== null && req.transactionSequenceNumber !== null && req.transactionSequenceNumber !== undefined) {
|
|
970
|
+
if (req.transactionSequenceNumber === frame.Header.transactionSequenceNumber) {
|
|
971
|
+
debug("resolve data request with transSeq Nr.: " + req.transactionSequenceNumber);
|
|
972
|
+
this.openRequestsQueue.splice(i, 1);
|
|
973
|
+
req.resolve(resp);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
else {
|
|
977
|
+
debug("resolve data request without a transSeq Nr.");
|
|
978
|
+
this.openRequestsQueue.splice(i, 1);
|
|
979
|
+
req.resolve(resp);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
const now = Date.now();
|
|
983
|
+
// Default timeout: 60 seconds.
|
|
984
|
+
// Comparison is negated to prevent orphans when invalid timeout is entered (resulting in NaN).
|
|
985
|
+
if (!((now - req.ts) <= ((_a = req.timeout) !== null && _a !== void 0 ? _a : 60000))) {
|
|
986
|
+
//debug("Timeout for request in openRequestsQueue addr: " + req.addr.toString(16) + " clusterId: " + req.clusterId.toString(16) + " profileId: " + req.profileId.toString(16));
|
|
987
|
+
//remove from busyQueue
|
|
988
|
+
this.openRequestsQueue.splice(i, 1);
|
|
989
|
+
req.reject("waiting for response TIMEOUT");
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
// check unattended incomming messages
|
|
993
|
+
if (resp != null && resp.profileId === 0x00 && resp.clusterId === 0x13) {
|
|
994
|
+
// device Annce
|
|
995
|
+
const payBuf = Buffer.from(resp.asduPayload);
|
|
996
|
+
const payload = {
|
|
997
|
+
networkAddress: payBuf.readUInt16LE(1),
|
|
998
|
+
ieeeAddr: this.driver.macAddrArrayToString(resp.asduPayload.slice(3, 11)),
|
|
999
|
+
};
|
|
1000
|
+
if (this.joinPermitted === true) {
|
|
1001
|
+
this.emit(Events.Events.deviceJoined, payload);
|
|
1002
|
+
}
|
|
1003
|
+
else {
|
|
1004
|
+
this.emit(Events.Events.deviceAnnounce, payload);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
if (resp != null && resp.profileId != 0x00) {
|
|
1008
|
+
const payBuf = Buffer.from(resp.asduPayload);
|
|
1009
|
+
try {
|
|
1010
|
+
const payload = {
|
|
1011
|
+
frame: zcl_1.ZclFrame.fromBuffer(resp.clusterId, payBuf),
|
|
1012
|
+
address: (resp.destAddrMode === 0x03) ? resp.srcAddr64 : resp.srcAddr16,
|
|
1013
|
+
endpoint: resp.srcEndpoint,
|
|
1014
|
+
linkquality: resp.lqi,
|
|
1015
|
+
groupID: (resp.destAddrMode === 0x01) ? resp.destAddr16 : null,
|
|
1016
|
+
wasBroadcast: resp.destAddrMode === 0x01 || resp.destAddrMode === 0xF,
|
|
1017
|
+
destinationEndpoint: resp.destEndpoint,
|
|
1018
|
+
};
|
|
1019
|
+
this.waitress.resolve(payload);
|
|
1020
|
+
this.emit(Events.Events.zclData, payload);
|
|
1021
|
+
}
|
|
1022
|
+
catch (error) {
|
|
1023
|
+
const payload = {
|
|
1024
|
+
clusterID: resp.clusterId,
|
|
1025
|
+
data: payBuf,
|
|
1026
|
+
address: (resp.destAddrMode === 0x03) ? resp.srcAddr64 : resp.srcAddr16,
|
|
1027
|
+
endpoint: resp.srcEndpoint,
|
|
1028
|
+
linkquality: resp.lqi,
|
|
1029
|
+
groupID: (resp.destAddrMode === 0x01) ? resp.destAddr16 : null,
|
|
1030
|
+
wasBroadcast: resp.destAddrMode === 0x01 || resp.destAddrMode === 0xF,
|
|
1031
|
+
destinationEndpoint: resp.destEndpoint,
|
|
1032
|
+
};
|
|
1033
|
+
this.emit(Events.Events.rawData, payload);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
nextTransactionID() {
|
|
1038
|
+
this.transactionID++;
|
|
1039
|
+
if (this.transactionID > 255) {
|
|
1040
|
+
this.transactionID = 1;
|
|
1041
|
+
}
|
|
1042
|
+
return this.transactionID;
|
|
1043
|
+
}
|
|
1044
|
+
waitressTimeoutFormatter(matcher, timeout) {
|
|
1045
|
+
return `Timeout - ${matcher.address} - ${matcher.endpoint}` +
|
|
1046
|
+
` - ${matcher.transactionSequenceNumber} - ${matcher.clusterID}` +
|
|
1047
|
+
` - ${matcher.commandIdentifier} after ${timeout}ms`;
|
|
1048
|
+
}
|
|
1049
|
+
waitressValidator(payload, matcher) {
|
|
1050
|
+
const transactionSequenceNumber = payload.frame.Header.transactionSequenceNumber;
|
|
1051
|
+
return (!matcher.address || payload.address === matcher.address) &&
|
|
1052
|
+
payload.endpoint === matcher.endpoint &&
|
|
1053
|
+
(!matcher.transactionSequenceNumber || transactionSequenceNumber === matcher.transactionSequenceNumber) &&
|
|
1054
|
+
payload.frame.Cluster.ID === matcher.clusterID &&
|
|
1055
|
+
matcher.frameType === payload.frame.Header.frameControl.frameType &&
|
|
1056
|
+
matcher.commandIdentifier === payload.frame.Header.commandIdentifier &&
|
|
1057
|
+
matcher.direction === payload.frame.Header.frameControl.direction;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
exports.default = DeconzAdapter;
|
|
1064
1061
|
//# sourceMappingURL=deconzAdapter.js.map
|