incyclist-devices 1.5.38 → 2.0.0
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/README.MD +238 -0
- package/lib/adapters.d.ts +7 -0
- package/lib/adapters.js +49 -0
- package/lib/antv2/adapter-factory.d.ts +21 -10
- package/lib/antv2/adapter-factory.js +51 -33
- package/lib/antv2/adapter.d.ts +65 -0
- package/lib/antv2/adapter.js +310 -0
- package/lib/antv2/ant-interface.d.ts +17 -11
- package/lib/antv2/ant-interface.js +41 -31
- package/lib/antv2/{ant-binding.d.ts → binding.d.ts} +1 -1
- package/lib/antv2/{ant-binding.js → binding.js} +1 -1
- package/lib/antv2/fe/adapter.d.ts +28 -0
- package/lib/antv2/{fe.js → fe/adapter.js} +106 -90
- package/lib/antv2/fe/index.d.ts +2 -0
- package/lib/antv2/fe/index.js +7 -0
- package/lib/antv2/hr/adapter.d.ts +15 -0
- package/lib/antv2/hr/adapter.js +76 -0
- package/lib/antv2/hr/index.d.ts +2 -0
- package/lib/antv2/hr/index.js +7 -0
- package/lib/antv2/index.d.ts +7 -0
- package/lib/antv2/index.js +20 -0
- package/lib/antv2/modes/ant-fe-adv-st-mode.d.ts +9 -0
- package/lib/{ant/antfe → antv2/modes}/ant-fe-adv-st-mode.js +1 -1
- package/lib/antv2/modes/ant-fe-erg-mode.d.ts +6 -0
- package/lib/{ant/antfe → antv2/modes}/ant-fe-erg-mode.js +1 -1
- package/lib/antv2/modes/ant-fe-st-mode.d.ts +5 -0
- package/lib/{ant/antfe → antv2/modes}/ant-fe-st-mode.js +1 -1
- package/lib/antv2/pwr/adapter.d.ts +24 -0
- package/lib/antv2/pwr/adapter.js +141 -0
- package/lib/antv2/pwr/index.d.ts +2 -0
- package/lib/antv2/pwr/index.js +7 -0
- package/lib/antv2/sensor-factory.d.ts +2 -2
- package/lib/antv2/types.d.ts +22 -0
- package/lib/antv2/types.js +5 -0
- package/lib/antv2/utils.d.ts +4 -0
- package/lib/antv2/utils.js +192 -0
- package/lib/base/adpater.d.ts +68 -0
- package/lib/base/adpater.js +183 -0
- package/lib/ble/adapter-factory.d.ts +33 -0
- package/lib/ble/adapter-factory.js +105 -0
- package/lib/ble/base/adapter.d.ts +53 -0
- package/lib/ble/base/adapter.js +290 -0
- package/lib/ble/base/comms-utils.d.ts +7 -0
- package/lib/ble/base/comms-utils.js +91 -0
- package/lib/ble/{ble-device.d.ts → base/comms.d.ts} +31 -16
- package/lib/ble/{ble-device.js → base/comms.js} +193 -55
- package/lib/ble/bindings/index.d.ts +2 -0
- package/lib/ble/bindings/index.js +8 -0
- package/lib/ble/bindings/linux.d.ts +15 -0
- package/lib/ble/bindings/linux.js +39 -0
- package/lib/ble/bindings/mock.d.ts +9 -0
- package/lib/ble/bindings/mock.js +108 -0
- package/lib/ble/bindings/types.d.ts +57 -0
- package/lib/ble/bindings/types.js +96 -0
- package/lib/ble/ble-interface.d.ts +38 -59
- package/lib/ble/ble-interface.js +254 -462
- package/lib/ble/ble-peripheral.d.ts +7 -5
- package/lib/ble/ble-peripheral.js +52 -21
- package/lib/ble/consts.d.ts +3 -0
- package/lib/ble/consts.js +4 -1
- package/lib/ble/cp/adapter.d.ts +22 -0
- package/lib/ble/cp/adapter.js +111 -0
- package/lib/ble/cp/comm.d.ts +31 -0
- package/lib/ble/cp/comm.js +125 -0
- package/lib/ble/cp/index.d.ts +4 -0
- package/lib/ble/cp/index.js +10 -0
- package/lib/ble/cp/types.d.ts +13 -0
- package/lib/ble/cp/types.js +2 -0
- package/lib/ble/elite/adapter.d.ts +19 -0
- package/lib/ble/elite/adapter.js +120 -0
- package/lib/ble/elite/comms.d.ts +32 -0
- package/lib/ble/elite/comms.js +126 -0
- package/lib/ble/elite/index.d.ts +3 -0
- package/lib/ble/elite/index.js +10 -0
- package/lib/ble/fm/adapter.d.ts +22 -0
- package/lib/ble/fm/adapter.js +249 -0
- package/lib/ble/fm/comms.d.ts +50 -0
- package/lib/ble/{fm.js → fm/comms.js} +34 -277
- package/lib/ble/fm/consts.d.ts +6 -0
- package/lib/ble/fm/consts.js +9 -0
- package/lib/ble/fm/index.d.ts +5 -0
- package/lib/ble/fm/index.js +13 -0
- package/lib/ble/fm/types.d.ts +30 -0
- package/lib/ble/fm/types.js +2 -0
- package/lib/ble/hr/adapter.d.ts +14 -0
- package/lib/ble/hr/adapter.js +45 -0
- package/lib/ble/hr/comm.d.ts +19 -0
- package/lib/ble/hr/comm.js +56 -0
- package/lib/ble/hr/index.d.ts +4 -0
- package/lib/ble/hr/index.js +10 -0
- package/lib/ble/hr/mock.d.ts +7 -0
- package/lib/ble/hr/mock.js +47 -0
- package/lib/ble/hr/types.d.ts +5 -0
- package/lib/ble/hr/types.js +2 -0
- package/lib/ble/index.d.ts +9 -0
- package/lib/ble/index.js +26 -0
- package/lib/ble/peripheral-cache.d.ts +43 -0
- package/lib/ble/peripheral-cache.js +107 -0
- package/lib/ble/tacx/adapter.d.ts +10 -0
- package/lib/ble/tacx/adapter.js +99 -0
- package/lib/ble/{tacx.d.ts → tacx/comms.d.ts} +11 -43
- package/lib/ble/{tacx.js → tacx/comms.js} +23 -155
- package/lib/ble/tacx/index.d.ts +4 -0
- package/lib/ble/tacx/index.js +10 -0
- package/lib/ble/tacx/types.d.ts +25 -0
- package/lib/ble/tacx/types.js +2 -0
- package/lib/ble/types.d.ts +128 -0
- package/lib/ble/types.js +2 -0
- package/lib/ble/utils.d.ts +17 -0
- package/lib/ble/utils.js +54 -0
- package/lib/ble/wahoo/adapter.d.ts +9 -0
- package/lib/ble/wahoo/adapter.js +95 -0
- package/lib/ble/{wahoo-kickr.d.ts → wahoo/comms.d.ts} +11 -44
- package/lib/ble/{wahoo-kickr.js → wahoo/comms.js} +29 -129
- package/lib/ble/wahoo/index.d.ts +4 -0
- package/lib/ble/wahoo/index.js +10 -0
- package/lib/ble/wahoo/types.d.ts +19 -0
- package/lib/ble/wahoo/types.js +2 -0
- package/lib/index.d.ts +15 -0
- package/lib/index.js +34 -0
- package/lib/interfaces.d.ts +7 -0
- package/lib/interfaces.js +27 -0
- package/lib/{ble → modes}/ble-erg-mode.d.ts +4 -4
- package/lib/{ble → modes}/ble-erg-mode.js +2 -2
- package/lib/{ble → modes}/ble-st-mode.d.ts +3 -3
- package/lib/{ble → modes}/ble-st-mode.js +1 -1
- package/lib/{cycling-mode.d.ts → modes/cycling-mode.d.ts} +8 -8
- package/lib/modes/power-base.d.ts +3 -3
- package/lib/modes/power-base.js +8 -4
- package/lib/modes/power-meter.d.ts +3 -3
- package/lib/modes/simulator.d.ts +2 -2
- package/lib/modes/simulator.js +1 -1
- package/lib/serial/adapter-factory.d.ts +12 -0
- package/lib/serial/adapter-factory.js +30 -0
- package/lib/serial/adapter.d.ts +21 -0
- package/lib/serial/adapter.js +61 -0
- package/lib/serial/bindings/tcp.d.ts +45 -0
- package/lib/serial/bindings/tcp.js +284 -0
- package/lib/serial/comm.d.ts +7 -0
- package/lib/serial/comm.js +2 -0
- package/lib/{daum → serial/daum}/DaumAdapter.d.ts +14 -23
- package/lib/{daum → serial/daum}/DaumAdapter.js +57 -97
- package/lib/{daum → serial/daum}/DaumPowerMeterCyclingMode.d.ts +2 -2
- package/lib/{daum → serial/daum}/DaumPowerMeterCyclingMode.js +1 -1
- package/lib/{daum → serial/daum}/ERGCyclingMode.d.ts +3 -3
- package/lib/{daum → serial/daum}/ERGCyclingMode.js +3 -3
- package/lib/{daum → serial/daum}/SmartTrainerCyclingMode.d.ts +3 -3
- package/lib/{daum → serial/daum}/SmartTrainerCyclingMode.js +4 -3
- package/lib/serial/daum/classic/adapter.d.ts +29 -0
- package/lib/{daum/classic/DaumClassicAdapter.js → serial/daum/classic/adapter.js} +77 -50
- package/lib/{daum/classic/bike.d.ts → serial/daum/classic/comms.d.ts} +14 -16
- package/lib/{daum/classic/bike.js → serial/daum/classic/comms.js} +68 -152
- package/lib/serial/daum/classic/mock.d.ts +96 -0
- package/lib/serial/daum/classic/mock.js +365 -0
- package/lib/{daum/classic/DaumClassicCyclingMode.d.ts → serial/daum/classic/modes/daum-classic.d.ts} +3 -3
- package/lib/{daum/classic/DaumClassicCyclingMode.js → serial/daum/classic/modes/daum-classic.js} +2 -2
- package/lib/{daum → serial/daum}/classic/utils.d.ts +1 -1
- package/lib/serial/daum/premium/adapter.d.ts +25 -0
- package/lib/{daum/premium/DaumPremiumAdapter.js → serial/daum/premium/adapter.js} +107 -47
- package/lib/{daum/premium/bike.d.ts → serial/daum/premium/comms.d.ts} +26 -54
- package/lib/{daum/premium/bike.js → serial/daum/premium/comms.js} +215 -420
- package/lib/serial/daum/premium/mock.d.ts +75 -0
- package/lib/serial/daum/premium/mock.js +289 -0
- package/lib/{daum/premium/DaumClassicCyclingMode.d.ts → serial/daum/premium/modes/daum-classic.d.ts} +3 -3
- package/lib/{daum/premium/DaumClassicCyclingMode.js → serial/daum/premium/modes/daum-classic.js} +2 -2
- package/lib/serial/daum/premium/types.d.ts +12 -0
- package/lib/serial/daum/premium/types.js +2 -0
- package/lib/{daum → serial/daum}/premium/utils.d.ts +8 -11
- package/lib/{daum → serial/daum}/premium/utils.js +22 -63
- package/lib/serial/index.d.ts +9 -0
- package/lib/serial/index.js +49 -0
- package/lib/{kettler → serial/kettler}/comms.d.ts +8 -6
- package/lib/{kettler → serial/kettler}/comms.js +71 -32
- package/lib/{kettler → serial/kettler}/ergo-racer/adapter.d.ts +14 -28
- package/lib/{kettler → serial/kettler}/ergo-racer/adapter.js +102 -169
- package/lib/serial/kettler/ergo-racer/mock.d.ts +66 -0
- package/lib/serial/kettler/ergo-racer/mock.js +216 -0
- package/lib/{kettler/ergo-racer/ERGCyclingMode.d.ts → serial/kettler/ergo-racer/modes/erg.d.ts} +4 -4
- package/lib/{kettler/ergo-racer/ERGCyclingMode.js → serial/kettler/ergo-racer/modes/erg.js} +2 -2
- package/lib/serial/serial-interface.d.ts +60 -0
- package/lib/serial/serial-interface.js +309 -0
- package/lib/simulator/Simulator.d.ts +12 -25
- package/lib/simulator/Simulator.js +26 -87
- package/lib/types/adapter.d.ts +39 -0
- package/lib/types/adapter.js +2 -0
- package/lib/types/capabilities.d.ts +8 -0
- package/lib/types/capabilities.js +12 -0
- package/lib/types/data.d.ts +12 -0
- package/lib/types/data.js +2 -0
- package/lib/types/device.d.ts +32 -0
- package/lib/types/device.js +11 -0
- package/lib/types/interface.d.ts +18 -0
- package/lib/types/interface.js +2 -0
- package/lib/types/route.d.ts +2 -2
- package/lib/types/user.d.ts +1 -1
- package/lib/{utils.d.ts → utils/utils.d.ts} +1 -0
- package/lib/{utils.js → utils/utils.js} +5 -1
- package/package.json +16 -14
- package/lib/DeviceSupport.d.ts +0 -36
- package/lib/DeviceSupport.js +0 -82
- package/lib/ant/AntAdapter.d.ts +0 -50
- package/lib/ant/AntAdapter.js +0 -109
- package/lib/ant/AntScanner.d.ts +0 -60
- package/lib/ant/AntScanner.js +0 -651
- package/lib/ant/antfe/AntFEAdapter.d.ts +0 -83
- package/lib/ant/antfe/AntFEAdapter.js +0 -652
- package/lib/ant/antfe/ant-fe-adv-st-mode.d.ts +0 -9
- package/lib/ant/antfe/ant-fe-erg-mode.d.ts +0 -6
- package/lib/ant/antfe/ant-fe-st-mode.d.ts +0 -5
- package/lib/ant/anthrm/AntHrmAdapter.d.ts +0 -16
- package/lib/ant/anthrm/AntHrmAdapter.js +0 -130
- package/lib/ant/antpwr/pwr-adapter.d.ts +0 -49
- package/lib/ant/antpwr/pwr-adapter.js +0 -251
- package/lib/ant/utils.d.ts +0 -1
- package/lib/ant/utils.js +0 -23
- package/lib/antv2/AntAdapter.d.ts +0 -48
- package/lib/antv2/AntAdapter.js +0 -104
- package/lib/antv2/ant-device.d.ts +0 -59
- package/lib/antv2/ant-device.js +0 -161
- package/lib/antv2/fe.d.ts +0 -32
- package/lib/antv2/hr.d.ts +0 -18
- package/lib/antv2/hr.js +0 -102
- package/lib/antv2/incyclist-protocol.d.ts +0 -37
- package/lib/antv2/incyclist-protocol.js +0 -126
- package/lib/antv2/pwr.d.ts +0 -28
- package/lib/antv2/pwr.js +0 -171
- package/lib/ble/ble.d.ts +0 -129
- package/lib/ble/ble.js +0 -86
- package/lib/ble/elite.d.ts +0 -90
- package/lib/ble/elite.js +0 -322
- package/lib/ble/fm.d.ts +0 -125
- package/lib/ble/hrm.d.ts +0 -48
- package/lib/ble/hrm.js +0 -134
- package/lib/ble/incyclist-protocol.d.ts +0 -31
- package/lib/ble/incyclist-protocol.js +0 -153
- package/lib/ble/pwr.d.ts +0 -89
- package/lib/ble/pwr.js +0 -322
- package/lib/daum/classic/DaumClassicAdapter.d.ts +0 -28
- package/lib/daum/classic/DaumClassicProtocol.d.ts +0 -27
- package/lib/daum/classic/DaumClassicProtocol.js +0 -185
- package/lib/daum/premium/DaumPremiumAdapter.d.ts +0 -16
- package/lib/daum/premium/DaumPremiumProtocol.d.ts +0 -32
- package/lib/daum/premium/DaumPremiumProtocol.js +0 -207
- package/lib/daum/premium/tcpserial.d.ts +0 -33
- package/lib/daum/premium/tcpserial.js +0 -123
- package/lib/device.d.ts +0 -94
- package/lib/device.js +0 -76
- package/lib/kettler/ergo-racer/protocol.d.ts +0 -41
- package/lib/kettler/ergo-racer/protocol.js +0 -203
- package/lib/protocol.d.ts +0 -74
- package/lib/protocol.js +0 -41
- package/lib/registry.d.ts +0 -8
- package/lib/registry.js +0 -33
- package/lib/serialport/bindings/tcp.d.ts +0 -20
- package/lib/serialport/bindings/tcp.js +0 -33
- package/lib/serialport/index.d.ts +0 -2
- package/lib/serialport/index.js +0 -29
- package/lib/serialport/serialport.d.ts +0 -29
- package/lib/serialport/serialport.js +0 -87
- /package/lib/{cycling-mode.js → modes/cycling-mode.js} +0 -0
- /package/lib/{daum → serial/daum}/classic/utils.js +0 -0
- /package/lib/{daum → serial/daum}/constants.d.ts +0 -0
- /package/lib/{daum → serial/daum}/constants.js +0 -0
- /package/lib/{serialport.d.ts → serial/serialport.d.ts} +0 -0
- /package/lib/{serialport.js → serial/serialport.js} +0 -0
- /package/lib/{calculations.d.ts → utils/calculations.d.ts} +0 -0
- /package/lib/{calculations.js → utils/calculations.js} +0 -0
package/lib/ble/ble-interface.js
CHANGED
|
@@ -13,23 +13,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
const gd_eventlog_1 = require("gd-eventlog");
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
16
|
+
const adapter_factory_1 = __importDefault(require("./adapter-factory"));
|
|
17
|
+
const utils_1 = require("./utils");
|
|
18
|
+
const comms_utils_1 = require("./base/comms-utils");
|
|
19
|
+
const peripheral_cache_1 = __importDefault(require("./peripheral-cache"));
|
|
20
|
+
const events_1 = __importDefault(require("events"));
|
|
21
|
+
const utils_2 = require("../utils/utils");
|
|
21
22
|
const DEFAULT_SCAN_TIMEOUT = 20000;
|
|
22
|
-
class BleInterface extends
|
|
23
|
-
constructor(props = {}) {
|
|
24
|
-
super(props);
|
|
25
|
-
this.scanState = { isScanning: false, isConnecting: false, timeout: undefined, isBackgroundScan: false };
|
|
26
|
-
this.connectState = { isConnecting: false, isConnected: false, isInitSuccess: false };
|
|
27
|
-
this.devices = [];
|
|
28
|
-
this.peripheralCache = [];
|
|
29
|
-
if (props.logger)
|
|
30
|
-
this.logger = props.logger;
|
|
31
|
-
this.logger = new gd_eventlog_1.EventLogger('BLE');
|
|
32
|
-
}
|
|
23
|
+
class BleInterface extends events_1.default {
|
|
33
24
|
static getInstance(props = {}) {
|
|
34
25
|
if (!BleInterface._instance) {
|
|
35
26
|
BleInterface._instance = new BleInterface(props);
|
|
@@ -47,10 +38,42 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
47
38
|
}
|
|
48
39
|
return BleInterface._instance;
|
|
49
40
|
}
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
constructor(props = {}) {
|
|
42
|
+
super();
|
|
43
|
+
this.scanState = { isScanning: false, isConnecting: false, timeout: undefined, isBackgroundScan: false };
|
|
44
|
+
this.connectState = { isConnecting: false, isConnected: false, isInitSuccess: false };
|
|
45
|
+
this.props = props;
|
|
46
|
+
if (props.binding)
|
|
47
|
+
this.setBinding(props.binding);
|
|
48
|
+
this.peripheralCache = new peripheral_cache_1.default();
|
|
49
|
+
this.connectedDevices = [];
|
|
50
|
+
if (props.logger)
|
|
51
|
+
this.logger = props.logger;
|
|
52
|
+
else
|
|
53
|
+
this.logger = new gd_eventlog_1.EventLogger('BLE');
|
|
54
|
+
}
|
|
55
|
+
getBinding() { return this.binding; }
|
|
56
|
+
setBinding(binding) { if (binding)
|
|
57
|
+
this.binding = binding; }
|
|
58
|
+
getName() {
|
|
59
|
+
return 'ble';
|
|
60
|
+
}
|
|
61
|
+
startConnectSensor() {
|
|
62
|
+
this.sensorIsConnecting = true;
|
|
63
|
+
}
|
|
64
|
+
stopConnectSensor() {
|
|
65
|
+
this.sensorIsConnecting = false;
|
|
66
|
+
}
|
|
67
|
+
waitForSensorConnectionFinish() {
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
while (this.sensorIsConnecting && this.connectState.isConnected) {
|
|
70
|
+
yield (0, utils_2.sleep)(100);
|
|
71
|
+
}
|
|
52
72
|
return;
|
|
53
|
-
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
getAdapterFactory() {
|
|
76
|
+
return adapter_factory_1.default.getInstance();
|
|
54
77
|
}
|
|
55
78
|
logEvent(event) {
|
|
56
79
|
if (this.logger) {
|
|
@@ -61,7 +84,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
61
84
|
}
|
|
62
85
|
}
|
|
63
86
|
onStateChange(state) {
|
|
64
|
-
if (state !==
|
|
87
|
+
if (state !== 'poweredOn') {
|
|
65
88
|
this.connectState.isConnected = false;
|
|
66
89
|
}
|
|
67
90
|
else {
|
|
@@ -71,48 +94,25 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
71
94
|
onError(err) {
|
|
72
95
|
this.logEvent({ message: 'error', error: err.message, stack: err.stack });
|
|
73
96
|
}
|
|
74
|
-
connect(
|
|
75
|
-
const timeout = props.timeout || 2000;
|
|
97
|
+
connect(to) {
|
|
98
|
+
const timeout = this.props.timeout || to || 2000;
|
|
76
99
|
return new Promise((resolve, reject) => {
|
|
77
100
|
if (this.connectState.isConnected) {
|
|
78
101
|
return resolve(true);
|
|
79
102
|
}
|
|
80
|
-
this.logEvent({ message: 'connect request', });
|
|
103
|
+
this.logEvent({ message: 'Ble connect request', });
|
|
81
104
|
if (!this.getBinding())
|
|
82
105
|
return Promise.reject(new Error('no binding defined'));
|
|
83
106
|
this.connectState.timeout = setTimeout(() => {
|
|
84
107
|
this.connectState.isConnected = false;
|
|
85
108
|
this.connectState.isConnecting = false;
|
|
86
109
|
this.connectState.timeout = null;
|
|
87
|
-
this.logEvent({ message: 'connect result: timeout' });
|
|
88
|
-
|
|
110
|
+
this.logEvent({ message: 'Ble connect result: timeout' });
|
|
111
|
+
resolve(false);
|
|
89
112
|
}, timeout);
|
|
90
113
|
try {
|
|
91
|
-
if (!this.connectState.isInitSuccess) {
|
|
92
|
-
const binding = this.getBinding()._bindings;
|
|
93
|
-
if (binding) {
|
|
94
|
-
const binding_init_original = binding.init.bind(binding);
|
|
95
|
-
const self = this;
|
|
96
|
-
binding.on('error', (err) => { this.getBinding().emit('error', err); });
|
|
97
|
-
binding.init = function () {
|
|
98
|
-
try {
|
|
99
|
-
binding_init_original();
|
|
100
|
-
self.connectState.isInitSuccess = true;
|
|
101
|
-
}
|
|
102
|
-
catch (err) {
|
|
103
|
-
self.connectState.isInitSuccess = false;
|
|
104
|
-
self.connectState.isConnected = false;
|
|
105
|
-
self.connectState.isConnecting = false;
|
|
106
|
-
self.logEvent({ message: 'connect result: error', error: err.message });
|
|
107
|
-
return reject(new Error(err.message));
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
114
|
const state = this.getBinding().state;
|
|
115
|
-
if (state ===
|
|
115
|
+
if (state === 'poweredOn') {
|
|
116
116
|
clearTimeout(this.connectState.timeout);
|
|
117
117
|
this.connectState.timeout = null;
|
|
118
118
|
this.getBinding().removeAllListeners('stateChange');
|
|
@@ -132,14 +132,14 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
132
132
|
return reject(err);
|
|
133
133
|
});
|
|
134
134
|
this.getBinding().on('stateChange', (state) => {
|
|
135
|
-
if (state ===
|
|
135
|
+
if (state === 'poweredOn') {
|
|
136
136
|
clearTimeout(this.connectState.timeout);
|
|
137
137
|
this.connectState.timeout = null;
|
|
138
138
|
this.getBinding().removeAllListeners('stateChange');
|
|
139
139
|
this.getBinding().on('stateChange', this.onStateChange.bind(this));
|
|
140
140
|
this.connectState.isConnected = true;
|
|
141
141
|
this.connectState.isConnecting = false;
|
|
142
|
-
this.logEvent({ message: 'connect result: success' });
|
|
142
|
+
this.logEvent({ message: 'Ble connect result: success' });
|
|
143
143
|
return resolve(true);
|
|
144
144
|
}
|
|
145
145
|
else {
|
|
@@ -154,7 +154,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
154
154
|
if (this.connectState.timeout)
|
|
155
155
|
clearTimeout(this.connectState.timeout);
|
|
156
156
|
this.connectState.timeout = null;
|
|
157
|
-
this.logEvent({ message: 'connect result: error', error: err.message });
|
|
157
|
+
this.logEvent({ message: 'Ble connect result: error', error: err.message });
|
|
158
158
|
return reject(new Error('bluetooth unavailable, cause: ' + err.message));
|
|
159
159
|
}
|
|
160
160
|
});
|
|
@@ -170,11 +170,11 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
170
170
|
if (this.scanState.isScanning) {
|
|
171
171
|
yield this.stopScan();
|
|
172
172
|
}
|
|
173
|
-
const
|
|
173
|
+
const devices = this.getAdapterFactory().getAllInstances();
|
|
174
|
+
const connectedDevices = devices.filter(d => d.isConnected());
|
|
174
175
|
for (let i = 0; i < connectedDevices.length; i++) {
|
|
175
176
|
const d = connectedDevices[i];
|
|
176
|
-
|
|
177
|
-
yield device.disconnect();
|
|
177
|
+
yield d.close();
|
|
178
178
|
}
|
|
179
179
|
this.connectState.isConnected = false;
|
|
180
180
|
this.connectState.isConnecting = false;
|
|
@@ -189,83 +189,6 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
189
189
|
isConnected() {
|
|
190
190
|
return this.connectState.isConnected;
|
|
191
191
|
}
|
|
192
|
-
getDevicesFromServices(deviceTypes, services) {
|
|
193
|
-
if (!deviceTypes || !Array.isArray(deviceTypes) || deviceTypes.length === 0) {
|
|
194
|
-
return [];
|
|
195
|
-
}
|
|
196
|
-
const get = (deviceTypes, fnCompare) => {
|
|
197
|
-
const types = deviceTypes.filter(DeviceType => {
|
|
198
|
-
const C = DeviceType;
|
|
199
|
-
let found = false;
|
|
200
|
-
if (C.services)
|
|
201
|
-
found = C.services.find((s) => fnCompare(s));
|
|
202
|
-
return found;
|
|
203
|
-
});
|
|
204
|
-
return types;
|
|
205
|
-
};
|
|
206
|
-
if (typeof services === 'string') {
|
|
207
|
-
return get(deviceTypes, (s) => (0, ble_2.matches)(s, services));
|
|
208
|
-
}
|
|
209
|
-
if (Array.isArray(services)) {
|
|
210
|
-
const sids = services.map(ble_1.uuid);
|
|
211
|
-
return get(deviceTypes, s => {
|
|
212
|
-
const res = sids.find((service) => (0, ble_2.matches)(s, service));
|
|
213
|
-
return res !== undefined;
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
return [];
|
|
217
|
-
}
|
|
218
|
-
getAllSupportedServices() {
|
|
219
|
-
const supported = BleInterface.deviceClasses;
|
|
220
|
-
const res = [];
|
|
221
|
-
if (supported && supported.length > 0) {
|
|
222
|
-
supported.forEach(dc => {
|
|
223
|
-
if (dc && dc.services) {
|
|
224
|
-
dc.services.forEach(s => {
|
|
225
|
-
if (!res.includes(s))
|
|
226
|
-
res.push(s);
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
return res;
|
|
232
|
-
}
|
|
233
|
-
getAllSupportedDeviceTypes() {
|
|
234
|
-
const supported = BleInterface.deviceClasses;
|
|
235
|
-
return supported.map(dc => dc.Class);
|
|
236
|
-
}
|
|
237
|
-
getServicesFromDeviceTypes(deviceTypes) {
|
|
238
|
-
let services = [];
|
|
239
|
-
try {
|
|
240
|
-
if (!deviceTypes || !Array.isArray(deviceTypes) || deviceTypes.length === 0) {
|
|
241
|
-
return [];
|
|
242
|
-
}
|
|
243
|
-
deviceTypes.forEach(DeviceType => {
|
|
244
|
-
if (DeviceType.services) {
|
|
245
|
-
const dtServices = DeviceType.services;
|
|
246
|
-
dtServices.forEach(s => {
|
|
247
|
-
if (!services.find(s2 => s2 === s))
|
|
248
|
-
services.push(s);
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
catch (err) {
|
|
254
|
-
console.log(err);
|
|
255
|
-
}
|
|
256
|
-
return services;
|
|
257
|
-
}
|
|
258
|
-
getServicesFromDevice(device) {
|
|
259
|
-
if (!device)
|
|
260
|
-
return [];
|
|
261
|
-
const services = [];
|
|
262
|
-
const dServices = device.getServiceUUids();
|
|
263
|
-
dServices.forEach(s => {
|
|
264
|
-
if (!services.find(s2 => s2 === s))
|
|
265
|
-
services.push(s);
|
|
266
|
-
});
|
|
267
|
-
return services;
|
|
268
|
-
}
|
|
269
192
|
waitForConnectFinished(timeout) {
|
|
270
193
|
const waitStart = Date.now();
|
|
271
194
|
const waitTimeout = waitStart + timeout;
|
|
@@ -282,39 +205,18 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
282
205
|
}, 100);
|
|
283
206
|
});
|
|
284
207
|
}
|
|
285
|
-
addPeripheralToCache(peripheral, props = {}) {
|
|
286
|
-
const info = this.peripheralCache.find(i => i.address === peripheral.address);
|
|
287
|
-
const connector = info && info.connector ? info.connector : new ble_peripheral_1.default(this, peripheral);
|
|
288
|
-
this.peripheralCache.push(Object.assign({ address: peripheral.address, ts: Date.now(), peripheral, connector }, props));
|
|
289
|
-
}
|
|
290
208
|
onDisconnect(peripheral) {
|
|
291
|
-
|
|
292
|
-
if (idx !== -1)
|
|
293
|
-
this.peripheralCache.splice(idx, 1);
|
|
294
|
-
}
|
|
295
|
-
getConnector(peripheral) {
|
|
296
|
-
const info = this.peripheralCache.find(i => i.address === peripheral.address);
|
|
297
|
-
if (!info) {
|
|
298
|
-
const connector = new ble_peripheral_1.default(this, peripheral);
|
|
299
|
-
this.peripheralCache.push({ address: peripheral.address, ts: Date.now(), peripheral, connector });
|
|
300
|
-
return connector;
|
|
301
|
-
}
|
|
302
|
-
return info.connector;
|
|
303
|
-
}
|
|
304
|
-
findPeripheral(peripheral) {
|
|
305
|
-
const info = this.peripheralCache.find(i => i.address === peripheral.address || peripheral.address === i.peripheral.address || peripheral.name === i.peripheral.name || peripheral.id === i.peripheral.id);
|
|
306
|
-
return info ? info.peripheral : undefined;
|
|
209
|
+
this.peripheralCache.remove(peripheral);
|
|
307
210
|
}
|
|
308
211
|
getCharacteristics(peripheral) {
|
|
309
212
|
return __awaiter(this, void 0, void 0, function* () {
|
|
310
213
|
let characteristics = undefined;
|
|
311
|
-
let chachedPeripheralInfo = this.peripheralCache.find(
|
|
214
|
+
let chachedPeripheralInfo = this.peripheralCache.find({ peripheral });
|
|
312
215
|
if (chachedPeripheralInfo && Date.now() - chachedPeripheralInfo.ts > 600000) {
|
|
313
216
|
chachedPeripheralInfo.ts = Date.now();
|
|
314
217
|
}
|
|
315
218
|
if (!chachedPeripheralInfo) {
|
|
316
|
-
this.
|
|
317
|
-
chachedPeripheralInfo = this.peripheralCache.find(i => i.address === peripheral.address);
|
|
219
|
+
chachedPeripheralInfo = this.peripheralCache.add({ address: peripheral.address, ts: Date.now(), peripheral });
|
|
318
220
|
}
|
|
319
221
|
const connector = chachedPeripheralInfo.connector;
|
|
320
222
|
if (!chachedPeripheralInfo.characteristics) {
|
|
@@ -324,150 +226,23 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
324
226
|
peripheral.state = connector.getState();
|
|
325
227
|
yield connector.initialize();
|
|
326
228
|
characteristics = connector.getCharachteristics();
|
|
327
|
-
this.logEvent({ message: 'characteristic info (+):', info: characteristics.map(
|
|
229
|
+
this.logEvent({ message: 'characteristic info (+):', address: peripheral.address, info: characteristics.map(utils_1.getCharachteristicsInfo) });
|
|
328
230
|
chachedPeripheralInfo.characteristics = characteristics;
|
|
329
231
|
chachedPeripheralInfo.state = { isConfigured: true, isLoading: false, isInterrupted: false };
|
|
330
232
|
}
|
|
331
233
|
catch (err) {
|
|
332
|
-
console.log(err);
|
|
234
|
+
console.log('~~ ERROR', err);
|
|
333
235
|
}
|
|
334
236
|
}
|
|
335
237
|
else {
|
|
336
238
|
characteristics = chachedPeripheralInfo.characteristics;
|
|
337
|
-
this.logEvent({ message: 'characteristic info (*):', info: characteristics.map(
|
|
239
|
+
this.logEvent({ message: 'characteristic info (*):', address: peripheral.address, info: characteristics.map(utils_1.getCharachteristicsInfo) });
|
|
338
240
|
}
|
|
339
241
|
if (!characteristics)
|
|
340
242
|
this.logEvent({ message: 'characteristic info:', info: 'none' });
|
|
341
243
|
return characteristics;
|
|
342
244
|
});
|
|
343
245
|
}
|
|
344
|
-
getDeviceClasses(peripheral, props = {}) {
|
|
345
|
-
let DeviceClasses;
|
|
346
|
-
const { deviceTypes, profile, services = peripheral.advertisement.serviceUuids } = props;
|
|
347
|
-
if ((!deviceTypes || deviceTypes.length === 0)) {
|
|
348
|
-
const classes = BleInterface.deviceClasses.map(c => c.Class);
|
|
349
|
-
DeviceClasses = this.getDevicesFromServices(classes, services);
|
|
350
|
-
}
|
|
351
|
-
else {
|
|
352
|
-
DeviceClasses = this.getDevicesFromServices(deviceTypes, services);
|
|
353
|
-
}
|
|
354
|
-
if (profile && DeviceClasses && DeviceClasses.length > 0) {
|
|
355
|
-
DeviceClasses = DeviceClasses.filter(C => {
|
|
356
|
-
const device = new C({ peripheral });
|
|
357
|
-
if (device.getProfile() !== profile)
|
|
358
|
-
return false;
|
|
359
|
-
return true;
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
return DeviceClasses;
|
|
363
|
-
}
|
|
364
|
-
createDevice(DeviceClass, peripheral, characteristics) {
|
|
365
|
-
try {
|
|
366
|
-
const C = DeviceClass;
|
|
367
|
-
const device = new C({ peripheral });
|
|
368
|
-
const cids = characteristics ? characteristics.map(c => (0, ble_1.uuid)(c.uuid)) : [];
|
|
369
|
-
this.logEvent({ message: 'trying to create device', peripheral: peripheral.address, characteristics: cids, profile: device.getProfile() });
|
|
370
|
-
const existingDevice = this.devices.find(i => i.device.id === device.id && i.device.getProfile() === device.getProfile());
|
|
371
|
-
if (existingDevice)
|
|
372
|
-
return existingDevice.device;
|
|
373
|
-
device.setInterface(this);
|
|
374
|
-
if (characteristics && device.isMatching(cids)) {
|
|
375
|
-
device.characteristics = characteristics;
|
|
376
|
-
device.setCharacteristicUUIDs(characteristics.map(c => c.uuid));
|
|
377
|
-
return device;
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
380
|
-
this.logEvent({ message: 'failed to create device', peripheral: peripheral.address, profile: device.getProfile() });
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
catch (err) {
|
|
384
|
-
this.logEvent({ message: 'error', fn: '', error: err.message || err, stack: err.stack });
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
connectDevice(requested, timeout = DEFAULT_SCAN_TIMEOUT + CONNECT_TIMEOUT) {
|
|
388
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
389
|
-
const { id, name, address } = requested;
|
|
390
|
-
const profile = requested instanceof ble_1.BleDeviceClass ?
|
|
391
|
-
(requested.getProfile && typeof (requested.getProfile) === 'function' ? requested.getProfile() : undefined) :
|
|
392
|
-
requested.profile;
|
|
393
|
-
this.logEvent({ message: 'connectDevice', id, name, address, profile, isbusy: this.scanState.isConnecting });
|
|
394
|
-
if (this.scanState.isConnecting) {
|
|
395
|
-
yield this.waitForConnectFinished(CONNECT_TIMEOUT);
|
|
396
|
-
}
|
|
397
|
-
this.scanState.isConnecting = true;
|
|
398
|
-
const existing = this.devices.find(i => (!profile || i.device.getProfile() === profile) && (i.device.address === requested.address || i.device.id === requested.id || i.device.name === requested.name));
|
|
399
|
-
if (existing) {
|
|
400
|
-
this.logEvent({ message: 'connect existing device' });
|
|
401
|
-
yield existing.device.connect();
|
|
402
|
-
this.scanState.isConnecting = false;
|
|
403
|
-
return existing.device;
|
|
404
|
-
}
|
|
405
|
-
const peripheralInfo = this.peripheralCache.find(i => (i.address === requested.address || (i.periphal && i.peripheral.id === requested.id)));
|
|
406
|
-
if (peripheralInfo) {
|
|
407
|
-
if (!peripheralInfo.characteristic) {
|
|
408
|
-
yield this.getCharacteristics(peripheralInfo.periphal);
|
|
409
|
-
const DeviceClasses = this.getDeviceClasses(peripheralInfo.peripheral, { profile });
|
|
410
|
-
if (!DeviceClasses || DeviceClasses.length === 0)
|
|
411
|
-
return;
|
|
412
|
-
const devices = DeviceClasses.map(C => this.createDevice(C, peripheralInfo.periphal, peripheralInfo.characteristics));
|
|
413
|
-
if (devices && devices.length > 0) {
|
|
414
|
-
for (let i = 0; i < devices.length; i++) {
|
|
415
|
-
const idx = this.devices.push({ device: devices[i], isConnected: false }) - 1;
|
|
416
|
-
if (!devices[i].isConnected())
|
|
417
|
-
yield devices[i].connect();
|
|
418
|
-
this.devices[idx].isConnected = true;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
const connectedDevice = this.devices.find(d => d.isConnected);
|
|
423
|
-
if (connectedDevice)
|
|
424
|
-
return connectedDevice.device;
|
|
425
|
-
}
|
|
426
|
-
let devices = [];
|
|
427
|
-
let retry = false;
|
|
428
|
-
let retryCount = 0;
|
|
429
|
-
do {
|
|
430
|
-
if (retryCount > 0) {
|
|
431
|
-
this.logEvent({ message: 'retry connect device', id, name, address, profile, retryCount });
|
|
432
|
-
}
|
|
433
|
-
try {
|
|
434
|
-
devices = yield this.scan({ timeout: DEFAULT_SCAN_TIMEOUT, requested: requested });
|
|
435
|
-
if (devices.length === 0) {
|
|
436
|
-
retryCount++;
|
|
437
|
-
retry = retryCount < 5;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
catch (err) {
|
|
441
|
-
if (err.message === 'scanning already in progress') {
|
|
442
|
-
yield (0, utils_1.sleep)(1000);
|
|
443
|
-
retryCount++;
|
|
444
|
-
retry = retryCount < 5;
|
|
445
|
-
continue;
|
|
446
|
-
}
|
|
447
|
-
this.scanState.isConnecting = false;
|
|
448
|
-
throw err;
|
|
449
|
-
}
|
|
450
|
-
} while (devices.length === 0 && retry);
|
|
451
|
-
if (devices.length === 0) {
|
|
452
|
-
this.logEvent({ message: 'connectDevice failure', id, name, address, profile, error: 'device not found' });
|
|
453
|
-
this.scanState.isConnecting = false;
|
|
454
|
-
throw new Error('device not found');
|
|
455
|
-
}
|
|
456
|
-
if (devices[0]) {
|
|
457
|
-
this.logEvent({ message: 'connectDevice connecting', id, name, address, profile });
|
|
458
|
-
const connected = yield devices[0].connect();
|
|
459
|
-
this.scanState.isConnecting = false;
|
|
460
|
-
if (connected) {
|
|
461
|
-
this.logEvent({ message: 'connectDevice success', id, name, address, profile });
|
|
462
|
-
return devices[0];
|
|
463
|
-
}
|
|
464
|
-
else {
|
|
465
|
-
this.logEvent({ message: 'connectDevice failure', id, name, address, profile });
|
|
466
|
-
throw new Error('connect failed');
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
});
|
|
470
|
-
}
|
|
471
246
|
waitForScanFinished(timeout) {
|
|
472
247
|
const waitStart = Date.now();
|
|
473
248
|
const waitTimeout = waitStart + timeout;
|
|
@@ -484,181 +259,222 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
484
259
|
}, 100);
|
|
485
260
|
});
|
|
486
261
|
}
|
|
487
|
-
|
|
488
|
-
if (!DeviceClasses || DeviceClasses.length === 0)
|
|
489
|
-
return;
|
|
490
|
-
const details = DeviceClasses.map(c => ({ name: c.prototype.constructor.name, priority: c.detectionPriority || 0, class: c }));
|
|
491
|
-
details.sort((a, b) => b.priority - a.priority);
|
|
492
|
-
return details[0].class;
|
|
493
|
-
}
|
|
494
|
-
scan(props) {
|
|
262
|
+
onPeripheralFound(p, callback, props = {}) {
|
|
495
263
|
return __awaiter(this, void 0, void 0, function* () {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
264
|
+
let peripheral = p;
|
|
265
|
+
if (!peripheral || !peripheral.advertisement || !peripheral.advertisement.localName) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const scanForDevice = (props.comms !== undefined) || (props.request !== undefined && props.request !== null);
|
|
269
|
+
const request = props.comms ? props.comms.getSettings() : props.request;
|
|
270
|
+
if (scanForDevice && this.scanState.peripherals.size > 0) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
if (!this.scanState.peripherals)
|
|
274
|
+
this.scanState.peripherals = new Map();
|
|
275
|
+
if (peripheral.address === undefined || peripheral.address === '')
|
|
276
|
+
peripheral.address = peripheral.id || peripheral.name;
|
|
277
|
+
const isPeripheralProcessed = this.scanState.peripherals.get(peripheral.address) !== undefined;
|
|
278
|
+
if (isPeripheralProcessed) {
|
|
279
|
+
return;
|
|
510
280
|
}
|
|
511
|
-
const peripheralsProcessed = [];
|
|
512
|
-
const devicesProcessed = [];
|
|
513
|
-
this.logEvent({ message: 'scan()', props: { timeout }, scanState: this.scanState,
|
|
514
|
-
peripheralCache: this.peripheralCache.map(i => ({ address: i.address, ts: i.ts, name: i.peripheral ? i.peripheral.advertisement.localName : '' })),
|
|
515
|
-
deviceCache: this.devices.map(i => ({ address: i.device.address, profile: i.device.getProfile(), isConnected: i.isConnected }))
|
|
516
|
-
});
|
|
517
|
-
let opStr;
|
|
518
281
|
if (scanForDevice) {
|
|
519
|
-
|
|
520
|
-
|
|
282
|
+
let found = false;
|
|
283
|
+
found =
|
|
284
|
+
(request.name && peripheral.advertisement && request.name === peripheral.advertisement.localName) ||
|
|
285
|
+
(request.address && request.address === peripheral.address);
|
|
286
|
+
if (!found) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
this.logEvent({ message: 'search device: found device', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), scanForDevice, callback: callback !== undefined });
|
|
290
|
+
this.scanState.peripherals.set(peripheral.address, peripheral);
|
|
291
|
+
const characteristics = yield this.getCharacteristics(peripheral);
|
|
292
|
+
callback(peripheral, characteristics);
|
|
293
|
+
return;
|
|
521
294
|
}
|
|
522
295
|
else {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
296
|
+
this.logEvent({ message: 'BLE scan: found device', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), scanForDevice, callback: callback !== undefined });
|
|
297
|
+
this.scanState.peripherals.set(peripheral.address, peripheral);
|
|
298
|
+
const { protocolFilter } = props;
|
|
299
|
+
const connector = this.peripheralCache.getConnector(p);
|
|
300
|
+
const characteristics = yield this.getCharacteristics(p);
|
|
301
|
+
const announcedServices = connector.getServices();
|
|
302
|
+
const services = announcedServices ? announcedServices.map(utils_1.uuid) : undefined;
|
|
303
|
+
peripheral = connector.getPeripheral();
|
|
304
|
+
const DeviceClasses = this.getAdapterFactory().getDeviceClasses(peripheral, { services }) || [];
|
|
305
|
+
const MatchingClasses = protocolFilter && DeviceClasses ? DeviceClasses.filter(C => protocolFilter.includes(C.protocol)) : DeviceClasses;
|
|
306
|
+
const DeviceClass = (0, comms_utils_1.getBestDeviceMatch)(MatchingClasses.filter(C => C.isMatching(characteristics.map(c => c.uuid))));
|
|
307
|
+
this.logEvent({ message: 'BLE scan: device connected', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), services, protocols: DeviceClasses.map(c => c.protocol) });
|
|
308
|
+
if (!DeviceClass)
|
|
309
|
+
return callback(null);
|
|
310
|
+
const { id, name, address } = (0, utils_1.getPeripheralInfo)(peripheral);
|
|
311
|
+
const settings = { protocol: DeviceClass.protocol, interface: 'ble', id, name: peripheral.name || name, address: peripheral.address || address };
|
|
312
|
+
callback(settings, characteristics);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
scanForDevice(comms, props) {
|
|
317
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
318
|
+
const { timeout = DEFAULT_SCAN_TIMEOUT } = props;
|
|
319
|
+
const request = comms.getSettings();
|
|
320
|
+
const { protocol } = request;
|
|
321
|
+
const ble = this.getBinding();
|
|
322
|
+
if (!this.isConnected()) {
|
|
323
|
+
yield this.connect();
|
|
526
324
|
}
|
|
325
|
+
const device = adapter_factory_1.default.getInstance().createInstance(request);
|
|
326
|
+
if (device.isConnected())
|
|
327
|
+
return device.getComms().peripheral;
|
|
328
|
+
let opStr;
|
|
329
|
+
opStr = 'search device';
|
|
330
|
+
this.logEvent({ message: 'search device request', request });
|
|
527
331
|
if (this.scanState.isScanning) {
|
|
528
332
|
try {
|
|
529
333
|
this.logEvent({ message: `${opStr}: waiting for previous scan to finish` });
|
|
530
334
|
yield this.waitForScanFinished(timeout);
|
|
531
335
|
}
|
|
532
336
|
catch (err) {
|
|
533
|
-
this.logEvent({ message: `${opStr} result: already scanning
|
|
534
|
-
|
|
337
|
+
this.logEvent({ message: `${opStr} result: already scanning`, error: err.message });
|
|
338
|
+
throw (err);
|
|
535
339
|
}
|
|
536
340
|
}
|
|
537
341
|
return new Promise((resolve, reject) => {
|
|
538
342
|
this.scanState.isScanning = true;
|
|
539
|
-
|
|
540
|
-
if (this.devices && this.devices.length > 0) {
|
|
541
|
-
const knownDevices = this.devices.map(i => ({ name: i.device.name, address: i.device.address, isConnected: i.isConnected, connectState: i.device.getConnectState() }));
|
|
542
|
-
this.logEvent({ message: `${opStr}: check if already registered`, device: { name, address }, knownDevices });
|
|
543
|
-
const existing = this.devices.find(i => (i.device.address === address || i.device.name === name || i.device.id === id));
|
|
544
|
-
if (existing)
|
|
545
|
-
this.logEvent({ message: `${opStr}: device already registered`, device: { name, address } });
|
|
546
|
-
}
|
|
547
|
-
}
|
|
343
|
+
this.scanState.peripherals = new Map();
|
|
548
344
|
const onTimeout = () => {
|
|
549
345
|
if (!this.scanState.isScanning || !this.scanState.timeout)
|
|
550
346
|
return;
|
|
551
347
|
this.scanState.timeout = null;
|
|
552
|
-
this.logEvent({ message: `${opStr} result:
|
|
553
|
-
|
|
554
|
-
this.logEvent({ message: `${opStr}: stop scanning`,
|
|
555
|
-
|
|
348
|
+
this.logEvent({ message: `${opStr} result: timeout`, request });
|
|
349
|
+
ble.removeAllListeners('discover');
|
|
350
|
+
this.logEvent({ message: `${opStr}: stop scanning`, request });
|
|
351
|
+
ble.stopScanning(() => {
|
|
556
352
|
this.scanState.isScanning = false;
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
resolve(this.devices.map(i => i.device));
|
|
353
|
+
reject(new Error('device not found'));
|
|
354
|
+
return;
|
|
562
355
|
});
|
|
563
356
|
};
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
this.
|
|
573
|
-
|
|
574
|
-
if (peripheral.address === undefined || peripheral.address === '')
|
|
575
|
-
peripheral.address = peripheral.id;
|
|
576
|
-
const isPeripheralProcessed = peripheralsProcessed.find(p => p === peripheral.address) !== undefined;
|
|
577
|
-
if (isPeripheralProcessed)
|
|
578
|
-
return;
|
|
579
|
-
peripheralsProcessed.push(peripheral.address);
|
|
580
|
-
if (scanForDevice && requested.name && requested.name !== peripheral.advertisement.localName)
|
|
581
|
-
return;
|
|
582
|
-
const connector = this.getConnector(peripheral);
|
|
583
|
-
const characteristics = yield this.getCharacteristics(peripheral);
|
|
584
|
-
const connectedServices = connector.getServices();
|
|
585
|
-
const services = connectedServices ? connectedServices.map(cs => cs.uuid) : undefined;
|
|
586
|
-
const connectedPeripheral = connector.getPeripheral();
|
|
587
|
-
const { id, name, address, advertisement = {} } = connectedPeripheral;
|
|
588
|
-
const DeviceClasses = this.getDeviceClasses(connectedPeripheral, { profile, services }) || [];
|
|
589
|
-
this.logEvent({ message: 'BLE scan: device connected', peripheral: { id, name, address, services: advertisement.serviceUuids }, services, classes: DeviceClasses.map(c => c.prototype.constructor.name) });
|
|
590
|
-
let cntFound = 0;
|
|
591
|
-
const DeviceClass = this.getBestDeviceMatch(DeviceClasses);
|
|
592
|
-
if (!DeviceClass)
|
|
593
|
-
return;
|
|
594
|
-
if (scanForDevice && cntFound > 0)
|
|
595
|
-
return;
|
|
596
|
-
const d = this.createDevice(DeviceClass, peripheral, characteristics);
|
|
597
|
-
if (!d) {
|
|
598
|
-
this.logEvent({ message: `${opStr}: could not create device `, DeviceClass });
|
|
599
|
-
return;
|
|
600
|
-
}
|
|
601
|
-
try {
|
|
602
|
-
this.logEvent({ message: `${opStr}: connecting `, device: d.name, profile: d.getProfile(), address: d.address });
|
|
603
|
-
yield d.connect();
|
|
604
|
-
}
|
|
605
|
-
catch (err) {
|
|
606
|
-
this.logEvent({ message: 'error', fn: 'onPeripheralFound()', error: err.message || err, stack: err.stack });
|
|
607
|
-
}
|
|
608
|
-
if (scanForDevice) {
|
|
609
|
-
if ((id && id !== '' && d.id === id) ||
|
|
610
|
-
(address && address !== '' && d.address === address) ||
|
|
611
|
-
(name && name !== '' && d.name === name))
|
|
612
|
-
cntFound++;
|
|
613
|
-
}
|
|
614
|
-
else
|
|
615
|
-
cntFound++;
|
|
616
|
-
const existing = devicesProcessed.find(device => device.id === d.id && device.getProfile() === d.getProfile());
|
|
617
|
-
if (!scanForDevice && cntFound > 0 && !existing) {
|
|
618
|
-
this.logEvent({ message: `${opStr}: device found`, device: d.name, profile: d.getProfile(), address: d.address, services: d.services.join(',') });
|
|
619
|
-
this.addDeviceToCache(d, peripheral.state === 'connected');
|
|
620
|
-
devicesProcessed.push(d);
|
|
621
|
-
this.emit('device', d);
|
|
622
|
-
return;
|
|
357
|
+
this.logEvent({ message: `${opStr}: start scanning`, request, timeout });
|
|
358
|
+
let services = [];
|
|
359
|
+
if (protocol !== 'tacx') {
|
|
360
|
+
services = (device.getComms().getServices()) || [];
|
|
361
|
+
}
|
|
362
|
+
ble.startScanning(services, false, (err) => {
|
|
363
|
+
if (err) {
|
|
364
|
+
this.logEvent({ message: `${opStr} result: error`, request, error: err.message });
|
|
365
|
+
this.scanState.isScanning = false;
|
|
366
|
+
return reject(err);
|
|
623
367
|
}
|
|
624
|
-
|
|
625
|
-
this.
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
this.
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
resolve([d]);
|
|
368
|
+
ble.on('discover', (p) => {
|
|
369
|
+
this.onPeripheralFound(p, (peripheral, characteristics) => {
|
|
370
|
+
device.getComms().characteristics = characteristics;
|
|
371
|
+
process.nextTick(() => {
|
|
372
|
+
if (this.scanState.timeout) {
|
|
373
|
+
clearTimeout(this.scanState.timeout);
|
|
374
|
+
this.scanState.timeout = null;
|
|
375
|
+
}
|
|
376
|
+
this.logEvent({ message: `${opStr}: stop scanning`, request });
|
|
377
|
+
ble.stopScanning(() => {
|
|
378
|
+
ble.removeAllListeners('discover');
|
|
379
|
+
this.scanState.isScanning = false;
|
|
380
|
+
resolve(peripheral);
|
|
381
|
+
});
|
|
639
382
|
});
|
|
640
|
-
});
|
|
383
|
+
}, { comms });
|
|
384
|
+
});
|
|
385
|
+
const cachedItem = this.peripheralCache.find(request);
|
|
386
|
+
if (cachedItem) {
|
|
387
|
+
this.logEvent({ message: `${opStr}: adding peripheral from cache `, peripheral: (0, utils_1.getPeripheralInfo)(cachedItem.peripheral) });
|
|
388
|
+
ble.emit('discover', cachedItem.peripheral);
|
|
641
389
|
}
|
|
642
390
|
});
|
|
643
|
-
this.
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
391
|
+
this.scanState.timeout = setTimeout(onTimeout, timeout);
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
scan(props = {}) {
|
|
396
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
397
|
+
const { timeout = DEFAULT_SCAN_TIMEOUT, protocol, protocols } = props;
|
|
398
|
+
const requestedProtocols = protocols || [];
|
|
399
|
+
if (protocol && !requestedProtocols.find(p => p === protocol))
|
|
400
|
+
requestedProtocols.push(protocol);
|
|
401
|
+
const protocolFilter = requestedProtocols.length > 0 ? requestedProtocols : null;
|
|
402
|
+
const services = protocolFilter === null ? this.getAdapterFactory().getAllSupportedServices() : (0, comms_utils_1.getServicesFromProtocols)(protocolFilter);
|
|
403
|
+
const ble = this.getBinding();
|
|
404
|
+
const opStr = 'scan';
|
|
405
|
+
if (this.scanState.isScanning) {
|
|
406
|
+
try {
|
|
407
|
+
this.logEvent({ message: `${opStr}: waiting for previous scan to finish` });
|
|
408
|
+
yield this.waitForScanFinished(timeout);
|
|
409
|
+
}
|
|
410
|
+
catch (err) {
|
|
411
|
+
this.logEvent({ message: `${opStr} result: already scanning` });
|
|
412
|
+
throw (err);
|
|
650
413
|
}
|
|
651
|
-
|
|
414
|
+
}
|
|
415
|
+
this.scanState.isScanning = true;
|
|
416
|
+
const tsStart = Date.now();
|
|
417
|
+
const tsTimeoutExpired = tsStart + timeout;
|
|
418
|
+
while (!this.isConnected() && this.scanState.isScanning && Date.now() < tsTimeoutExpired) {
|
|
419
|
+
const connected = yield this.connect();
|
|
420
|
+
if (!connected)
|
|
421
|
+
yield (0, utils_2.sleep)(1000);
|
|
422
|
+
}
|
|
423
|
+
if (Date.now() > tsTimeoutExpired) {
|
|
424
|
+
return [];
|
|
425
|
+
}
|
|
426
|
+
if (!this.scanState.isScanning) {
|
|
427
|
+
return [];
|
|
428
|
+
}
|
|
429
|
+
const adjustedScanTimeout = tsStart - Date.now() + timeout;
|
|
430
|
+
const supported = adapter_factory_1.default.getInstance().getAll().map(i => i.protocol);
|
|
431
|
+
this.logEvent({ message: 'scan start', services, supported });
|
|
432
|
+
return new Promise((resolve, reject) => {
|
|
433
|
+
this.scanState.peripherals = new Map();
|
|
434
|
+
const detected = [];
|
|
435
|
+
const requested = protocolFilter;
|
|
436
|
+
const onTimeout = () => {
|
|
437
|
+
if (!this.scanState.isScanning || !this.scanState.timeout)
|
|
438
|
+
return;
|
|
439
|
+
this.scanState.timeout = null;
|
|
440
|
+
const devices = detected.map(d => {
|
|
441
|
+
const { id, name, address, protocol } = d;
|
|
442
|
+
return { id, name, address, protocol };
|
|
443
|
+
});
|
|
444
|
+
this.logEvent({ message: `${opStr} result: timeout, devices found`, requested, devices });
|
|
445
|
+
ble.removeAllListeners('discover');
|
|
446
|
+
this.logEvent({ message: `${opStr}: stop scanning`, requested });
|
|
447
|
+
ble.stopScanning(() => {
|
|
448
|
+
this.scanState.isScanning = false;
|
|
449
|
+
resolve(detected);
|
|
450
|
+
});
|
|
451
|
+
};
|
|
452
|
+
this.logEvent({ message: `${opStr}: start scanning`, requested, timeout });
|
|
453
|
+
this.scanState.timeout = setTimeout(onTimeout, adjustedScanTimeout);
|
|
454
|
+
ble.startScanning(protocolFilter ? services : [], false, (err) => {
|
|
652
455
|
if (err) {
|
|
653
|
-
this.logEvent({ message: `${opStr} result: error`, requested
|
|
456
|
+
this.logEvent({ message: `${opStr} result: error`, requested, error: err.message });
|
|
654
457
|
this.scanState.isScanning = false;
|
|
655
458
|
return reject(err);
|
|
656
459
|
}
|
|
657
|
-
|
|
658
|
-
onPeripheralFound(p)
|
|
460
|
+
ble.on('discover', (p) => {
|
|
461
|
+
this.onPeripheralFound(p, (deviceSettings, characteristics) => {
|
|
462
|
+
if (deviceSettings) {
|
|
463
|
+
detected.push(deviceSettings);
|
|
464
|
+
const device = this.getAdapterFactory().createInstance(deviceSettings);
|
|
465
|
+
device.getComms().characteristics = characteristics;
|
|
466
|
+
this.emit('device', deviceSettings);
|
|
467
|
+
}
|
|
468
|
+
}, { protocolFilter });
|
|
659
469
|
});
|
|
470
|
+
const cachedItems = this.peripheralCache.filter(protocolFilter ? services : []);
|
|
471
|
+
if (cachedItems && cachedItems.length > 0) {
|
|
472
|
+
cachedItems.map(c => c.peripheral).forEach(peripheral => {
|
|
473
|
+
this.logEvent({ message: `${opStr}: adding peripheral from cache `, peripheral: (0, utils_1.getPeripheralInfo)(peripheral) });
|
|
474
|
+
ble.emit('discover', peripheral);
|
|
475
|
+
});
|
|
476
|
+
}
|
|
660
477
|
});
|
|
661
|
-
this.scanState.timeout = setTimeout(onTimeout, timeout);
|
|
662
478
|
});
|
|
663
479
|
});
|
|
664
480
|
}
|
|
@@ -669,13 +485,12 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
669
485
|
this.logEvent({ message: 'scan stop result: not scanning' });
|
|
670
486
|
return true;
|
|
671
487
|
}
|
|
672
|
-
|
|
488
|
+
const ble = this.getBinding();
|
|
489
|
+
if (!ble)
|
|
673
490
|
throw new Error('no binding defined');
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
ongoing.forEach(i => { i.isInterrupted = true; });
|
|
678
|
-
yield this.getBinding().stopScanning();
|
|
491
|
+
ble.removeAllListeners('discover');
|
|
492
|
+
this.peripheralCache.handleStopScan();
|
|
493
|
+
ble.stopScanning();
|
|
679
494
|
this.scanState.isScanning = false;
|
|
680
495
|
this.logEvent({ message: 'scan stop result: success' });
|
|
681
496
|
return true;
|
|
@@ -685,37 +500,14 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
685
500
|
return this.scanState.isScanning === true;
|
|
686
501
|
}
|
|
687
502
|
addConnectedDevice(device) {
|
|
688
|
-
const
|
|
689
|
-
if (
|
|
690
|
-
|
|
691
|
-
return;
|
|
692
|
-
}
|
|
693
|
-
this.devices.push({ device, isConnected: true });
|
|
694
|
-
}
|
|
695
|
-
addDeviceToCache(device, isConnected) {
|
|
696
|
-
const existigDevice = this.devices.find(i => i.device.id === device.id && i.device.getProfile() === device.getProfile());
|
|
697
|
-
if (existigDevice) {
|
|
698
|
-
return;
|
|
699
|
-
}
|
|
700
|
-
this.devices.push({ device, isConnected });
|
|
701
|
-
}
|
|
702
|
-
findConnected(device) {
|
|
703
|
-
const connected = this.devices.find(i => i.device.id === device.id && i.isConnected);
|
|
704
|
-
if (connected)
|
|
705
|
-
return connected.device;
|
|
706
|
-
return undefined;
|
|
707
|
-
}
|
|
708
|
-
findDeviceInCache(device) {
|
|
709
|
-
const existing = this.devices.find(i => (i.device.id === device.id || i.device.address === device.address || i.device.name === device.name) && i.device.getProfile() === device.profile);
|
|
710
|
-
return existing ? existing.device : undefined;
|
|
503
|
+
const idx = this.connectedDevices.findIndex(d => d.isSame(device));
|
|
504
|
+
if (idx === -1)
|
|
505
|
+
this.connectedDevices.push(device);
|
|
711
506
|
}
|
|
712
507
|
removeConnectedDevice(device) {
|
|
713
|
-
const
|
|
714
|
-
if (
|
|
715
|
-
|
|
716
|
-
return;
|
|
717
|
-
}
|
|
508
|
+
const idx = this.connectedDevices.findIndex(d => d.isSame(device));
|
|
509
|
+
if (idx !== -1)
|
|
510
|
+
this.connectedDevices.splice(idx);
|
|
718
511
|
}
|
|
719
512
|
}
|
|
720
513
|
exports.default = BleInterface;
|
|
721
|
-
BleInterface.deviceClasses = [];
|