@willieee802/zigbee-herdsman 0.15.0 → 0.15.2
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/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 +38 -39
- package/dist/controller/model/group.d.ts.map +1 -1
- package/dist/controller/model/group.js +221 -221
- package/dist/controller/model/group.js.map +1 -1
- 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 +1 -1
- package/.github/ISSUE_TEMPLATE/config.yml +0 -5
- package/.github/dependabot.yml +0 -6
- package/.github/workflows/ci.yml +0 -40
- package/.github/workflows/release_please.yml +0 -20
- package/.github/workflows/stale.yml +0 -20
- package/.github/workflows/update_deps.yml +0 -29
|
@@ -1,733 +1,733 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.enableRtsTimeout = exports.disableRTS = exports.enableRTS = exports.readyToSend = exports.apsBusyQueue = exports.busyQueue = void 0;
|
|
7
|
-
/* istanbul ignore file */
|
|
8
|
-
/* eslint-disable */
|
|
9
|
-
const debug_1 = __importDefault(require("debug"));
|
|
10
|
-
const events_1 = __importDefault(require("events"));
|
|
11
|
-
const writer_1 = __importDefault(require("./writer"));
|
|
12
|
-
const parser_1 = __importDefault(require("./parser"));
|
|
13
|
-
const constants_1 = __importDefault(require("./constants"));
|
|
14
|
-
const serialPort_1 = require("../../serialPort");
|
|
15
|
-
const serialPortUtils_1 = __importDefault(require("../../serialPortUtils"));
|
|
16
|
-
const socketPortUtils_1 = __importDefault(require("../../socketPortUtils"));
|
|
17
|
-
const net_1 = __importDefault(require("net"));
|
|
18
|
-
// @ts-ignore
|
|
19
|
-
const slip_1 = __importDefault(require("slip"));
|
|
20
|
-
const debug = (0, debug_1.default)('zigbee-herdsman:deconz:driver');
|
|
21
|
-
const autoDetectDefinitions = [
|
|
22
|
-
{ manufacturer: 'dresden elektronik ingenieurtechnik GmbH', vendorId: '1cf1', productId: '0030' }, // Conbee II
|
|
23
|
-
];
|
|
24
|
-
var queue = [];
|
|
25
|
-
var busyQueue = [];
|
|
26
|
-
exports.busyQueue = busyQueue;
|
|
27
|
-
var apsQueue = [];
|
|
28
|
-
var apsBusyQueue = [];
|
|
29
|
-
exports.apsBusyQueue = apsBusyQueue;
|
|
30
|
-
var apsConfirmIndQueue = [];
|
|
31
|
-
var timeoutCounter = 0;
|
|
32
|
-
var readyToSend = true;
|
|
33
|
-
exports.readyToSend = readyToSend;
|
|
34
|
-
function enableRTS() {
|
|
35
|
-
if (readyToSend === false) {
|
|
36
|
-
exports.readyToSend = readyToSend = true;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
exports.enableRTS = enableRTS;
|
|
40
|
-
function disableRTS() {
|
|
41
|
-
exports.readyToSend = readyToSend = false;
|
|
42
|
-
}
|
|
43
|
-
exports.disableRTS = disableRTS;
|
|
44
|
-
var enableRtsTimeout = null;
|
|
45
|
-
exports.enableRtsTimeout = enableRtsTimeout;
|
|
46
|
-
var frameParser = require('./frameParser');
|
|
47
|
-
const littleEndian = true;
|
|
48
|
-
class Driver extends events_1.default.EventEmitter {
|
|
49
|
-
constructor(path) {
|
|
50
|
-
super();
|
|
51
|
-
this.frameParserEvent = frameParser.frameParserEvents;
|
|
52
|
-
this.intervals = [];
|
|
53
|
-
this.path = path;
|
|
54
|
-
this.initialized = false;
|
|
55
|
-
this.seqNumber = 0;
|
|
56
|
-
this.timeoutResetTimeout = null;
|
|
57
|
-
this.portType = socketPortUtils_1.default.isTcpPath(path) ? 'socket' : 'serial';
|
|
58
|
-
this.apsRequestFreeSlots = 1;
|
|
59
|
-
this.apsDataConfirm = 0;
|
|
60
|
-
this.apsDataIndication = 0;
|
|
61
|
-
this.configChanged = 0;
|
|
62
|
-
this.DELAY = 0;
|
|
63
|
-
this.READY_TO_SEND_TIMEOUT = 1;
|
|
64
|
-
this.HANDLE_DEVICE_STATUS_DELAY = 5;
|
|
65
|
-
this.PROCESS_QUEUES = 5;
|
|
66
|
-
const that = this;
|
|
67
|
-
setInterval(() => {
|
|
68
|
-
that.deviceStateRequest()
|
|
69
|
-
.then(result => { })
|
|
70
|
-
.catch(error => { });
|
|
71
|
-
}, 10000);
|
|
72
|
-
setInterval(() => {
|
|
73
|
-
that.writeParameterRequest(0x26, 600) // reset watchdog // 10 minutes
|
|
74
|
-
.then(result => { })
|
|
75
|
-
.catch(error => {
|
|
76
|
-
//try again
|
|
77
|
-
debug("try again to reset watchdog");
|
|
78
|
-
that.writeParameterRequest(0x26, 600)
|
|
79
|
-
.then(result => { })
|
|
80
|
-
.catch(error => { debug("warning watchdog was not reset"); });
|
|
81
|
-
});
|
|
82
|
-
}, (1000 * 60 * 8)); // 8 minutes
|
|
83
|
-
this.onParsed = this.onParsed.bind(this);
|
|
84
|
-
this.frameParserEvent.on('receivedDataNotification', (data) => { this.catchPromise(this.checkDeviceStatus(data)); });
|
|
85
|
-
this.on('close', () => {
|
|
86
|
-
this.intervals.forEach(i => clearInterval(i));
|
|
87
|
-
queue.length = 0;
|
|
88
|
-
busyQueue.length = 0;
|
|
89
|
-
apsQueue.length = 0;
|
|
90
|
-
apsBusyQueue.length = 0;
|
|
91
|
-
apsConfirmIndQueue.length = 0;
|
|
92
|
-
timeoutCounter = 0;
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
registerInterval(interval) {
|
|
96
|
-
this.intervals.push(interval);
|
|
97
|
-
}
|
|
98
|
-
catchPromise(val) {
|
|
99
|
-
return Promise.resolve(val)
|
|
100
|
-
.catch(err => debug(`Promise was caught with reason: ${err}`));
|
|
101
|
-
}
|
|
102
|
-
setDelay(delay) {
|
|
103
|
-
debug(`Set delay to ${delay}`);
|
|
104
|
-
this.DELAY = delay;
|
|
105
|
-
this.READY_TO_SEND_TIMEOUT = delay;
|
|
106
|
-
this.PROCESS_QUEUES = delay;
|
|
107
|
-
this.HANDLE_DEVICE_STATUS_DELAY = delay;
|
|
108
|
-
if (this.READY_TO_SEND_TIMEOUT === 0) {
|
|
109
|
-
this.READY_TO_SEND_TIMEOUT = 1;
|
|
110
|
-
}
|
|
111
|
-
if (this.PROCESS_QUEUES < 5) {
|
|
112
|
-
this.PROCESS_QUEUES = 5;
|
|
113
|
-
}
|
|
114
|
-
if (this.HANDLE_DEVICE_STATUS_DELAY < 5) {
|
|
115
|
-
this.HANDLE_DEVICE_STATUS_DELAY = 5;
|
|
116
|
-
}
|
|
117
|
-
if (this.PROCESS_QUEUES > 60) {
|
|
118
|
-
this.PROCESS_QUEUES = 60;
|
|
119
|
-
}
|
|
120
|
-
if (this.HANDLE_DEVICE_STATUS_DELAY > 60) {
|
|
121
|
-
this.HANDLE_DEVICE_STATUS_DELAY = 60;
|
|
122
|
-
}
|
|
123
|
-
const that = this;
|
|
124
|
-
this.registerInterval(setInterval(() => { that.processQueue(); }, this.PROCESS_QUEUES)); // fire non aps requests
|
|
125
|
-
this.registerInterval(setInterval(() => { this.catchPromise(that.processBusyQueue()); }, this.PROCESS_QUEUES)); // check timeouts for non aps requests
|
|
126
|
-
this.registerInterval(setInterval(() => { this.catchPromise(that.processApsQueue()); }, this.PROCESS_QUEUES)); // fire aps request
|
|
127
|
-
this.registerInterval(setInterval(() => { that.processApsBusyQueue(); }, this.PROCESS_QUEUES)); // check timeouts for all open aps requests
|
|
128
|
-
this.registerInterval(setInterval(() => { this.catchPromise(that.processApsConfirmIndQueue()); }, this.PROCESS_QUEUES)); // fire aps indications and confirms
|
|
129
|
-
this.registerInterval(setInterval(() => { this.catchPromise(that.handleDeviceStatus()); }, this.HANDLE_DEVICE_STATUS_DELAY)); // query confirm and indication requests
|
|
130
|
-
}
|
|
131
|
-
static async isValidPath(path) {
|
|
132
|
-
return serialPortUtils_1.default.is(path, autoDetectDefinitions);
|
|
133
|
-
}
|
|
134
|
-
static async autoDetectPath() {
|
|
135
|
-
const paths = await serialPortUtils_1.default.find(autoDetectDefinitions);
|
|
136
|
-
return paths.length > 0 ? paths[0] : null;
|
|
137
|
-
}
|
|
138
|
-
onPortClose() {
|
|
139
|
-
debug('Port closed');
|
|
140
|
-
this.initialized = false;
|
|
141
|
-
this.emit('close');
|
|
142
|
-
}
|
|
143
|
-
async open() {
|
|
144
|
-
return this.portType === 'serial' ? this.openSerialPort() : this.openSocketPort();
|
|
145
|
-
}
|
|
146
|
-
openSerialPort() {
|
|
147
|
-
debug(`Opening with ${this.path}`);
|
|
148
|
-
this.serialPort = new serialPort_1.SerialPort({ path: this.path, baudRate: 38400, autoOpen: false });
|
|
149
|
-
this.writer = new writer_1.default();
|
|
150
|
-
// @ts-ignore
|
|
151
|
-
this.writer.pipe(this.serialPort);
|
|
152
|
-
this.parser = new parser_1.default();
|
|
153
|
-
this.serialPort.pipe(this.parser);
|
|
154
|
-
this.parser.on('parsed', this.onParsed);
|
|
155
|
-
return new Promise((resolve, reject) => {
|
|
156
|
-
this.serialPort.open(async (error) => {
|
|
157
|
-
if (error) {
|
|
158
|
-
reject(new Error(`Error while opening serialport '${error}'`));
|
|
159
|
-
this.initialized = false;
|
|
160
|
-
if (this.serialPort.isOpen) {
|
|
161
|
-
this.serialPort.close();
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
debug('Serialport opened');
|
|
166
|
-
this.initialized = true;
|
|
167
|
-
resolve();
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
async openSocketPort() {
|
|
173
|
-
const info = socketPortUtils_1.default.parseTcpPath(this.path);
|
|
174
|
-
debug(`Opening TCP socket with ${info.host}:${info.port}`);
|
|
175
|
-
this.socketPort = new net_1.default.Socket();
|
|
176
|
-
this.socketPort.setNoDelay(true);
|
|
177
|
-
this.socketPort.setKeepAlive(true, 15000);
|
|
178
|
-
this.writer = new writer_1.default();
|
|
179
|
-
this.writer.pipe(this.socketPort);
|
|
180
|
-
this.parser = new parser_1.default();
|
|
181
|
-
this.socketPort.pipe(this.parser);
|
|
182
|
-
this.parser.on('parsed', this.onParsed);
|
|
183
|
-
return new Promise((resolve, reject) => {
|
|
184
|
-
this.socketPort.on('connect', function () {
|
|
185
|
-
debug('Socket connected');
|
|
186
|
-
});
|
|
187
|
-
// eslint-disable-next-line
|
|
188
|
-
const self = this;
|
|
189
|
-
this.socketPort.on('ready', async function () {
|
|
190
|
-
debug('Socket ready');
|
|
191
|
-
self.initialized = true;
|
|
192
|
-
resolve();
|
|
193
|
-
});
|
|
194
|
-
this.socketPort.once('close', this.onPortClose);
|
|
195
|
-
this.socketPort.on('error', function () {
|
|
196
|
-
debug('Socket error');
|
|
197
|
-
reject(new Error(`Error while opening socket`));
|
|
198
|
-
self.initialized = false;
|
|
199
|
-
});
|
|
200
|
-
this.socketPort.connect(info.port, info.host);
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
close() {
|
|
204
|
-
return new Promise((resolve, reject) => {
|
|
205
|
-
if (this.initialized) {
|
|
206
|
-
if (this.portType === 'serial') {
|
|
207
|
-
this.serialPort.flush(() => {
|
|
208
|
-
this.serialPort.close((error) => {
|
|
209
|
-
this.initialized = false;
|
|
210
|
-
error == null ?
|
|
211
|
-
resolve() :
|
|
212
|
-
reject(new Error(`Error while closing serialport '${error}'`));
|
|
213
|
-
this.emit('close');
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
this.socketPort.destroy();
|
|
219
|
-
resolve();
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
resolve();
|
|
224
|
-
this.emit('close');
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
readParameterRequest(parameterId) {
|
|
229
|
-
const seqNumber = this.nextSeqNumber();
|
|
230
|
-
return new Promise((resolve, reject) => {
|
|
231
|
-
//debug(`push read parameter request to queue. seqNr: ${seqNumber} paramId: ${parameterId}`);
|
|
232
|
-
const ts = 0;
|
|
233
|
-
const commandId = constants_1.default.PARAM.FrameType.ReadParameter;
|
|
234
|
-
const req = { commandId, parameterId, seqNumber, resolve, reject, ts };
|
|
235
|
-
queue.push(req);
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
writeParameterRequest(parameterId, parameter) {
|
|
239
|
-
const seqNumber = this.nextSeqNumber();
|
|
240
|
-
return new Promise((resolve, reject) => {
|
|
241
|
-
//debug(`push write parameter request to queue. seqNr: ${seqNumber} paramId: ${parameterId} parameter: ${parameter}`);
|
|
242
|
-
const ts = 0;
|
|
243
|
-
const commandId = constants_1.default.PARAM.FrameType.WriteParameter;
|
|
244
|
-
const req = { commandId, parameterId, parameter, seqNumber, resolve, reject, ts };
|
|
245
|
-
queue.push(req);
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
readFirmwareVersionRequest() {
|
|
249
|
-
const seqNumber = this.nextSeqNumber();
|
|
250
|
-
return new Promise((resolve, reject) => {
|
|
251
|
-
//debug(`push read firmware version request to queue. seqNr: ${seqNumber}`);
|
|
252
|
-
const ts = 0;
|
|
253
|
-
const commandId = constants_1.default.PARAM.FrameType.ReadFirmwareVersion;
|
|
254
|
-
const req = { commandId, seqNumber, resolve, reject, ts };
|
|
255
|
-
queue.push(req);
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
sendReadParameterRequest(parameterId, seqNumber) {
|
|
259
|
-
/* command id, sequence number, 0, framelength(U16), payloadlength(U16), parameter id */
|
|
260
|
-
const requestFrame = [constants_1.default.PARAM.FrameType.ReadParameter, seqNumber, 0x00, 0x08, 0x00, 0x01, 0x00, parameterId];
|
|
261
|
-
if (parameterId === constants_1.default.PARAM.Network.NETWORK_KEY) {
|
|
262
|
-
const requestFrame2 = [constants_1.default.PARAM.FrameType.ReadParameter, seqNumber, 0x00, 0x09, 0x00, 0x02, 0x00, parameterId, 0x00];
|
|
263
|
-
this.sendRequest(requestFrame2);
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
this.sendRequest(requestFrame);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
sendWriteParameterRequest(parameterId, value, seqNumber) {
|
|
270
|
-
/* command id, sequence number, 0, framelength(U16), payloadlength(U16), parameter id, pameter */
|
|
271
|
-
let parameterLength = 0;
|
|
272
|
-
if (parameterId === constants_1.default.PARAM.STK.Endpoint) {
|
|
273
|
-
let arrayParameterValue = value;
|
|
274
|
-
parameterLength = arrayParameterValue.length;
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
parameterLength = this.getLengthOfParameter(parameterId);
|
|
278
|
-
}
|
|
279
|
-
//debug("SEND WRITE_PARAMETER Request - parameter id: " + parameterId + " value: " + value.toString(16) + " length: " + parameterLength);
|
|
280
|
-
const payloadLength = 1 + parameterLength;
|
|
281
|
-
const frameLength = 7 + payloadLength;
|
|
282
|
-
const fLength1 = frameLength & 0xff;
|
|
283
|
-
const fLength2 = frameLength >> 8;
|
|
284
|
-
const pLength1 = payloadLength & 0xff;
|
|
285
|
-
const pLength2 = payloadLength >> 8;
|
|
286
|
-
if (parameterId === constants_1.default.PARAM.Network.NETWORK_KEY) {
|
|
287
|
-
const requestFrame2 = [constants_1.default.PARAM.FrameType.WriteParameter, seqNumber, 0x00, 0x19, 0x00, 0x12, 0x00, parameterId, 0x00].concat(value);
|
|
288
|
-
this.sendRequest(requestFrame2);
|
|
289
|
-
}
|
|
290
|
-
else {
|
|
291
|
-
const requestframe = [constants_1.default.PARAM.FrameType.WriteParameter, seqNumber, 0x00, fLength1, fLength2, pLength1, pLength2, parameterId].concat(this.parameterBuffer(value, parameterLength));
|
|
292
|
-
this.sendRequest(requestframe);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
getLengthOfParameter(parameterId) {
|
|
296
|
-
switch (parameterId) {
|
|
297
|
-
case 9:
|
|
298
|
-
case 16:
|
|
299
|
-
case 21:
|
|
300
|
-
case 28:
|
|
301
|
-
case 33:
|
|
302
|
-
case 36:
|
|
303
|
-
return 1;
|
|
304
|
-
case 5:
|
|
305
|
-
case 7:
|
|
306
|
-
case 34:
|
|
307
|
-
return 2;
|
|
308
|
-
case 10:
|
|
309
|
-
case 38:
|
|
310
|
-
return 4;
|
|
311
|
-
case 1:
|
|
312
|
-
case 8:
|
|
313
|
-
case 11:
|
|
314
|
-
case 14:
|
|
315
|
-
return 8;
|
|
316
|
-
case 24:
|
|
317
|
-
case 25:
|
|
318
|
-
return 16;
|
|
319
|
-
default:
|
|
320
|
-
return 0;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
parameterBuffer(parameter, parameterLength) {
|
|
324
|
-
const paramArray = new Array();
|
|
325
|
-
if (typeof parameter === 'number') {
|
|
326
|
-
// for parameter <= 4 Byte
|
|
327
|
-
if (parameterLength > 4)
|
|
328
|
-
throw new Error("parameter to big for type number");
|
|
329
|
-
for (let i = 0; i < parameterLength; i++) {
|
|
330
|
-
paramArray[i] = (parameter >> (8 * i)) & 0xff;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
else {
|
|
334
|
-
return parameter.reverse();
|
|
335
|
-
}
|
|
336
|
-
return paramArray;
|
|
337
|
-
}
|
|
338
|
-
sendReadFirmwareVersionRequest(seqNumber) {
|
|
339
|
-
/* command id, sequence number, 0, framelength(U16) */
|
|
340
|
-
const requestFrame = [constants_1.default.PARAM.FrameType.ReadFirmwareVersion, seqNumber, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00];
|
|
341
|
-
//debug(requestFrame);
|
|
342
|
-
this.sendRequest(requestFrame);
|
|
343
|
-
}
|
|
344
|
-
sendReadDeviceStateRequest(seqNumber) {
|
|
345
|
-
/* command id, sequence number, 0, framelength(U16) */
|
|
346
|
-
const requestFrame = [constants_1.default.PARAM.FrameType.ReadDeviceState, seqNumber, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00];
|
|
347
|
-
this.sendRequest(requestFrame);
|
|
348
|
-
}
|
|
349
|
-
sendRequest(buffer) {
|
|
350
|
-
const crc = this.calcCrc(Buffer.from(buffer));
|
|
351
|
-
const frame = Buffer.from(buffer.concat([crc[0], crc[1]]));
|
|
352
|
-
const slipframe = slip_1.default.encode(frame);
|
|
353
|
-
if (this.portType === 'serial') {
|
|
354
|
-
this.serialPort.write(slipframe, function (err) {
|
|
355
|
-
if (err) {
|
|
356
|
-
debug("Error writing serial Port: " + err.message);
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
else {
|
|
361
|
-
this.socketPort.write(slipframe, function (err) {
|
|
362
|
-
if (err) {
|
|
363
|
-
debug("Error writing socket Port: " + err.message);
|
|
364
|
-
}
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
processQueue() {
|
|
369
|
-
if (queue.length === 0) {
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
if (busyQueue.length > 0) {
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
const req = queue.shift();
|
|
376
|
-
req.ts = Date.now();
|
|
377
|
-
switch (req.commandId) {
|
|
378
|
-
case constants_1.default.PARAM.FrameType.ReadParameter:
|
|
379
|
-
debug(`send read parameter request from queue. seqNr: ${req.seqNumber} paramId: ${req.parameterId}`);
|
|
380
|
-
this.sendReadParameterRequest(req.parameterId, req.seqNumber);
|
|
381
|
-
break;
|
|
382
|
-
case constants_1.default.PARAM.FrameType.WriteParameter:
|
|
383
|
-
debug(`send write parameter request from queue. seqNr: ${req.seqNumber} paramId: ${req.parameterId} param: ${req.parameter}`);
|
|
384
|
-
this.sendWriteParameterRequest(req.parameterId, req.parameter, req.seqNumber);
|
|
385
|
-
break;
|
|
386
|
-
case constants_1.default.PARAM.FrameType.ReadFirmwareVersion:
|
|
387
|
-
debug(`send read firmware version request from queue. seqNr: ${req.seqNumber}`);
|
|
388
|
-
this.sendReadFirmwareVersionRequest(req.seqNumber);
|
|
389
|
-
break;
|
|
390
|
-
case constants_1.default.PARAM.FrameType.ReadDeviceState:
|
|
391
|
-
debug(`send read device state from queue. seqNr: ${req.seqNumber}`);
|
|
392
|
-
this.sendReadDeviceStateRequest(req.seqNumber);
|
|
393
|
-
break;
|
|
394
|
-
case constants_1.default.PARAM.NetworkState.CHANGE_NETWORK_STATE:
|
|
395
|
-
debug(`send change network state request from queue. seqNr: ${req.seqNumber}`);
|
|
396
|
-
this.sendChangeNetworkStateRequest(req.seqNumber, req.networkState);
|
|
397
|
-
break;
|
|
398
|
-
default:
|
|
399
|
-
throw new Error("process queue - unknown command id");
|
|
400
|
-
break;
|
|
401
|
-
}
|
|
402
|
-
busyQueue.push(req);
|
|
403
|
-
}
|
|
404
|
-
async processBusyQueue() {
|
|
405
|
-
var _a;
|
|
406
|
-
let i = busyQueue.length;
|
|
407
|
-
while (i--) {
|
|
408
|
-
const req = busyQueue[i];
|
|
409
|
-
const now = Date.now();
|
|
410
|
-
if ((now - req.ts) > 10000) {
|
|
411
|
-
debug(`Timeout for request - CMD: 0x${req.commandId.toString(16)} seqNr: ${req.seqNumber}`);
|
|
412
|
-
//remove from busyQueue
|
|
413
|
-
busyQueue.splice(i, 1);
|
|
414
|
-
timeoutCounter++;
|
|
415
|
-
// after a timeout the timeoutcounter will be reset after 1 min. If another timeout happen then the timeoutcounter
|
|
416
|
-
// will not be reset
|
|
417
|
-
clearTimeout(this.timeoutResetTimeout);
|
|
418
|
-
this.timeoutResetTimeout = null;
|
|
419
|
-
this.resetTimeoutCounterAfter1min();
|
|
420
|
-
req.reject("TIMEOUT");
|
|
421
|
-
if (timeoutCounter >= 2) {
|
|
422
|
-
timeoutCounter = 0;
|
|
423
|
-
debug("too many timeouts - restart serial connecion");
|
|
424
|
-
if ((_a = this.serialPort) === null || _a === void 0 ? void 0 : _a.isOpen) {
|
|
425
|
-
this.serialPort.close();
|
|
426
|
-
}
|
|
427
|
-
if (this.socketPort) {
|
|
428
|
-
this.socketPort.destroy();
|
|
429
|
-
}
|
|
430
|
-
await this.open();
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
changeNetworkStateRequest(networkState) {
|
|
436
|
-
const seqNumber = this.nextSeqNumber();
|
|
437
|
-
return new Promise((resolve, reject) => {
|
|
438
|
-
//debug(`push change network state request to apsQueue. seqNr: ${seqNumber}`);
|
|
439
|
-
const ts = 0;
|
|
440
|
-
const commandId = constants_1.default.PARAM.NetworkState.CHANGE_NETWORK_STATE;
|
|
441
|
-
const req = { commandId, networkState, seqNumber, resolve, reject, ts };
|
|
442
|
-
queue.push(req);
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
sendChangeNetworkStateRequest(seqNumber, networkState) {
|
|
446
|
-
const requestFrame = [constants_1.default.PARAM.NetworkState.CHANGE_NETWORK_STATE, seqNumber, 0x00, 0x06, 0x00, networkState];
|
|
447
|
-
this.sendRequest(requestFrame);
|
|
448
|
-
}
|
|
449
|
-
deviceStateRequest() {
|
|
450
|
-
const seqNumber = this.nextSeqNumber();
|
|
451
|
-
return new Promise((resolve, reject) => {
|
|
452
|
-
//debug(`DEVICE_STATE Request - seqNr: ${seqNumber}`);
|
|
453
|
-
const ts = 0;
|
|
454
|
-
const commandId = constants_1.default.PARAM.FrameType.ReadDeviceState;
|
|
455
|
-
const req = { commandId, seqNumber, resolve, reject, ts };
|
|
456
|
-
queue.push(req);
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
async checkDeviceStatus(currentDeviceStatus) {
|
|
460
|
-
const networkState = currentDeviceStatus & 0x03;
|
|
461
|
-
this.apsDataConfirm = (currentDeviceStatus >> 2) & 0x01;
|
|
462
|
-
this.apsDataIndication = (currentDeviceStatus >> 3) & 0x01;
|
|
463
|
-
this.configChanged = (currentDeviceStatus >> 4) & 0x01;
|
|
464
|
-
this.apsRequestFreeSlots = (currentDeviceStatus >> 5) & 0x01;
|
|
465
|
-
debug("networkstate: " + networkState + " apsDataConfirm: " + this.apsDataConfirm + " apsDataIndication: " + this.apsDataIndication +
|
|
466
|
-
" configChanged: " + this.configChanged + " apsRequestFreeSlots: " + this.apsRequestFreeSlots);
|
|
467
|
-
}
|
|
468
|
-
async handleDeviceStatus() {
|
|
469
|
-
if (this.apsDataConfirm === 1) {
|
|
470
|
-
try {
|
|
471
|
-
debug("query aps data confirm");
|
|
472
|
-
this.apsDataConfirm = 0;
|
|
473
|
-
const x = await this.querySendDataStateRequest();
|
|
474
|
-
}
|
|
475
|
-
catch (e) {
|
|
476
|
-
if (e.status === 5) {
|
|
477
|
-
this.apsDataConfirm = 0;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
if (this.apsDataIndication === 1) {
|
|
482
|
-
try {
|
|
483
|
-
debug("query aps data indication");
|
|
484
|
-
this.apsDataIndication = 0;
|
|
485
|
-
const x = await this.readReceivedDataRequest();
|
|
486
|
-
}
|
|
487
|
-
catch (e) {
|
|
488
|
-
if (e.status === 5) {
|
|
489
|
-
this.apsDataIndication = 0;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
if (this.configChanged === 1) {
|
|
494
|
-
// when network settings changed
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
// DATA_IND
|
|
498
|
-
readReceivedDataRequest() {
|
|
499
|
-
const seqNumber = this.nextSeqNumber();
|
|
500
|
-
return new Promise((resolve, reject) => {
|
|
501
|
-
//debug(`push read received data request to apsQueue. seqNr: ${seqNumber}`);
|
|
502
|
-
const ts = 0;
|
|
503
|
-
const commandId = constants_1.default.PARAM.APS.DATA_INDICATION;
|
|
504
|
-
const req = { commandId, seqNumber, resolve, reject, ts };
|
|
505
|
-
apsConfirmIndQueue.push(req);
|
|
506
|
-
});
|
|
507
|
-
}
|
|
508
|
-
// DATA_REQ
|
|
509
|
-
enqueueSendDataRequest(request) {
|
|
510
|
-
const seqNumber = this.nextSeqNumber();
|
|
511
|
-
return new Promise((resolve, reject) => {
|
|
512
|
-
//debug(`push enqueue send data request to apsQueue. seqNr: ${seqNumber}`);
|
|
513
|
-
const ts = 0;
|
|
514
|
-
const requestId = request.requestId;
|
|
515
|
-
const commandId = constants_1.default.PARAM.APS.DATA_REQUEST;
|
|
516
|
-
const req = { commandId, seqNumber, request, resolve, reject, ts };
|
|
517
|
-
apsQueue.push(req);
|
|
518
|
-
});
|
|
519
|
-
}
|
|
520
|
-
// DATA_CONF
|
|
521
|
-
querySendDataStateRequest() {
|
|
522
|
-
const seqNumber = this.nextSeqNumber();
|
|
523
|
-
return new Promise((resolve, reject) => {
|
|
524
|
-
//debug(`push query send data state request to apsQueue. seqNr: ${seqNumber}`);
|
|
525
|
-
const ts = 0;
|
|
526
|
-
const commandId = constants_1.default.PARAM.APS.DATA_CONFIRM;
|
|
527
|
-
const req = { commandId, seqNumber, resolve, reject, ts };
|
|
528
|
-
apsConfirmIndQueue.push(req);
|
|
529
|
-
});
|
|
530
|
-
}
|
|
531
|
-
async processApsQueue() {
|
|
532
|
-
if (apsQueue.length === 0) {
|
|
533
|
-
return;
|
|
534
|
-
}
|
|
535
|
-
if (this.apsRequestFreeSlots !== 1) {
|
|
536
|
-
debug("no free slots. Delay sending of APS Request");
|
|
537
|
-
await this.sleep(1000);
|
|
538
|
-
return;
|
|
539
|
-
}
|
|
540
|
-
const req = apsQueue.shift();
|
|
541
|
-
req.ts = Date.now();
|
|
542
|
-
switch (req.commandId) {
|
|
543
|
-
case constants_1.default.PARAM.APS.DATA_REQUEST:
|
|
544
|
-
if (readyToSend === false) { // wait until last request was confirmed or given time elapsed
|
|
545
|
-
debug("delay sending of APS Request");
|
|
546
|
-
apsQueue.unshift(req);
|
|
547
|
-
break;
|
|
548
|
-
}
|
|
549
|
-
else {
|
|
550
|
-
disableRTS();
|
|
551
|
-
exports.enableRtsTimeout = enableRtsTimeout = setTimeout(function () { enableRTS(); }, this.READY_TO_SEND_TIMEOUT);
|
|
552
|
-
apsBusyQueue.push(req);
|
|
553
|
-
this.sendEnqueueSendDataRequest(req.request, req.seqNumber);
|
|
554
|
-
break;
|
|
555
|
-
}
|
|
556
|
-
default:
|
|
557
|
-
throw new Error("process APS queue - unknown command id");
|
|
558
|
-
break;
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
async processApsConfirmIndQueue() {
|
|
562
|
-
if (apsConfirmIndQueue.length === 0) {
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
const req = apsConfirmIndQueue.shift();
|
|
566
|
-
req.ts = Date.now();
|
|
567
|
-
apsBusyQueue.push(req);
|
|
568
|
-
switch (req.commandId) {
|
|
569
|
-
case constants_1.default.PARAM.APS.DATA_INDICATION:
|
|
570
|
-
//debug(`read received data request. seqNr: ${req.seqNumber}`);
|
|
571
|
-
if (this.DELAY === 0) {
|
|
572
|
-
this.sendReadReceivedDataRequest(req.seqNumber);
|
|
573
|
-
}
|
|
574
|
-
else {
|
|
575
|
-
await this.sendReadReceivedDataRequest(req.seqNumber);
|
|
576
|
-
}
|
|
577
|
-
break;
|
|
578
|
-
case constants_1.default.PARAM.APS.DATA_CONFIRM:
|
|
579
|
-
//debug(`query send data state request. seqNr: ${req.seqNumber}`);
|
|
580
|
-
if (this.DELAY === 0) {
|
|
581
|
-
this.sendQueryDataStateRequest(req.seqNumber);
|
|
582
|
-
}
|
|
583
|
-
else {
|
|
584
|
-
await this.sendQueryDataStateRequest(req.seqNumber);
|
|
585
|
-
}
|
|
586
|
-
break;
|
|
587
|
-
default:
|
|
588
|
-
throw new Error("process APS Confirm/Ind queue - unknown command id");
|
|
589
|
-
break;
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
sendQueryDataStateRequest(seqNumber) {
|
|
593
|
-
debug(`DATA_CONFIRM - sending data state request - SeqNr. ${seqNumber}`);
|
|
594
|
-
const requestFrame = [constants_1.default.PARAM.APS.DATA_CONFIRM, seqNumber, 0x00, 0x07, 0x00, 0x00, 0x00];
|
|
595
|
-
this.sendRequest(requestFrame);
|
|
596
|
-
}
|
|
597
|
-
sendReadReceivedDataRequest(seqNumber) {
|
|
598
|
-
debug(`DATA_INDICATION - sending read data request - SeqNr. ${seqNumber}`);
|
|
599
|
-
// payloadlength = 0, flag = none
|
|
600
|
-
const requestFrame = [constants_1.default.PARAM.APS.DATA_INDICATION, seqNumber, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01];
|
|
601
|
-
this.sendRequest(requestFrame);
|
|
602
|
-
}
|
|
603
|
-
sendEnqueueSendDataRequest(request, seqNumber) {
|
|
604
|
-
const payloadLength = 12 + ((request.destAddrMode === 0x01) ? 2 : (request.destAddrMode === 0x02) ? 3 : 9) + request.asduLength;
|
|
605
|
-
const frameLength = 7 + payloadLength;
|
|
606
|
-
const cid1 = request.clusterId & 0xff;
|
|
607
|
-
const cid2 = (request.clusterId >> 8) & 0xff;
|
|
608
|
-
const asdul1 = request.asduLength & 0xff;
|
|
609
|
-
const asdul2 = (request.asduLength >> 8) & 0xff;
|
|
610
|
-
let destArray = [];
|
|
611
|
-
let dest = "";
|
|
612
|
-
if (request.destAddr16 != null) {
|
|
613
|
-
destArray[0] = request.destAddr16 & 0xff;
|
|
614
|
-
destArray[1] = (request.destAddr16 >> 8) & 0xff;
|
|
615
|
-
dest = request.destAddr16.toString(16);
|
|
616
|
-
}
|
|
617
|
-
if (request.destAddr64 != null) {
|
|
618
|
-
dest = request.destAddr64;
|
|
619
|
-
destArray = this.macAddrStringToArray(request.destAddr64);
|
|
620
|
-
}
|
|
621
|
-
if (request.destEndpoint != null) {
|
|
622
|
-
destArray.push(request.destEndpoint);
|
|
623
|
-
dest += " EP:";
|
|
624
|
-
dest += request.destEndpoint;
|
|
625
|
-
}
|
|
626
|
-
debug(`DATA_REQUEST - destAddr: 0x${dest} SeqNr. ${seqNumber} request id: ${request.requestId}`);
|
|
627
|
-
const requestFrame = [constants_1.default.PARAM.APS.DATA_REQUEST, seqNumber, 0x00, frameLength & 0xff, (frameLength >> 8) & 0xff,
|
|
628
|
-
payloadLength & 0xff, (payloadLength >> 8) & 0xff,
|
|
629
|
-
request.requestId, 0x00, request.destAddrMode].concat(destArray).concat([request.profileId & 0xff, (request.profileId >> 8) & 0xff,
|
|
630
|
-
cid1, cid2, request.srcEndpoint, asdul1, asdul2]).concat(request.asduPayload).concat([request.txOptions, request.radius]);
|
|
631
|
-
this.sendRequest(requestFrame);
|
|
632
|
-
}
|
|
633
|
-
processApsBusyQueue() {
|
|
634
|
-
let i = apsBusyQueue.length;
|
|
635
|
-
while (i--) {
|
|
636
|
-
const req = apsBusyQueue[i];
|
|
637
|
-
const now = Date.now();
|
|
638
|
-
let timeout = 60000;
|
|
639
|
-
if (req.request != null && req.request.timeout != null) {
|
|
640
|
-
timeout = req.request.timeout * 1000; // seconds * 1000 = milliseconds
|
|
641
|
-
}
|
|
642
|
-
if ((now - req.ts) > timeout) {
|
|
643
|
-
debug(`Timeout for aps request CMD: 0x${req.commandId.toString(16)} seq: ${req.seqNumber}`);
|
|
644
|
-
//remove from busyQueue
|
|
645
|
-
apsBusyQueue.splice(i, 1);
|
|
646
|
-
req.reject(new Error("APS TIMEOUT"));
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
calcCrc(buffer) {
|
|
651
|
-
let crc = 0;
|
|
652
|
-
for (let i = 0; i < buffer.length; i++) {
|
|
653
|
-
crc += buffer[i];
|
|
654
|
-
}
|
|
655
|
-
const crc0 = (~crc + 1) & 0xff;
|
|
656
|
-
const crc1 = ((~crc + 1) >> 8) & 0xff;
|
|
657
|
-
return [crc0, crc1];
|
|
658
|
-
}
|
|
659
|
-
macAddrStringToArray(addr) {
|
|
660
|
-
if (addr.indexOf("0x") === 0) {
|
|
661
|
-
addr = addr.slice(2, addr.length);
|
|
662
|
-
}
|
|
663
|
-
if (addr.length < 16) {
|
|
664
|
-
for (let l = 0; l < (16 - addr.length); l++) {
|
|
665
|
-
addr = "0" + addr;
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
let result = new Array();
|
|
669
|
-
let y = 0;
|
|
670
|
-
for (let i = 0; i < 8; i++) {
|
|
671
|
-
result[i] = parseInt(addr.substr(y, 2), 16);
|
|
672
|
-
y += 2;
|
|
673
|
-
}
|
|
674
|
-
const reverse = result.reverse();
|
|
675
|
-
return reverse;
|
|
676
|
-
}
|
|
677
|
-
macAddrArrayToString(addr) {
|
|
678
|
-
if (addr.length != 8) {
|
|
679
|
-
throw new Error("invalid array length for MAC address: " + addr.length);
|
|
680
|
-
}
|
|
681
|
-
let result = "0x";
|
|
682
|
-
let char = '';
|
|
683
|
-
let i = 8;
|
|
684
|
-
while (i--) {
|
|
685
|
-
char = addr[i].toString(16);
|
|
686
|
-
if (char.length < 2) {
|
|
687
|
-
char = "0" + char;
|
|
688
|
-
}
|
|
689
|
-
result += char;
|
|
690
|
-
}
|
|
691
|
-
return result;
|
|
692
|
-
}
|
|
693
|
-
/**
|
|
694
|
-
* generalArrayToString result is not reversed!
|
|
695
|
-
*/
|
|
696
|
-
generalArrayToString(key, length) {
|
|
697
|
-
let result = "0x";
|
|
698
|
-
let char = '';
|
|
699
|
-
let i = 0;
|
|
700
|
-
while (i < length) {
|
|
701
|
-
char = key[i].toString(16);
|
|
702
|
-
if (char.length < 2) {
|
|
703
|
-
char = "0" + char;
|
|
704
|
-
}
|
|
705
|
-
result += char;
|
|
706
|
-
i++;
|
|
707
|
-
}
|
|
708
|
-
return result;
|
|
709
|
-
}
|
|
710
|
-
nextSeqNumber() {
|
|
711
|
-
this.seqNumber++;
|
|
712
|
-
if (this.seqNumber > 254) {
|
|
713
|
-
this.seqNumber = 1;
|
|
714
|
-
}
|
|
715
|
-
return this.seqNumber;
|
|
716
|
-
}
|
|
717
|
-
onParsed(frame) {
|
|
718
|
-
this.emit('rxFrame', frame);
|
|
719
|
-
}
|
|
720
|
-
sleep(ms) {
|
|
721
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
722
|
-
}
|
|
723
|
-
resetTimeoutCounterAfter1min() {
|
|
724
|
-
if (this.timeoutResetTimeout === null) {
|
|
725
|
-
this.timeoutResetTimeout = setTimeout(() => {
|
|
726
|
-
timeoutCounter = 0;
|
|
727
|
-
this.timeoutResetTimeout = null;
|
|
728
|
-
}, 60000);
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
exports.default = Driver;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.enableRtsTimeout = exports.disableRTS = exports.enableRTS = exports.readyToSend = exports.apsBusyQueue = exports.busyQueue = void 0;
|
|
7
|
+
/* istanbul ignore file */
|
|
8
|
+
/* eslint-disable */
|
|
9
|
+
const debug_1 = __importDefault(require("debug"));
|
|
10
|
+
const events_1 = __importDefault(require("events"));
|
|
11
|
+
const writer_1 = __importDefault(require("./writer"));
|
|
12
|
+
const parser_1 = __importDefault(require("./parser"));
|
|
13
|
+
const constants_1 = __importDefault(require("./constants"));
|
|
14
|
+
const serialPort_1 = require("../../serialPort");
|
|
15
|
+
const serialPortUtils_1 = __importDefault(require("../../serialPortUtils"));
|
|
16
|
+
const socketPortUtils_1 = __importDefault(require("../../socketPortUtils"));
|
|
17
|
+
const net_1 = __importDefault(require("net"));
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
const slip_1 = __importDefault(require("slip"));
|
|
20
|
+
const debug = (0, debug_1.default)('zigbee-herdsman:deconz:driver');
|
|
21
|
+
const autoDetectDefinitions = [
|
|
22
|
+
{ manufacturer: 'dresden elektronik ingenieurtechnik GmbH', vendorId: '1cf1', productId: '0030' }, // Conbee II
|
|
23
|
+
];
|
|
24
|
+
var queue = [];
|
|
25
|
+
var busyQueue = [];
|
|
26
|
+
exports.busyQueue = busyQueue;
|
|
27
|
+
var apsQueue = [];
|
|
28
|
+
var apsBusyQueue = [];
|
|
29
|
+
exports.apsBusyQueue = apsBusyQueue;
|
|
30
|
+
var apsConfirmIndQueue = [];
|
|
31
|
+
var timeoutCounter = 0;
|
|
32
|
+
var readyToSend = true;
|
|
33
|
+
exports.readyToSend = readyToSend;
|
|
34
|
+
function enableRTS() {
|
|
35
|
+
if (readyToSend === false) {
|
|
36
|
+
exports.readyToSend = readyToSend = true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.enableRTS = enableRTS;
|
|
40
|
+
function disableRTS() {
|
|
41
|
+
exports.readyToSend = readyToSend = false;
|
|
42
|
+
}
|
|
43
|
+
exports.disableRTS = disableRTS;
|
|
44
|
+
var enableRtsTimeout = null;
|
|
45
|
+
exports.enableRtsTimeout = enableRtsTimeout;
|
|
46
|
+
var frameParser = require('./frameParser');
|
|
47
|
+
const littleEndian = true;
|
|
48
|
+
class Driver extends events_1.default.EventEmitter {
|
|
49
|
+
constructor(path) {
|
|
50
|
+
super();
|
|
51
|
+
this.frameParserEvent = frameParser.frameParserEvents;
|
|
52
|
+
this.intervals = [];
|
|
53
|
+
this.path = path;
|
|
54
|
+
this.initialized = false;
|
|
55
|
+
this.seqNumber = 0;
|
|
56
|
+
this.timeoutResetTimeout = null;
|
|
57
|
+
this.portType = socketPortUtils_1.default.isTcpPath(path) ? 'socket' : 'serial';
|
|
58
|
+
this.apsRequestFreeSlots = 1;
|
|
59
|
+
this.apsDataConfirm = 0;
|
|
60
|
+
this.apsDataIndication = 0;
|
|
61
|
+
this.configChanged = 0;
|
|
62
|
+
this.DELAY = 0;
|
|
63
|
+
this.READY_TO_SEND_TIMEOUT = 1;
|
|
64
|
+
this.HANDLE_DEVICE_STATUS_DELAY = 5;
|
|
65
|
+
this.PROCESS_QUEUES = 5;
|
|
66
|
+
const that = this;
|
|
67
|
+
setInterval(() => {
|
|
68
|
+
that.deviceStateRequest()
|
|
69
|
+
.then(result => { })
|
|
70
|
+
.catch(error => { });
|
|
71
|
+
}, 10000);
|
|
72
|
+
setInterval(() => {
|
|
73
|
+
that.writeParameterRequest(0x26, 600) // reset watchdog // 10 minutes
|
|
74
|
+
.then(result => { })
|
|
75
|
+
.catch(error => {
|
|
76
|
+
//try again
|
|
77
|
+
debug("try again to reset watchdog");
|
|
78
|
+
that.writeParameterRequest(0x26, 600)
|
|
79
|
+
.then(result => { })
|
|
80
|
+
.catch(error => { debug("warning watchdog was not reset"); });
|
|
81
|
+
});
|
|
82
|
+
}, (1000 * 60 * 8)); // 8 minutes
|
|
83
|
+
this.onParsed = this.onParsed.bind(this);
|
|
84
|
+
this.frameParserEvent.on('receivedDataNotification', (data) => { this.catchPromise(this.checkDeviceStatus(data)); });
|
|
85
|
+
this.on('close', () => {
|
|
86
|
+
this.intervals.forEach(i => clearInterval(i));
|
|
87
|
+
queue.length = 0;
|
|
88
|
+
busyQueue.length = 0;
|
|
89
|
+
apsQueue.length = 0;
|
|
90
|
+
apsBusyQueue.length = 0;
|
|
91
|
+
apsConfirmIndQueue.length = 0;
|
|
92
|
+
timeoutCounter = 0;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
registerInterval(interval) {
|
|
96
|
+
this.intervals.push(interval);
|
|
97
|
+
}
|
|
98
|
+
catchPromise(val) {
|
|
99
|
+
return Promise.resolve(val)
|
|
100
|
+
.catch(err => debug(`Promise was caught with reason: ${err}`));
|
|
101
|
+
}
|
|
102
|
+
setDelay(delay) {
|
|
103
|
+
debug(`Set delay to ${delay}`);
|
|
104
|
+
this.DELAY = delay;
|
|
105
|
+
this.READY_TO_SEND_TIMEOUT = delay;
|
|
106
|
+
this.PROCESS_QUEUES = delay;
|
|
107
|
+
this.HANDLE_DEVICE_STATUS_DELAY = delay;
|
|
108
|
+
if (this.READY_TO_SEND_TIMEOUT === 0) {
|
|
109
|
+
this.READY_TO_SEND_TIMEOUT = 1;
|
|
110
|
+
}
|
|
111
|
+
if (this.PROCESS_QUEUES < 5) {
|
|
112
|
+
this.PROCESS_QUEUES = 5;
|
|
113
|
+
}
|
|
114
|
+
if (this.HANDLE_DEVICE_STATUS_DELAY < 5) {
|
|
115
|
+
this.HANDLE_DEVICE_STATUS_DELAY = 5;
|
|
116
|
+
}
|
|
117
|
+
if (this.PROCESS_QUEUES > 60) {
|
|
118
|
+
this.PROCESS_QUEUES = 60;
|
|
119
|
+
}
|
|
120
|
+
if (this.HANDLE_DEVICE_STATUS_DELAY > 60) {
|
|
121
|
+
this.HANDLE_DEVICE_STATUS_DELAY = 60;
|
|
122
|
+
}
|
|
123
|
+
const that = this;
|
|
124
|
+
this.registerInterval(setInterval(() => { that.processQueue(); }, this.PROCESS_QUEUES)); // fire non aps requests
|
|
125
|
+
this.registerInterval(setInterval(() => { this.catchPromise(that.processBusyQueue()); }, this.PROCESS_QUEUES)); // check timeouts for non aps requests
|
|
126
|
+
this.registerInterval(setInterval(() => { this.catchPromise(that.processApsQueue()); }, this.PROCESS_QUEUES)); // fire aps request
|
|
127
|
+
this.registerInterval(setInterval(() => { that.processApsBusyQueue(); }, this.PROCESS_QUEUES)); // check timeouts for all open aps requests
|
|
128
|
+
this.registerInterval(setInterval(() => { this.catchPromise(that.processApsConfirmIndQueue()); }, this.PROCESS_QUEUES)); // fire aps indications and confirms
|
|
129
|
+
this.registerInterval(setInterval(() => { this.catchPromise(that.handleDeviceStatus()); }, this.HANDLE_DEVICE_STATUS_DELAY)); // query confirm and indication requests
|
|
130
|
+
}
|
|
131
|
+
static async isValidPath(path) {
|
|
132
|
+
return serialPortUtils_1.default.is(path, autoDetectDefinitions);
|
|
133
|
+
}
|
|
134
|
+
static async autoDetectPath() {
|
|
135
|
+
const paths = await serialPortUtils_1.default.find(autoDetectDefinitions);
|
|
136
|
+
return paths.length > 0 ? paths[0] : null;
|
|
137
|
+
}
|
|
138
|
+
onPortClose() {
|
|
139
|
+
debug('Port closed');
|
|
140
|
+
this.initialized = false;
|
|
141
|
+
this.emit('close');
|
|
142
|
+
}
|
|
143
|
+
async open() {
|
|
144
|
+
return this.portType === 'serial' ? this.openSerialPort() : this.openSocketPort();
|
|
145
|
+
}
|
|
146
|
+
openSerialPort() {
|
|
147
|
+
debug(`Opening with ${this.path}`);
|
|
148
|
+
this.serialPort = new serialPort_1.SerialPort({ path: this.path, baudRate: 38400, autoOpen: false });
|
|
149
|
+
this.writer = new writer_1.default();
|
|
150
|
+
// @ts-ignore
|
|
151
|
+
this.writer.pipe(this.serialPort);
|
|
152
|
+
this.parser = new parser_1.default();
|
|
153
|
+
this.serialPort.pipe(this.parser);
|
|
154
|
+
this.parser.on('parsed', this.onParsed);
|
|
155
|
+
return new Promise((resolve, reject) => {
|
|
156
|
+
this.serialPort.open(async (error) => {
|
|
157
|
+
if (error) {
|
|
158
|
+
reject(new Error(`Error while opening serialport '${error}'`));
|
|
159
|
+
this.initialized = false;
|
|
160
|
+
if (this.serialPort.isOpen) {
|
|
161
|
+
this.serialPort.close();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
debug('Serialport opened');
|
|
166
|
+
this.initialized = true;
|
|
167
|
+
resolve();
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
async openSocketPort() {
|
|
173
|
+
const info = socketPortUtils_1.default.parseTcpPath(this.path);
|
|
174
|
+
debug(`Opening TCP socket with ${info.host}:${info.port}`);
|
|
175
|
+
this.socketPort = new net_1.default.Socket();
|
|
176
|
+
this.socketPort.setNoDelay(true);
|
|
177
|
+
this.socketPort.setKeepAlive(true, 15000);
|
|
178
|
+
this.writer = new writer_1.default();
|
|
179
|
+
this.writer.pipe(this.socketPort);
|
|
180
|
+
this.parser = new parser_1.default();
|
|
181
|
+
this.socketPort.pipe(this.parser);
|
|
182
|
+
this.parser.on('parsed', this.onParsed);
|
|
183
|
+
return new Promise((resolve, reject) => {
|
|
184
|
+
this.socketPort.on('connect', function () {
|
|
185
|
+
debug('Socket connected');
|
|
186
|
+
});
|
|
187
|
+
// eslint-disable-next-line
|
|
188
|
+
const self = this;
|
|
189
|
+
this.socketPort.on('ready', async function () {
|
|
190
|
+
debug('Socket ready');
|
|
191
|
+
self.initialized = true;
|
|
192
|
+
resolve();
|
|
193
|
+
});
|
|
194
|
+
this.socketPort.once('close', this.onPortClose);
|
|
195
|
+
this.socketPort.on('error', function () {
|
|
196
|
+
debug('Socket error');
|
|
197
|
+
reject(new Error(`Error while opening socket`));
|
|
198
|
+
self.initialized = false;
|
|
199
|
+
});
|
|
200
|
+
this.socketPort.connect(info.port, info.host);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
close() {
|
|
204
|
+
return new Promise((resolve, reject) => {
|
|
205
|
+
if (this.initialized) {
|
|
206
|
+
if (this.portType === 'serial') {
|
|
207
|
+
this.serialPort.flush(() => {
|
|
208
|
+
this.serialPort.close((error) => {
|
|
209
|
+
this.initialized = false;
|
|
210
|
+
error == null ?
|
|
211
|
+
resolve() :
|
|
212
|
+
reject(new Error(`Error while closing serialport '${error}'`));
|
|
213
|
+
this.emit('close');
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
this.socketPort.destroy();
|
|
219
|
+
resolve();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
resolve();
|
|
224
|
+
this.emit('close');
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
readParameterRequest(parameterId) {
|
|
229
|
+
const seqNumber = this.nextSeqNumber();
|
|
230
|
+
return new Promise((resolve, reject) => {
|
|
231
|
+
//debug(`push read parameter request to queue. seqNr: ${seqNumber} paramId: ${parameterId}`);
|
|
232
|
+
const ts = 0;
|
|
233
|
+
const commandId = constants_1.default.PARAM.FrameType.ReadParameter;
|
|
234
|
+
const req = { commandId, parameterId, seqNumber, resolve, reject, ts };
|
|
235
|
+
queue.push(req);
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
writeParameterRequest(parameterId, parameter) {
|
|
239
|
+
const seqNumber = this.nextSeqNumber();
|
|
240
|
+
return new Promise((resolve, reject) => {
|
|
241
|
+
//debug(`push write parameter request to queue. seqNr: ${seqNumber} paramId: ${parameterId} parameter: ${parameter}`);
|
|
242
|
+
const ts = 0;
|
|
243
|
+
const commandId = constants_1.default.PARAM.FrameType.WriteParameter;
|
|
244
|
+
const req = { commandId, parameterId, parameter, seqNumber, resolve, reject, ts };
|
|
245
|
+
queue.push(req);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
readFirmwareVersionRequest() {
|
|
249
|
+
const seqNumber = this.nextSeqNumber();
|
|
250
|
+
return new Promise((resolve, reject) => {
|
|
251
|
+
//debug(`push read firmware version request to queue. seqNr: ${seqNumber}`);
|
|
252
|
+
const ts = 0;
|
|
253
|
+
const commandId = constants_1.default.PARAM.FrameType.ReadFirmwareVersion;
|
|
254
|
+
const req = { commandId, seqNumber, resolve, reject, ts };
|
|
255
|
+
queue.push(req);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
sendReadParameterRequest(parameterId, seqNumber) {
|
|
259
|
+
/* command id, sequence number, 0, framelength(U16), payloadlength(U16), parameter id */
|
|
260
|
+
const requestFrame = [constants_1.default.PARAM.FrameType.ReadParameter, seqNumber, 0x00, 0x08, 0x00, 0x01, 0x00, parameterId];
|
|
261
|
+
if (parameterId === constants_1.default.PARAM.Network.NETWORK_KEY) {
|
|
262
|
+
const requestFrame2 = [constants_1.default.PARAM.FrameType.ReadParameter, seqNumber, 0x00, 0x09, 0x00, 0x02, 0x00, parameterId, 0x00];
|
|
263
|
+
this.sendRequest(requestFrame2);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
this.sendRequest(requestFrame);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
sendWriteParameterRequest(parameterId, value, seqNumber) {
|
|
270
|
+
/* command id, sequence number, 0, framelength(U16), payloadlength(U16), parameter id, pameter */
|
|
271
|
+
let parameterLength = 0;
|
|
272
|
+
if (parameterId === constants_1.default.PARAM.STK.Endpoint) {
|
|
273
|
+
let arrayParameterValue = value;
|
|
274
|
+
parameterLength = arrayParameterValue.length;
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
parameterLength = this.getLengthOfParameter(parameterId);
|
|
278
|
+
}
|
|
279
|
+
//debug("SEND WRITE_PARAMETER Request - parameter id: " + parameterId + " value: " + value.toString(16) + " length: " + parameterLength);
|
|
280
|
+
const payloadLength = 1 + parameterLength;
|
|
281
|
+
const frameLength = 7 + payloadLength;
|
|
282
|
+
const fLength1 = frameLength & 0xff;
|
|
283
|
+
const fLength2 = frameLength >> 8;
|
|
284
|
+
const pLength1 = payloadLength & 0xff;
|
|
285
|
+
const pLength2 = payloadLength >> 8;
|
|
286
|
+
if (parameterId === constants_1.default.PARAM.Network.NETWORK_KEY) {
|
|
287
|
+
const requestFrame2 = [constants_1.default.PARAM.FrameType.WriteParameter, seqNumber, 0x00, 0x19, 0x00, 0x12, 0x00, parameterId, 0x00].concat(value);
|
|
288
|
+
this.sendRequest(requestFrame2);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
const requestframe = [constants_1.default.PARAM.FrameType.WriteParameter, seqNumber, 0x00, fLength1, fLength2, pLength1, pLength2, parameterId].concat(this.parameterBuffer(value, parameterLength));
|
|
292
|
+
this.sendRequest(requestframe);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
getLengthOfParameter(parameterId) {
|
|
296
|
+
switch (parameterId) {
|
|
297
|
+
case 9:
|
|
298
|
+
case 16:
|
|
299
|
+
case 21:
|
|
300
|
+
case 28:
|
|
301
|
+
case 33:
|
|
302
|
+
case 36:
|
|
303
|
+
return 1;
|
|
304
|
+
case 5:
|
|
305
|
+
case 7:
|
|
306
|
+
case 34:
|
|
307
|
+
return 2;
|
|
308
|
+
case 10:
|
|
309
|
+
case 38:
|
|
310
|
+
return 4;
|
|
311
|
+
case 1:
|
|
312
|
+
case 8:
|
|
313
|
+
case 11:
|
|
314
|
+
case 14:
|
|
315
|
+
return 8;
|
|
316
|
+
case 24:
|
|
317
|
+
case 25:
|
|
318
|
+
return 16;
|
|
319
|
+
default:
|
|
320
|
+
return 0;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
parameterBuffer(parameter, parameterLength) {
|
|
324
|
+
const paramArray = new Array();
|
|
325
|
+
if (typeof parameter === 'number') {
|
|
326
|
+
// for parameter <= 4 Byte
|
|
327
|
+
if (parameterLength > 4)
|
|
328
|
+
throw new Error("parameter to big for type number");
|
|
329
|
+
for (let i = 0; i < parameterLength; i++) {
|
|
330
|
+
paramArray[i] = (parameter >> (8 * i)) & 0xff;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
return parameter.reverse();
|
|
335
|
+
}
|
|
336
|
+
return paramArray;
|
|
337
|
+
}
|
|
338
|
+
sendReadFirmwareVersionRequest(seqNumber) {
|
|
339
|
+
/* command id, sequence number, 0, framelength(U16) */
|
|
340
|
+
const requestFrame = [constants_1.default.PARAM.FrameType.ReadFirmwareVersion, seqNumber, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00];
|
|
341
|
+
//debug(requestFrame);
|
|
342
|
+
this.sendRequest(requestFrame);
|
|
343
|
+
}
|
|
344
|
+
sendReadDeviceStateRequest(seqNumber) {
|
|
345
|
+
/* command id, sequence number, 0, framelength(U16) */
|
|
346
|
+
const requestFrame = [constants_1.default.PARAM.FrameType.ReadDeviceState, seqNumber, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00];
|
|
347
|
+
this.sendRequest(requestFrame);
|
|
348
|
+
}
|
|
349
|
+
sendRequest(buffer) {
|
|
350
|
+
const crc = this.calcCrc(Buffer.from(buffer));
|
|
351
|
+
const frame = Buffer.from(buffer.concat([crc[0], crc[1]]));
|
|
352
|
+
const slipframe = slip_1.default.encode(frame);
|
|
353
|
+
if (this.portType === 'serial') {
|
|
354
|
+
this.serialPort.write(slipframe, function (err) {
|
|
355
|
+
if (err) {
|
|
356
|
+
debug("Error writing serial Port: " + err.message);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
this.socketPort.write(slipframe, function (err) {
|
|
362
|
+
if (err) {
|
|
363
|
+
debug("Error writing socket Port: " + err.message);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
processQueue() {
|
|
369
|
+
if (queue.length === 0) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
if (busyQueue.length > 0) {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
const req = queue.shift();
|
|
376
|
+
req.ts = Date.now();
|
|
377
|
+
switch (req.commandId) {
|
|
378
|
+
case constants_1.default.PARAM.FrameType.ReadParameter:
|
|
379
|
+
debug(`send read parameter request from queue. seqNr: ${req.seqNumber} paramId: ${req.parameterId}`);
|
|
380
|
+
this.sendReadParameterRequest(req.parameterId, req.seqNumber);
|
|
381
|
+
break;
|
|
382
|
+
case constants_1.default.PARAM.FrameType.WriteParameter:
|
|
383
|
+
debug(`send write parameter request from queue. seqNr: ${req.seqNumber} paramId: ${req.parameterId} param: ${req.parameter}`);
|
|
384
|
+
this.sendWriteParameterRequest(req.parameterId, req.parameter, req.seqNumber);
|
|
385
|
+
break;
|
|
386
|
+
case constants_1.default.PARAM.FrameType.ReadFirmwareVersion:
|
|
387
|
+
debug(`send read firmware version request from queue. seqNr: ${req.seqNumber}`);
|
|
388
|
+
this.sendReadFirmwareVersionRequest(req.seqNumber);
|
|
389
|
+
break;
|
|
390
|
+
case constants_1.default.PARAM.FrameType.ReadDeviceState:
|
|
391
|
+
debug(`send read device state from queue. seqNr: ${req.seqNumber}`);
|
|
392
|
+
this.sendReadDeviceStateRequest(req.seqNumber);
|
|
393
|
+
break;
|
|
394
|
+
case constants_1.default.PARAM.NetworkState.CHANGE_NETWORK_STATE:
|
|
395
|
+
debug(`send change network state request from queue. seqNr: ${req.seqNumber}`);
|
|
396
|
+
this.sendChangeNetworkStateRequest(req.seqNumber, req.networkState);
|
|
397
|
+
break;
|
|
398
|
+
default:
|
|
399
|
+
throw new Error("process queue - unknown command id");
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
busyQueue.push(req);
|
|
403
|
+
}
|
|
404
|
+
async processBusyQueue() {
|
|
405
|
+
var _a;
|
|
406
|
+
let i = busyQueue.length;
|
|
407
|
+
while (i--) {
|
|
408
|
+
const req = busyQueue[i];
|
|
409
|
+
const now = Date.now();
|
|
410
|
+
if ((now - req.ts) > 10000) {
|
|
411
|
+
debug(`Timeout for request - CMD: 0x${req.commandId.toString(16)} seqNr: ${req.seqNumber}`);
|
|
412
|
+
//remove from busyQueue
|
|
413
|
+
busyQueue.splice(i, 1);
|
|
414
|
+
timeoutCounter++;
|
|
415
|
+
// after a timeout the timeoutcounter will be reset after 1 min. If another timeout happen then the timeoutcounter
|
|
416
|
+
// will not be reset
|
|
417
|
+
clearTimeout(this.timeoutResetTimeout);
|
|
418
|
+
this.timeoutResetTimeout = null;
|
|
419
|
+
this.resetTimeoutCounterAfter1min();
|
|
420
|
+
req.reject("TIMEOUT");
|
|
421
|
+
if (timeoutCounter >= 2) {
|
|
422
|
+
timeoutCounter = 0;
|
|
423
|
+
debug("too many timeouts - restart serial connecion");
|
|
424
|
+
if ((_a = this.serialPort) === null || _a === void 0 ? void 0 : _a.isOpen) {
|
|
425
|
+
this.serialPort.close();
|
|
426
|
+
}
|
|
427
|
+
if (this.socketPort) {
|
|
428
|
+
this.socketPort.destroy();
|
|
429
|
+
}
|
|
430
|
+
await this.open();
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
changeNetworkStateRequest(networkState) {
|
|
436
|
+
const seqNumber = this.nextSeqNumber();
|
|
437
|
+
return new Promise((resolve, reject) => {
|
|
438
|
+
//debug(`push change network state request to apsQueue. seqNr: ${seqNumber}`);
|
|
439
|
+
const ts = 0;
|
|
440
|
+
const commandId = constants_1.default.PARAM.NetworkState.CHANGE_NETWORK_STATE;
|
|
441
|
+
const req = { commandId, networkState, seqNumber, resolve, reject, ts };
|
|
442
|
+
queue.push(req);
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
sendChangeNetworkStateRequest(seqNumber, networkState) {
|
|
446
|
+
const requestFrame = [constants_1.default.PARAM.NetworkState.CHANGE_NETWORK_STATE, seqNumber, 0x00, 0x06, 0x00, networkState];
|
|
447
|
+
this.sendRequest(requestFrame);
|
|
448
|
+
}
|
|
449
|
+
deviceStateRequest() {
|
|
450
|
+
const seqNumber = this.nextSeqNumber();
|
|
451
|
+
return new Promise((resolve, reject) => {
|
|
452
|
+
//debug(`DEVICE_STATE Request - seqNr: ${seqNumber}`);
|
|
453
|
+
const ts = 0;
|
|
454
|
+
const commandId = constants_1.default.PARAM.FrameType.ReadDeviceState;
|
|
455
|
+
const req = { commandId, seqNumber, resolve, reject, ts };
|
|
456
|
+
queue.push(req);
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
async checkDeviceStatus(currentDeviceStatus) {
|
|
460
|
+
const networkState = currentDeviceStatus & 0x03;
|
|
461
|
+
this.apsDataConfirm = (currentDeviceStatus >> 2) & 0x01;
|
|
462
|
+
this.apsDataIndication = (currentDeviceStatus >> 3) & 0x01;
|
|
463
|
+
this.configChanged = (currentDeviceStatus >> 4) & 0x01;
|
|
464
|
+
this.apsRequestFreeSlots = (currentDeviceStatus >> 5) & 0x01;
|
|
465
|
+
debug("networkstate: " + networkState + " apsDataConfirm: " + this.apsDataConfirm + " apsDataIndication: " + this.apsDataIndication +
|
|
466
|
+
" configChanged: " + this.configChanged + " apsRequestFreeSlots: " + this.apsRequestFreeSlots);
|
|
467
|
+
}
|
|
468
|
+
async handleDeviceStatus() {
|
|
469
|
+
if (this.apsDataConfirm === 1) {
|
|
470
|
+
try {
|
|
471
|
+
debug("query aps data confirm");
|
|
472
|
+
this.apsDataConfirm = 0;
|
|
473
|
+
const x = await this.querySendDataStateRequest();
|
|
474
|
+
}
|
|
475
|
+
catch (e) {
|
|
476
|
+
if (e.status === 5) {
|
|
477
|
+
this.apsDataConfirm = 0;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
if (this.apsDataIndication === 1) {
|
|
482
|
+
try {
|
|
483
|
+
debug("query aps data indication");
|
|
484
|
+
this.apsDataIndication = 0;
|
|
485
|
+
const x = await this.readReceivedDataRequest();
|
|
486
|
+
}
|
|
487
|
+
catch (e) {
|
|
488
|
+
if (e.status === 5) {
|
|
489
|
+
this.apsDataIndication = 0;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
if (this.configChanged === 1) {
|
|
494
|
+
// when network settings changed
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
// DATA_IND
|
|
498
|
+
readReceivedDataRequest() {
|
|
499
|
+
const seqNumber = this.nextSeqNumber();
|
|
500
|
+
return new Promise((resolve, reject) => {
|
|
501
|
+
//debug(`push read received data request to apsQueue. seqNr: ${seqNumber}`);
|
|
502
|
+
const ts = 0;
|
|
503
|
+
const commandId = constants_1.default.PARAM.APS.DATA_INDICATION;
|
|
504
|
+
const req = { commandId, seqNumber, resolve, reject, ts };
|
|
505
|
+
apsConfirmIndQueue.push(req);
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
// DATA_REQ
|
|
509
|
+
enqueueSendDataRequest(request) {
|
|
510
|
+
const seqNumber = this.nextSeqNumber();
|
|
511
|
+
return new Promise((resolve, reject) => {
|
|
512
|
+
//debug(`push enqueue send data request to apsQueue. seqNr: ${seqNumber}`);
|
|
513
|
+
const ts = 0;
|
|
514
|
+
const requestId = request.requestId;
|
|
515
|
+
const commandId = constants_1.default.PARAM.APS.DATA_REQUEST;
|
|
516
|
+
const req = { commandId, seqNumber, request, resolve, reject, ts };
|
|
517
|
+
apsQueue.push(req);
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
// DATA_CONF
|
|
521
|
+
querySendDataStateRequest() {
|
|
522
|
+
const seqNumber = this.nextSeqNumber();
|
|
523
|
+
return new Promise((resolve, reject) => {
|
|
524
|
+
//debug(`push query send data state request to apsQueue. seqNr: ${seqNumber}`);
|
|
525
|
+
const ts = 0;
|
|
526
|
+
const commandId = constants_1.default.PARAM.APS.DATA_CONFIRM;
|
|
527
|
+
const req = { commandId, seqNumber, resolve, reject, ts };
|
|
528
|
+
apsConfirmIndQueue.push(req);
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
async processApsQueue() {
|
|
532
|
+
if (apsQueue.length === 0) {
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
if (this.apsRequestFreeSlots !== 1) {
|
|
536
|
+
debug("no free slots. Delay sending of APS Request");
|
|
537
|
+
await this.sleep(1000);
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
const req = apsQueue.shift();
|
|
541
|
+
req.ts = Date.now();
|
|
542
|
+
switch (req.commandId) {
|
|
543
|
+
case constants_1.default.PARAM.APS.DATA_REQUEST:
|
|
544
|
+
if (readyToSend === false) { // wait until last request was confirmed or given time elapsed
|
|
545
|
+
debug("delay sending of APS Request");
|
|
546
|
+
apsQueue.unshift(req);
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
disableRTS();
|
|
551
|
+
exports.enableRtsTimeout = enableRtsTimeout = setTimeout(function () { enableRTS(); }, this.READY_TO_SEND_TIMEOUT);
|
|
552
|
+
apsBusyQueue.push(req);
|
|
553
|
+
this.sendEnqueueSendDataRequest(req.request, req.seqNumber);
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
default:
|
|
557
|
+
throw new Error("process APS queue - unknown command id");
|
|
558
|
+
break;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
async processApsConfirmIndQueue() {
|
|
562
|
+
if (apsConfirmIndQueue.length === 0) {
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
const req = apsConfirmIndQueue.shift();
|
|
566
|
+
req.ts = Date.now();
|
|
567
|
+
apsBusyQueue.push(req);
|
|
568
|
+
switch (req.commandId) {
|
|
569
|
+
case constants_1.default.PARAM.APS.DATA_INDICATION:
|
|
570
|
+
//debug(`read received data request. seqNr: ${req.seqNumber}`);
|
|
571
|
+
if (this.DELAY === 0) {
|
|
572
|
+
this.sendReadReceivedDataRequest(req.seqNumber);
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
await this.sendReadReceivedDataRequest(req.seqNumber);
|
|
576
|
+
}
|
|
577
|
+
break;
|
|
578
|
+
case constants_1.default.PARAM.APS.DATA_CONFIRM:
|
|
579
|
+
//debug(`query send data state request. seqNr: ${req.seqNumber}`);
|
|
580
|
+
if (this.DELAY === 0) {
|
|
581
|
+
this.sendQueryDataStateRequest(req.seqNumber);
|
|
582
|
+
}
|
|
583
|
+
else {
|
|
584
|
+
await this.sendQueryDataStateRequest(req.seqNumber);
|
|
585
|
+
}
|
|
586
|
+
break;
|
|
587
|
+
default:
|
|
588
|
+
throw new Error("process APS Confirm/Ind queue - unknown command id");
|
|
589
|
+
break;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
sendQueryDataStateRequest(seqNumber) {
|
|
593
|
+
debug(`DATA_CONFIRM - sending data state request - SeqNr. ${seqNumber}`);
|
|
594
|
+
const requestFrame = [constants_1.default.PARAM.APS.DATA_CONFIRM, seqNumber, 0x00, 0x07, 0x00, 0x00, 0x00];
|
|
595
|
+
this.sendRequest(requestFrame);
|
|
596
|
+
}
|
|
597
|
+
sendReadReceivedDataRequest(seqNumber) {
|
|
598
|
+
debug(`DATA_INDICATION - sending read data request - SeqNr. ${seqNumber}`);
|
|
599
|
+
// payloadlength = 0, flag = none
|
|
600
|
+
const requestFrame = [constants_1.default.PARAM.APS.DATA_INDICATION, seqNumber, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01];
|
|
601
|
+
this.sendRequest(requestFrame);
|
|
602
|
+
}
|
|
603
|
+
sendEnqueueSendDataRequest(request, seqNumber) {
|
|
604
|
+
const payloadLength = 12 + ((request.destAddrMode === 0x01) ? 2 : (request.destAddrMode === 0x02) ? 3 : 9) + request.asduLength;
|
|
605
|
+
const frameLength = 7 + payloadLength;
|
|
606
|
+
const cid1 = request.clusterId & 0xff;
|
|
607
|
+
const cid2 = (request.clusterId >> 8) & 0xff;
|
|
608
|
+
const asdul1 = request.asduLength & 0xff;
|
|
609
|
+
const asdul2 = (request.asduLength >> 8) & 0xff;
|
|
610
|
+
let destArray = [];
|
|
611
|
+
let dest = "";
|
|
612
|
+
if (request.destAddr16 != null) {
|
|
613
|
+
destArray[0] = request.destAddr16 & 0xff;
|
|
614
|
+
destArray[1] = (request.destAddr16 >> 8) & 0xff;
|
|
615
|
+
dest = request.destAddr16.toString(16);
|
|
616
|
+
}
|
|
617
|
+
if (request.destAddr64 != null) {
|
|
618
|
+
dest = request.destAddr64;
|
|
619
|
+
destArray = this.macAddrStringToArray(request.destAddr64);
|
|
620
|
+
}
|
|
621
|
+
if (request.destEndpoint != null) {
|
|
622
|
+
destArray.push(request.destEndpoint);
|
|
623
|
+
dest += " EP:";
|
|
624
|
+
dest += request.destEndpoint;
|
|
625
|
+
}
|
|
626
|
+
debug(`DATA_REQUEST - destAddr: 0x${dest} SeqNr. ${seqNumber} request id: ${request.requestId}`);
|
|
627
|
+
const requestFrame = [constants_1.default.PARAM.APS.DATA_REQUEST, seqNumber, 0x00, frameLength & 0xff, (frameLength >> 8) & 0xff,
|
|
628
|
+
payloadLength & 0xff, (payloadLength >> 8) & 0xff,
|
|
629
|
+
request.requestId, 0x00, request.destAddrMode].concat(destArray).concat([request.profileId & 0xff, (request.profileId >> 8) & 0xff,
|
|
630
|
+
cid1, cid2, request.srcEndpoint, asdul1, asdul2]).concat(request.asduPayload).concat([request.txOptions, request.radius]);
|
|
631
|
+
this.sendRequest(requestFrame);
|
|
632
|
+
}
|
|
633
|
+
processApsBusyQueue() {
|
|
634
|
+
let i = apsBusyQueue.length;
|
|
635
|
+
while (i--) {
|
|
636
|
+
const req = apsBusyQueue[i];
|
|
637
|
+
const now = Date.now();
|
|
638
|
+
let timeout = 60000;
|
|
639
|
+
if (req.request != null && req.request.timeout != null) {
|
|
640
|
+
timeout = req.request.timeout * 1000; // seconds * 1000 = milliseconds
|
|
641
|
+
}
|
|
642
|
+
if ((now - req.ts) > timeout) {
|
|
643
|
+
debug(`Timeout for aps request CMD: 0x${req.commandId.toString(16)} seq: ${req.seqNumber}`);
|
|
644
|
+
//remove from busyQueue
|
|
645
|
+
apsBusyQueue.splice(i, 1);
|
|
646
|
+
req.reject(new Error("APS TIMEOUT"));
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
calcCrc(buffer) {
|
|
651
|
+
let crc = 0;
|
|
652
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
653
|
+
crc += buffer[i];
|
|
654
|
+
}
|
|
655
|
+
const crc0 = (~crc + 1) & 0xff;
|
|
656
|
+
const crc1 = ((~crc + 1) >> 8) & 0xff;
|
|
657
|
+
return [crc0, crc1];
|
|
658
|
+
}
|
|
659
|
+
macAddrStringToArray(addr) {
|
|
660
|
+
if (addr.indexOf("0x") === 0) {
|
|
661
|
+
addr = addr.slice(2, addr.length);
|
|
662
|
+
}
|
|
663
|
+
if (addr.length < 16) {
|
|
664
|
+
for (let l = 0; l < (16 - addr.length); l++) {
|
|
665
|
+
addr = "0" + addr;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
let result = new Array();
|
|
669
|
+
let y = 0;
|
|
670
|
+
for (let i = 0; i < 8; i++) {
|
|
671
|
+
result[i] = parseInt(addr.substr(y, 2), 16);
|
|
672
|
+
y += 2;
|
|
673
|
+
}
|
|
674
|
+
const reverse = result.reverse();
|
|
675
|
+
return reverse;
|
|
676
|
+
}
|
|
677
|
+
macAddrArrayToString(addr) {
|
|
678
|
+
if (addr.length != 8) {
|
|
679
|
+
throw new Error("invalid array length for MAC address: " + addr.length);
|
|
680
|
+
}
|
|
681
|
+
let result = "0x";
|
|
682
|
+
let char = '';
|
|
683
|
+
let i = 8;
|
|
684
|
+
while (i--) {
|
|
685
|
+
char = addr[i].toString(16);
|
|
686
|
+
if (char.length < 2) {
|
|
687
|
+
char = "0" + char;
|
|
688
|
+
}
|
|
689
|
+
result += char;
|
|
690
|
+
}
|
|
691
|
+
return result;
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* generalArrayToString result is not reversed!
|
|
695
|
+
*/
|
|
696
|
+
generalArrayToString(key, length) {
|
|
697
|
+
let result = "0x";
|
|
698
|
+
let char = '';
|
|
699
|
+
let i = 0;
|
|
700
|
+
while (i < length) {
|
|
701
|
+
char = key[i].toString(16);
|
|
702
|
+
if (char.length < 2) {
|
|
703
|
+
char = "0" + char;
|
|
704
|
+
}
|
|
705
|
+
result += char;
|
|
706
|
+
i++;
|
|
707
|
+
}
|
|
708
|
+
return result;
|
|
709
|
+
}
|
|
710
|
+
nextSeqNumber() {
|
|
711
|
+
this.seqNumber++;
|
|
712
|
+
if (this.seqNumber > 254) {
|
|
713
|
+
this.seqNumber = 1;
|
|
714
|
+
}
|
|
715
|
+
return this.seqNumber;
|
|
716
|
+
}
|
|
717
|
+
onParsed(frame) {
|
|
718
|
+
this.emit('rxFrame', frame);
|
|
719
|
+
}
|
|
720
|
+
sleep(ms) {
|
|
721
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
722
|
+
}
|
|
723
|
+
resetTimeoutCounterAfter1min() {
|
|
724
|
+
if (this.timeoutResetTimeout === null) {
|
|
725
|
+
this.timeoutResetTimeout = setTimeout(() => {
|
|
726
|
+
timeoutCounter = 0;
|
|
727
|
+
this.timeoutResetTimeout = null;
|
|
728
|
+
}, 60000);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
exports.default = Driver;
|
|
733
733
|
//# sourceMappingURL=driver.js.map
|