incyclist-devices 2.0.6 → 2.0.7
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/lib/base/adpater.js +3 -2
- package/lib/ble/base/comms.js +14 -10
- package/lib/ble/ble-interface.d.ts +1 -0
- package/lib/ble/ble-interface.js +33 -9
- package/lib/ble/ble-peripheral.d.ts +2 -1
- package/lib/ble/ble-peripheral.js +48 -28
- package/lib/ble/fm/adapter.js +2 -2
- package/lib/ble/peripheral-cache.js +3 -1
- package/lib/ble/types.d.ts +1 -1
- package/lib/serial/daum/premium/adapter.d.ts +1 -0
- package/lib/serial/daum/premium/adapter.js +17 -8
- package/lib/serial/daum/premium/comms.js +13 -7
- package/lib/serial/daum/premium/mock.js +0 -3
- package/lib/serial/kettler/ergo-racer/mock.js +1 -1
- package/lib/serial/serial-interface.d.ts +2 -0
- package/lib/serial/serial-interface.js +36 -15
- package/package.json +1 -1
package/lib/base/adpater.js
CHANGED
|
@@ -65,8 +65,9 @@ class IncyclistDevice extends events_1.default {
|
|
|
65
65
|
if (!this.logger || this.paused)
|
|
66
66
|
return;
|
|
67
67
|
this.logger.logEvent(event);
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
const w = global.window;
|
|
69
|
+
if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG || process.env.ANT_DEBUG) {
|
|
70
|
+
const logText = '~~~ ' + this.getInterface().toUpperCase();
|
|
70
71
|
console.log(logText, event);
|
|
71
72
|
}
|
|
72
73
|
}
|
package/lib/ble/base/comms.js
CHANGED
|
@@ -88,8 +88,9 @@ class BleComms extends events_1.default {
|
|
|
88
88
|
if (this.logger) {
|
|
89
89
|
this.logger.logEvent(event);
|
|
90
90
|
}
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
const w = global.window;
|
|
92
|
+
if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG) {
|
|
93
|
+
console.log('~~~ BLE', event);
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
setLogger(logger) {
|
|
@@ -203,12 +204,12 @@ class BleComms extends events_1.default {
|
|
|
203
204
|
yield connector.connect();
|
|
204
205
|
if (disconnectSignalled)
|
|
205
206
|
return;
|
|
206
|
-
yield connector.initialize();
|
|
207
|
-
if (disconnectSignalled)
|
|
208
|
-
return;
|
|
207
|
+
const initialized = yield connector.initialize();
|
|
208
|
+
if (!initialized || disconnectSignalled)
|
|
209
|
+
return done(false);
|
|
209
210
|
yield this.subscribeAll(connector);
|
|
210
211
|
if (disconnectSignalled)
|
|
211
|
-
return;
|
|
212
|
+
return done(false);
|
|
212
213
|
this.connectState.isConnected = true;
|
|
213
214
|
this.state = "connected";
|
|
214
215
|
this.emit('connected');
|
|
@@ -229,6 +230,7 @@ class BleComms extends events_1.default {
|
|
|
229
230
|
});
|
|
230
231
|
}
|
|
231
232
|
subscribeMultiple(characteristics, conn) {
|
|
233
|
+
this.logEvent({ message: 'subscribe', characteristics });
|
|
232
234
|
return new Promise(resolve => {
|
|
233
235
|
try {
|
|
234
236
|
const connector = conn || this.ble.peripheralCache.getConnector(this.peripheral);
|
|
@@ -317,6 +319,9 @@ class BleComms extends events_1.default {
|
|
|
317
319
|
const { id, name, address } = this;
|
|
318
320
|
try {
|
|
319
321
|
this.peripheral = this.ble.peripheralCache.getPeripheral({ id, name, address });
|
|
322
|
+
const connector = this.ble.peripheralCache.getConnector(this.peripheral);
|
|
323
|
+
if (!connector) {
|
|
324
|
+
}
|
|
320
325
|
}
|
|
321
326
|
catch (err) {
|
|
322
327
|
this.logEvent({ message: 'error', fn: 'connect()', error: err.message, stack: err.stack });
|
|
@@ -342,7 +347,7 @@ class BleComms extends events_1.default {
|
|
|
342
347
|
if (this.ble.isScanning()) {
|
|
343
348
|
yield this.ble.stopScan();
|
|
344
349
|
}
|
|
345
|
-
const peripheral = yield this.ble.scanForDevice(this, {})
|
|
350
|
+
const peripheral = yield this.ble.scanForDevice(this, {});
|
|
346
351
|
if (peripheral) {
|
|
347
352
|
this.peripheral = peripheral;
|
|
348
353
|
const connected = yield this.connectPeripheral(this.peripheral);
|
|
@@ -354,11 +359,10 @@ class BleComms extends events_1.default {
|
|
|
354
359
|
}
|
|
355
360
|
}
|
|
356
361
|
catch (err) {
|
|
357
|
-
console.log('~~~ ERROR', err);
|
|
358
362
|
error = err;
|
|
359
363
|
}
|
|
360
364
|
}
|
|
361
|
-
this.logEvent({ message: 'connect result: failure', mode: 'device', device: { id, name, address }, error: error.message
|
|
365
|
+
this.logEvent({ message: 'connect result: failure', mode: 'device', device: { id, name, address }, error: error.message });
|
|
362
366
|
this.connectState.isConnecting = false;
|
|
363
367
|
this.connectState.isConnected = false;
|
|
364
368
|
this.ble.stopConnectSensor();
|
|
@@ -368,7 +372,7 @@ class BleComms extends events_1.default {
|
|
|
368
372
|
catch (err) {
|
|
369
373
|
this.connectState.isConnecting = false;
|
|
370
374
|
this.connectState.isConnected = false;
|
|
371
|
-
this.logEvent({ message: 'connect result: error', error: err.message });
|
|
375
|
+
this.logEvent({ message: 'connect result: error', error: err.message, stack: err.stack });
|
|
372
376
|
this.ble.stopConnectSensor();
|
|
373
377
|
return false;
|
|
374
378
|
}
|
package/lib/ble/ble-interface.js
CHANGED
|
@@ -80,13 +80,16 @@ class BleInterface extends events_1.default {
|
|
|
80
80
|
if (this.logger) {
|
|
81
81
|
this.logger.logEvent(event);
|
|
82
82
|
}
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
const w = global.window;
|
|
84
|
+
if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG) {
|
|
85
|
+
console.log('~~~ BLE', event);
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
onStateChange(state) {
|
|
88
89
|
if (state !== 'poweredOn') {
|
|
90
|
+
this.logEvent({ message: 'Ble disconnected', });
|
|
89
91
|
this.connectState.isConnected = false;
|
|
92
|
+
this.stopConnectSensor();
|
|
90
93
|
}
|
|
91
94
|
else {
|
|
92
95
|
this.connectState.isConnected = true;
|
|
@@ -225,7 +228,9 @@ class BleInterface extends events_1.default {
|
|
|
225
228
|
chachedPeripheralInfo.state = { isConfigured: false, isLoading: true, isInterrupted: false };
|
|
226
229
|
yield connector.connect();
|
|
227
230
|
peripheral.state = connector.getState();
|
|
228
|
-
yield connector.initialize();
|
|
231
|
+
const initialized = yield connector.initialize();
|
|
232
|
+
if (!initialized)
|
|
233
|
+
return null;
|
|
229
234
|
characteristics = connector.getCharachteristics();
|
|
230
235
|
this.logEvent({ message: 'characteristic info (+):', address: peripheral.address, info: characteristics.map(utils_1.getCharachteristicsInfo) });
|
|
231
236
|
chachedPeripheralInfo.characteristics = characteristics;
|
|
@@ -261,6 +266,7 @@ class BleInterface extends events_1.default {
|
|
|
261
266
|
});
|
|
262
267
|
}
|
|
263
268
|
onPeripheralFound(p, callback, props = {}) {
|
|
269
|
+
var _a;
|
|
264
270
|
return __awaiter(this, void 0, void 0, function* () {
|
|
265
271
|
let peripheral = p;
|
|
266
272
|
if (!peripheral || !peripheral.advertisement || !peripheral.advertisement.localName) {
|
|
@@ -279,18 +285,30 @@ class BleInterface extends events_1.default {
|
|
|
279
285
|
if (isPeripheralProcessed) {
|
|
280
286
|
return;
|
|
281
287
|
}
|
|
288
|
+
if (scanForDevice) {
|
|
289
|
+
const alreadyDetected = ((_a = this.scanState.detected) === null || _a === void 0 ? void 0 : _a.find(p => p === peripheral.address)) !== undefined;
|
|
290
|
+
if (alreadyDetected)
|
|
291
|
+
return;
|
|
292
|
+
this.scanState.detected.push(peripheral.address);
|
|
293
|
+
}
|
|
282
294
|
if (scanForDevice) {
|
|
283
295
|
let found = false;
|
|
284
296
|
found =
|
|
285
|
-
(request.name && peripheral.advertisement && request.name === peripheral.advertisement.localName) ||
|
|
286
|
-
(request.address && request.address === peripheral.address);
|
|
297
|
+
(request.name !== undefined && peripheral.advertisement && request.name === peripheral.advertisement.localName) ||
|
|
298
|
+
(request.address !== undefined && request.address === peripheral.address);
|
|
299
|
+
this.logEvent({ message: 'search device: found device', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), scanForDevice, matching: found });
|
|
287
300
|
if (!found) {
|
|
288
301
|
return;
|
|
289
302
|
}
|
|
290
|
-
this.logEvent({ message: 'search device: found device', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), scanForDevice, callback: callback !== undefined });
|
|
291
303
|
this.scanState.peripherals.set(peripheral.address, peripheral);
|
|
292
304
|
const characteristics = yield this.getCharacteristics(peripheral);
|
|
293
|
-
|
|
305
|
+
if (characteristics) {
|
|
306
|
+
callback(peripheral, characteristics);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
callback(null);
|
|
310
|
+
}
|
|
311
|
+
this.stopScan();
|
|
294
312
|
return;
|
|
295
313
|
}
|
|
296
314
|
else {
|
|
@@ -299,13 +317,16 @@ class BleInterface extends events_1.default {
|
|
|
299
317
|
const { protocolFilter } = props;
|
|
300
318
|
const connector = this.peripheralCache.getConnector(p);
|
|
301
319
|
const characteristics = yield this.getCharacteristics(p);
|
|
320
|
+
if (!characteristics) {
|
|
321
|
+
return callback(null);
|
|
322
|
+
}
|
|
302
323
|
const announcedServices = connector.getServices();
|
|
303
324
|
const services = announcedServices ? announcedServices.map(utils_1.uuid) : undefined;
|
|
304
325
|
peripheral = connector.getPeripheral();
|
|
305
326
|
const DeviceClasses = this.getAdapterFactory().getDeviceClasses(peripheral, { services }) || [];
|
|
306
327
|
const MatchingClasses = protocolFilter && DeviceClasses ? DeviceClasses.filter(C => protocolFilter.includes(C.protocol)) : DeviceClasses;
|
|
307
328
|
const DeviceClass = (0, comms_utils_1.getBestDeviceMatch)(MatchingClasses.filter(C => C.isMatching(characteristics.map(c => c.uuid))));
|
|
308
|
-
this.logEvent({ message: 'BLE scan: device connected', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), services, protocols: DeviceClasses.map(c => c.protocol) });
|
|
329
|
+
this.logEvent({ message: 'BLE scan: device connected', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), services, protocols: DeviceClasses.map(c => c.protocol), found: DeviceClass !== undefined });
|
|
309
330
|
if (!DeviceClass)
|
|
310
331
|
return callback(null);
|
|
311
332
|
const { id, name, address } = (0, utils_1.getPeripheralInfo)(peripheral);
|
|
@@ -342,6 +363,7 @@ class BleInterface extends events_1.default {
|
|
|
342
363
|
return new Promise((resolve, reject) => {
|
|
343
364
|
this.scanState.isScanning = true;
|
|
344
365
|
this.scanState.peripherals = new Map();
|
|
366
|
+
this.scanState.detected = [];
|
|
345
367
|
const onTimeout = () => {
|
|
346
368
|
if (!this.scanState.isScanning || !this.scanState.timeout)
|
|
347
369
|
return;
|
|
@@ -360,7 +382,7 @@ class BleInterface extends events_1.default {
|
|
|
360
382
|
if (protocol !== 'tacx') {
|
|
361
383
|
services = (device.getComms().getServices()) || [];
|
|
362
384
|
}
|
|
363
|
-
ble.startScanning(services,
|
|
385
|
+
ble.startScanning(services, true, (err) => {
|
|
364
386
|
if (err) {
|
|
365
387
|
this.logEvent({ message: `${opStr} result: error`, request, error: err.message });
|
|
366
388
|
this.scanState.isScanning = false;
|
|
@@ -368,6 +390,8 @@ class BleInterface extends events_1.default {
|
|
|
368
390
|
}
|
|
369
391
|
ble.on('discover', (p) => {
|
|
370
392
|
this.onPeripheralFound(p, (peripheral, characteristics) => {
|
|
393
|
+
if (!peripheral)
|
|
394
|
+
return reject(new Error('could not connect'));
|
|
371
395
|
device.getComms().characteristics = characteristics;
|
|
372
396
|
process.nextTick(() => {
|
|
373
397
|
if (this.scanState.timeout) {
|
|
@@ -6,6 +6,7 @@ export type ConnectorState = {
|
|
|
6
6
|
isInitializing: boolean;
|
|
7
7
|
isSubscribing: boolean;
|
|
8
8
|
subscribed?: string[];
|
|
9
|
+
connectPromise?: Promise<void>;
|
|
9
10
|
};
|
|
10
11
|
export default class BlePeripheralConnector implements IBlePeripheralConnector {
|
|
11
12
|
private state;
|
|
@@ -20,7 +21,7 @@ export default class BlePeripheralConnector implements IBlePeripheralConnector {
|
|
|
20
21
|
connect(): Promise<void>;
|
|
21
22
|
reconnect(): Promise<void>;
|
|
22
23
|
onDisconnect(): void;
|
|
23
|
-
initialize(enforce?: boolean): Promise<
|
|
24
|
+
initialize(enforce?: boolean): Promise<boolean>;
|
|
24
25
|
isSubscribed(characteristicUuid: string): boolean;
|
|
25
26
|
subscribeAll(callback: (characteristicUuid: string, data: any) => void): Promise<string[]>;
|
|
26
27
|
subscribe(characteristicUuid: string, timeout?: number): Promise<boolean>;
|
|
@@ -32,8 +32,9 @@ class BlePeripheralConnector {
|
|
|
32
32
|
if (this.logger) {
|
|
33
33
|
this.logger.logEvent(event);
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
const w = global.window;
|
|
36
|
+
if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG) {
|
|
37
|
+
console.log('~~~ BLE', event);
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
connect() {
|
|
@@ -41,18 +42,25 @@ class BlePeripheralConnector {
|
|
|
41
42
|
if (this.state.isConnected)
|
|
42
43
|
return;
|
|
43
44
|
this.logEvent({ message: 'connect peripheral', peripheral: this.peripheral.address, state: this.state, peripheralState: this.peripheral.state });
|
|
45
|
+
const wasConnecting = this.state.isConnecting;
|
|
44
46
|
this.state.isConnecting = true;
|
|
45
47
|
try {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
if (!wasConnecting) {
|
|
49
|
+
this.peripheral.once('disconnect', () => { this.onDisconnect(); });
|
|
50
|
+
if (!this.state.isConnected || (this.peripheral && this.peripheral.state !== 'connected')) {
|
|
51
|
+
this.state.connectPromise = this.peripheral.connectAsync();
|
|
52
|
+
}
|
|
49
53
|
}
|
|
54
|
+
if (this.state.connectPromise)
|
|
55
|
+
yield this.state.connectPromise;
|
|
50
56
|
this.state.isConnected = this.peripheral.state === 'connected';
|
|
57
|
+
this.state.connectPromise = undefined;
|
|
51
58
|
return;
|
|
52
59
|
}
|
|
53
60
|
catch (err) {
|
|
54
61
|
this.logEvent({ message: 'Error', fn: 'connect()', error: err.message });
|
|
55
62
|
}
|
|
63
|
+
this.state.connectPromise = undefined;
|
|
56
64
|
this.state.isConnecting = false;
|
|
57
65
|
});
|
|
58
66
|
}
|
|
@@ -69,43 +77,55 @@ class BlePeripheralConnector {
|
|
|
69
77
|
this.state.isConnecting = false;
|
|
70
78
|
this.state.isInitialized = false;
|
|
71
79
|
this.state.isInitializing = false;
|
|
80
|
+
this.state.connectPromise = undefined;
|
|
81
|
+
this.state.isSubscribing = false;
|
|
82
|
+
this.state.subscribed = [];
|
|
72
83
|
this.emitter.emit('disconnect');
|
|
73
84
|
}
|
|
74
85
|
initialize(enforce = false) {
|
|
75
86
|
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
-
if (this.state.isInitialized && !enforce)
|
|
77
|
-
return;
|
|
78
87
|
this.logEvent({ message: 'initialize', peripheral: this.peripheral.address, state: this.state, enforce });
|
|
88
|
+
if (this.state.isInitialized && !enforce)
|
|
89
|
+
return true;
|
|
79
90
|
if (this.state.isInitialized && enforce) {
|
|
80
91
|
this.state.isInitialized = false;
|
|
81
92
|
}
|
|
82
|
-
this
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
this.
|
|
91
|
-
this.state.
|
|
92
|
-
|
|
93
|
+
return new Promise((done) => __awaiter(this, void 0, void 0, function* () {
|
|
94
|
+
this.state.isInitializing = true;
|
|
95
|
+
this.characteristics = undefined;
|
|
96
|
+
this.services = undefined;
|
|
97
|
+
try {
|
|
98
|
+
this.emitter.once('disconnect', () => {
|
|
99
|
+
done(false);
|
|
100
|
+
});
|
|
101
|
+
const res = yield this.peripheral.discoverSomeServicesAndCharacteristicsAsync([], []);
|
|
102
|
+
if (this.state.isInitializing) {
|
|
103
|
+
this.characteristics = res.characteristics;
|
|
104
|
+
this.services = res.services.map(s => typeof (s) === 'string' ? s : s.uuid);
|
|
105
|
+
this.state.isInitializing = false;
|
|
106
|
+
this.state.isInitialized = this.characteristics !== undefined && this.services !== undefined;
|
|
107
|
+
this.logEvent({ message: 'initialize done', peripheral: this.peripheral.address, state: this.state });
|
|
108
|
+
return done(true);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
this.logEvent({ message: 'initialize interrupted', peripheral: this.peripheral.address });
|
|
112
|
+
}
|
|
93
113
|
}
|
|
94
|
-
|
|
95
|
-
this.logEvent({ message: '
|
|
114
|
+
catch (err) {
|
|
115
|
+
this.logEvent({ message: 'error', fn: 'initialize', error: err.message, stack: err.stack });
|
|
116
|
+
this.state.isInitializing = false;
|
|
117
|
+
this.state.isInitialized = false;
|
|
118
|
+
done(false);
|
|
96
119
|
}
|
|
97
|
-
}
|
|
98
|
-
catch (err) {
|
|
99
|
-
this.logEvent({ message: 'error', fn: 'initialize', error: err.message, stack: err.stack });
|
|
100
|
-
this.state.isInitializing = false;
|
|
101
|
-
this.state.isInitialized = false;
|
|
102
|
-
}
|
|
120
|
+
}));
|
|
103
121
|
});
|
|
104
122
|
}
|
|
105
123
|
isSubscribed(characteristicUuid) {
|
|
106
|
-
|
|
124
|
+
var _a;
|
|
125
|
+
return ((_a = this.state.subscribed) === null || _a === void 0 ? void 0 : _a.find(c => c === characteristicUuid || (0, utils_1.uuid)(c) === characteristicUuid || c === (0, utils_1.uuid)(characteristicUuid))) !== undefined;
|
|
107
126
|
}
|
|
108
127
|
subscribeAll(callback) {
|
|
128
|
+
var _a;
|
|
109
129
|
return __awaiter(this, void 0, void 0, function* () {
|
|
110
130
|
const cnt = this.characteristics.length;
|
|
111
131
|
this.state.isSubscribing = true;
|
|
@@ -124,7 +144,7 @@ class BlePeripheralConnector {
|
|
|
124
144
|
this.on((0, utils_1.uuid)(c.uuid), callback);
|
|
125
145
|
}
|
|
126
146
|
this.logEvent({ message: 'subscribe', peripheral: this.peripheral.address, characteristic: c.uuid, uuid: (0, utils_1.uuid)(c.uuid) });
|
|
127
|
-
if (this.state.subscribed.find(uuid => uuid === c.uuid) === undefined) {
|
|
147
|
+
if (((_a = this.state.subscribed) === null || _a === void 0 ? void 0 : _a.find(uuid => uuid === c.uuid)) === undefined) {
|
|
128
148
|
try {
|
|
129
149
|
yield this.subscribe(c.uuid, 3000);
|
|
130
150
|
subscribed.push(c.uuid);
|
package/lib/ble/fm/adapter.js
CHANGED
|
@@ -117,7 +117,7 @@ class BleFmAdapter extends adapter_1.BleControllableAdapter {
|
|
|
117
117
|
this.resume();
|
|
118
118
|
if (this.started && !wasPaused)
|
|
119
119
|
return true;
|
|
120
|
-
this.logEvent(Object.assign(Object.assign({ message: 'starting device' }, this.getSettings()), { protocol: this.getProtocolName(), props, isStarted: this.started }));
|
|
120
|
+
this.logEvent(Object.assign(Object.assign({ message: 'starting device' }, this.getSettings()), { protocol: this.getProtocolName(), props, isStarted: this.started, isConnected: this.getComms().isConnected() }));
|
|
121
121
|
const { restart = wasPaused } = props;
|
|
122
122
|
if (!restart && this.ble.isScanning() && !this.getComms().isConnected()) {
|
|
123
123
|
}
|
|
@@ -131,11 +131,11 @@ class BleFmAdapter extends adapter_1.BleControllableAdapter {
|
|
|
131
131
|
this.connectPromise = this.connect();
|
|
132
132
|
const res = yield Promise.race([
|
|
133
133
|
this.connectPromise.then((connected) => {
|
|
134
|
-
this.connectPromise = undefined;
|
|
135
134
|
return { connected, reason: connected ? null : 'could not connect' };
|
|
136
135
|
}),
|
|
137
136
|
(0, utils_1.sleep)(timeout).then(() => ({ connected: false, reason: 'timeout' }))
|
|
138
137
|
]);
|
|
138
|
+
this.connectPromise = undefined;
|
|
139
139
|
const connected = res.connected;
|
|
140
140
|
if (!connected) {
|
|
141
141
|
throw new Error(`could not start device, reason:${res.reason}`);
|
|
@@ -12,6 +12,8 @@ class BlePeripheralCache {
|
|
|
12
12
|
return this.find(adapter.getSettings());
|
|
13
13
|
}
|
|
14
14
|
getConnector(peripheral) {
|
|
15
|
+
if (!peripheral)
|
|
16
|
+
return;
|
|
15
17
|
const info = this.find({ address: peripheral.address });
|
|
16
18
|
if (!info) {
|
|
17
19
|
const item = this.add({ address: peripheral.address, ts: Date.now(), peripheral });
|
|
@@ -99,7 +101,7 @@ class BlePeripheralCache {
|
|
|
99
101
|
const { address } = peripheral;
|
|
100
102
|
cachedItemIdx = this._findIndex({ address });
|
|
101
103
|
}
|
|
102
|
-
if (cachedItemIdx
|
|
104
|
+
if (cachedItemIdx === -1)
|
|
103
105
|
return;
|
|
104
106
|
this.peripherals.splice(cachedItemIdx);
|
|
105
107
|
}
|
package/lib/ble/types.d.ts
CHANGED
|
@@ -66,7 +66,7 @@ export interface BlePeripheral extends EventEmitter, BlePeripheralIdentifier {
|
|
|
66
66
|
export interface IBlePeripheralConnector {
|
|
67
67
|
connect(): Promise<void>;
|
|
68
68
|
reconnect(): Promise<void>;
|
|
69
|
-
initialize(enforce: boolean): Promise<
|
|
69
|
+
initialize(enforce: boolean): Promise<boolean>;
|
|
70
70
|
isSubscribed(characteristicUuid: string): boolean;
|
|
71
71
|
subscribeAll(callback: (characteristicUuid: string, data: any) => void): Promise<string[]>;
|
|
72
72
|
subscribe(characteristicUuid: string, timeout?: number): Promise<boolean>;
|
|
@@ -8,6 +8,7 @@ export default class DaumPremiumAdapter extends DaumAdapter {
|
|
|
8
8
|
commProps: SerialCommProps;
|
|
9
9
|
_startRetryTimeout: number;
|
|
10
10
|
constructor(settings: SerialDeviceSettings, props?: DeviceProperties);
|
|
11
|
+
logEvent(event: any): void;
|
|
11
12
|
getName(): string;
|
|
12
13
|
getUniqueName(): string;
|
|
13
14
|
getPort(): any;
|
|
@@ -60,6 +60,15 @@ class DaumPremiumAdapter extends DaumAdapter_1.default {
|
|
|
60
60
|
this.distanceInternal = undefined;
|
|
61
61
|
this.initData();
|
|
62
62
|
}
|
|
63
|
+
logEvent(event) {
|
|
64
|
+
if (this.logger) {
|
|
65
|
+
this.logger.logEvent(event);
|
|
66
|
+
}
|
|
67
|
+
const w = global.window;
|
|
68
|
+
if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG) {
|
|
69
|
+
console.log('~~~ DaumPremium', event);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
63
72
|
getName() {
|
|
64
73
|
return 'Daum8i';
|
|
65
74
|
}
|
|
@@ -102,19 +111,19 @@ class DaumPremiumAdapter extends DaumAdapter_1.default {
|
|
|
102
111
|
return __awaiter(this, void 0, void 0, function* () {
|
|
103
112
|
var info = {};
|
|
104
113
|
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
105
|
-
this.
|
|
114
|
+
this.logEvent({ message: "checking device", port: this.getPort() });
|
|
106
115
|
try {
|
|
116
|
+
yield this.bike.close();
|
|
107
117
|
const connected = yield this.connect();
|
|
108
118
|
if (!connected)
|
|
109
119
|
resolve(false);
|
|
110
120
|
info.deviceType = yield this.bike.getDeviceType();
|
|
111
121
|
info.version = yield this.bike.getProtocolVersion();
|
|
112
|
-
|
|
113
|
-
this.logger.logEvent({ message: "checking device success", port: this.getPort(), info });
|
|
122
|
+
this.logEvent({ message: "checking device success", port: this.getPort(), info });
|
|
114
123
|
resolve(true);
|
|
115
124
|
}
|
|
116
125
|
catch (err) {
|
|
117
|
-
this.
|
|
126
|
+
this.logEvent({ message: "checking device failed", port: this.getPort(), reason: err.message || err });
|
|
118
127
|
resolve(false);
|
|
119
128
|
}
|
|
120
129
|
}));
|
|
@@ -142,26 +151,26 @@ class DaumPremiumAdapter extends DaumAdapter_1.default {
|
|
|
142
151
|
}
|
|
143
152
|
startRide(props = {}) {
|
|
144
153
|
return __awaiter(this, void 0, void 0, function* () {
|
|
145
|
-
this.
|
|
154
|
+
this.logEvent({ message: 'relaunch of device' });
|
|
146
155
|
try {
|
|
147
156
|
yield this.launch(props, true);
|
|
148
157
|
return true;
|
|
149
158
|
}
|
|
150
159
|
catch (err) {
|
|
151
|
-
this.
|
|
160
|
+
this.logEvent({ message: 'start result: error', error: err.message });
|
|
152
161
|
throw new Error(`could not start device, reason:${err.message}`);
|
|
153
162
|
}
|
|
154
163
|
});
|
|
155
164
|
}
|
|
156
165
|
start(props = {}) {
|
|
157
166
|
return __awaiter(this, void 0, void 0, function* () {
|
|
158
|
-
this.
|
|
167
|
+
this.logEvent({ message: 'initial start of device' });
|
|
159
168
|
try {
|
|
160
169
|
yield this.launch(props, false);
|
|
161
170
|
return true;
|
|
162
171
|
}
|
|
163
172
|
catch (err) {
|
|
164
|
-
this.
|
|
173
|
+
this.logEvent({ message: 'start result: error', error: err.message });
|
|
165
174
|
throw new Error(`could not start device, reason:${err.message}`);
|
|
166
175
|
}
|
|
167
176
|
});
|
|
@@ -41,7 +41,8 @@ class Daum8i {
|
|
|
41
41
|
const { logger, serial, path } = props;
|
|
42
42
|
this.serial = serial;
|
|
43
43
|
this.path = validatePath(path);
|
|
44
|
-
|
|
44
|
+
const w = global.window;
|
|
45
|
+
this.logger = logger || ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.DEBUG ? DEBUG_LOGGER : new gd_eventlog_1.EventLogger('DaumPremium'));
|
|
45
46
|
this.isLoggingPaused = false;
|
|
46
47
|
this.connected = false;
|
|
47
48
|
this.blocked = false;
|
|
@@ -75,6 +76,10 @@ class Daum8i {
|
|
|
75
76
|
logEvent(e) {
|
|
76
77
|
if (!this.isLoggingPaused)
|
|
77
78
|
this.logger.logEvent(e);
|
|
79
|
+
const w = global.window;
|
|
80
|
+
if (w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) {
|
|
81
|
+
console.log('~~~ DaumPremium', e);
|
|
82
|
+
}
|
|
78
83
|
}
|
|
79
84
|
connect() {
|
|
80
85
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -114,6 +119,7 @@ class Daum8i {
|
|
|
114
119
|
}
|
|
115
120
|
this.connected = false;
|
|
116
121
|
if (this.sp) {
|
|
122
|
+
console.log('~~~ removing all listeners');
|
|
117
123
|
this.sp.removeAllListeners();
|
|
118
124
|
this.sp = null;
|
|
119
125
|
}
|
|
@@ -149,6 +155,7 @@ class Daum8i {
|
|
|
149
155
|
return __awaiter(this, void 0, void 0, function* () {
|
|
150
156
|
this.connected = false;
|
|
151
157
|
if (this.sp) {
|
|
158
|
+
console.log('~~~ removing all listeners');
|
|
152
159
|
this.sp.removeAllListeners();
|
|
153
160
|
this.sp = null;
|
|
154
161
|
}
|
|
@@ -421,19 +428,18 @@ class Daum8i {
|
|
|
421
428
|
}
|
|
422
429
|
write(buffer) {
|
|
423
430
|
return __awaiter(this, void 0, void 0, function* () {
|
|
424
|
-
return new Promise(done => {
|
|
431
|
+
return new Promise((done) => __awaiter(this, void 0, void 0, function* () {
|
|
425
432
|
this.state.writeBusy = true;
|
|
426
433
|
try {
|
|
427
|
-
this.sp.write(buffer
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
});
|
|
434
|
+
yield this.sp.write(buffer);
|
|
435
|
+
this.state.writeBusy = false;
|
|
436
|
+
done();
|
|
431
437
|
}
|
|
432
438
|
catch (err) {
|
|
433
439
|
this.state.writeBusy = false;
|
|
434
440
|
done();
|
|
435
441
|
}
|
|
436
|
-
});
|
|
442
|
+
}));
|
|
437
443
|
});
|
|
438
444
|
}
|
|
439
445
|
sendACK() {
|
|
@@ -143,9 +143,6 @@ class Daum8iMockBinding extends binding_mock_1.MockPortBinding {
|
|
|
143
143
|
}
|
|
144
144
|
this.writeOperation = (() => __awaiter(this, void 0, void 0, function* () {
|
|
145
145
|
yield (0, utils_1.resolveNextTick)();
|
|
146
|
-
if (!this.isOpen || !this.port) {
|
|
147
|
-
throw new Error('Write canceled');
|
|
148
|
-
}
|
|
149
146
|
if (this.simulator._isSimulateACKTimeout) {
|
|
150
147
|
this.simulator._isSimulateACKTimeout = false;
|
|
151
148
|
}
|
|
@@ -31,6 +31,7 @@ export declare class SinglePathScanner {
|
|
|
31
31
|
props: SerialScannerProps;
|
|
32
32
|
logger: EventLogger;
|
|
33
33
|
constructor(path: string, serial: SerialInterface, props: SerialScannerProps);
|
|
34
|
+
logEvent(event: any): void;
|
|
34
35
|
onStopRequest(resolve: any): Promise<void>;
|
|
35
36
|
scan(): Promise<SerialDeviceSettings | undefined>;
|
|
36
37
|
}
|
|
@@ -48,6 +49,7 @@ export default class SerialInterface extends EventEmitter implements IncyclistIn
|
|
|
48
49
|
static getInstance(props: SerialInterfaceProps): SerialInterface;
|
|
49
50
|
static _add(instance: SerialInterface): void;
|
|
50
51
|
constructor(props: SerialInterfaceProps);
|
|
52
|
+
logEvent(event: any): void;
|
|
51
53
|
setBinding(binding: BindingInterface): void;
|
|
52
54
|
getName(): string;
|
|
53
55
|
isConnected(): boolean;
|
|
@@ -32,9 +32,18 @@ class SinglePathScanner {
|
|
|
32
32
|
this.props = props;
|
|
33
33
|
this.logger = props.logger || new gd_eventlog_1.EventLogger('SerialScanner');
|
|
34
34
|
}
|
|
35
|
+
logEvent(event) {
|
|
36
|
+
if (this.logger) {
|
|
37
|
+
this.logger.logEvent(event);
|
|
38
|
+
}
|
|
39
|
+
const w = global.window;
|
|
40
|
+
if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG) {
|
|
41
|
+
console.log('~~~ SerialScanner', event);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
35
44
|
onStopRequest(resolve) {
|
|
36
45
|
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
-
this.
|
|
46
|
+
this.logEvent({ message: 'stopping scan', path: this.path });
|
|
38
47
|
yield this.serial.closePort(this.path);
|
|
39
48
|
this.isScanning = false;
|
|
40
49
|
resolve(this.result);
|
|
@@ -46,7 +55,7 @@ class SinglePathScanner {
|
|
|
46
55
|
return;
|
|
47
56
|
this.isScanning = true;
|
|
48
57
|
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
49
|
-
this.
|
|
58
|
+
this.logEvent({ message: 'starting scan', path: this.path });
|
|
50
59
|
this.serial.scanEvents.on('timeout', () => this.onStopRequest(resolve));
|
|
51
60
|
this.serial.scanEvents.on('stop', () => this.onStopRequest(resolve));
|
|
52
61
|
let found = false;
|
|
@@ -65,12 +74,13 @@ class SinglePathScanner {
|
|
|
65
74
|
found = yield adapter.check();
|
|
66
75
|
if (found) {
|
|
67
76
|
const name = adapter.getName();
|
|
77
|
+
yield this.serial.closePort(this.path).catch();
|
|
68
78
|
resolve(Object.assign(Object.assign({}, adapterSettings), { name }));
|
|
69
79
|
}
|
|
70
80
|
yield (0, utils_1.sleep)(100);
|
|
71
81
|
}
|
|
72
82
|
catch (err) {
|
|
73
|
-
this.
|
|
83
|
+
this.logEvent({ message: 'error', fn: 'scan()', error: err.message || err, stack: err.stack });
|
|
74
84
|
yield (0, utils_1.sleep)(100);
|
|
75
85
|
}
|
|
76
86
|
}
|
|
@@ -113,12 +123,21 @@ class SerialInterface extends events_1.default {
|
|
|
113
123
|
this.scanEvents.setMaxListeners(100);
|
|
114
124
|
this.logger = props.logger || new gd_eventlog_1.EventLogger(`Serial:${ifaceName}`);
|
|
115
125
|
this.connected = false;
|
|
116
|
-
this.
|
|
126
|
+
this.logEvent({ message: 'new serial interface', ifaceName });
|
|
117
127
|
if (binding) {
|
|
118
128
|
this.setBinding(binding);
|
|
119
129
|
}
|
|
120
130
|
SerialInterface._add(this);
|
|
121
131
|
}
|
|
132
|
+
logEvent(event) {
|
|
133
|
+
if (this.logger) {
|
|
134
|
+
this.logger.logEvent(event);
|
|
135
|
+
}
|
|
136
|
+
const w = global.window;
|
|
137
|
+
if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG) {
|
|
138
|
+
console.log('~~~ Serial', event);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
122
141
|
setBinding(binding) {
|
|
123
142
|
this.binding = binding;
|
|
124
143
|
serialport_1.default.getInstance().setBinding(this.ifaceName, binding);
|
|
@@ -138,7 +157,7 @@ class SerialInterface extends events_1.default {
|
|
|
138
157
|
}
|
|
139
158
|
try {
|
|
140
159
|
const SerialPort = this.binding;
|
|
141
|
-
|
|
160
|
+
yield SerialPort.list();
|
|
142
161
|
this.connected = true;
|
|
143
162
|
return true;
|
|
144
163
|
}
|
|
@@ -156,7 +175,7 @@ class SerialInterface extends events_1.default {
|
|
|
156
175
|
}
|
|
157
176
|
openPort(path) {
|
|
158
177
|
return __awaiter(this, void 0, void 0, function* () {
|
|
159
|
-
this.
|
|
178
|
+
this.logEvent({ message: 'opening port', path });
|
|
160
179
|
const port = serialport_1.default.getInstance().getSerialPort(this.ifaceName, { path });
|
|
161
180
|
if (!port) {
|
|
162
181
|
return null;
|
|
@@ -164,20 +183,21 @@ class SerialInterface extends events_1.default {
|
|
|
164
183
|
const existing = this.ports.findIndex(p => p.path === path);
|
|
165
184
|
if (existing !== -1) {
|
|
166
185
|
const port = this.ports[existing].port;
|
|
167
|
-
if (port.isOpen)
|
|
186
|
+
if (port.isOpen) {
|
|
168
187
|
return port;
|
|
188
|
+
}
|
|
169
189
|
else {
|
|
170
190
|
this.ports.splice(existing, 1);
|
|
171
191
|
}
|
|
172
192
|
}
|
|
173
193
|
return new Promise((resolve) => {
|
|
174
194
|
port.once('error', (err) => {
|
|
175
|
-
this.
|
|
195
|
+
this.logEvent({ message: 'error', path, error: err || err.message });
|
|
176
196
|
port.removeAllListeners();
|
|
177
197
|
resolve(null);
|
|
178
198
|
});
|
|
179
199
|
port.once('open', () => {
|
|
180
|
-
this.
|
|
200
|
+
this.logEvent({ message: 'port opened', path });
|
|
181
201
|
port.removeAllListeners();
|
|
182
202
|
this.ports.push({ path, port });
|
|
183
203
|
resolve(port);
|
|
@@ -188,6 +208,7 @@ class SerialInterface extends events_1.default {
|
|
|
188
208
|
}
|
|
189
209
|
closePort(path) {
|
|
190
210
|
return __awaiter(this, void 0, void 0, function* () {
|
|
211
|
+
this.logEvent({ message: 'closing port' });
|
|
191
212
|
const existing = this.ports.findIndex(p => p.path === path);
|
|
192
213
|
if (existing === -1)
|
|
193
214
|
return true;
|
|
@@ -229,7 +250,7 @@ class SerialInterface extends events_1.default {
|
|
|
229
250
|
this.scanEvents.emit('timeout');
|
|
230
251
|
}, timeout);
|
|
231
252
|
}
|
|
232
|
-
this.
|
|
253
|
+
this.logEvent({ message: 'checking for ports' });
|
|
233
254
|
this.isScanning = true;
|
|
234
255
|
do {
|
|
235
256
|
try {
|
|
@@ -245,21 +266,21 @@ class SerialInterface extends events_1.default {
|
|
|
245
266
|
console.log('~~~ERROR', err);
|
|
246
267
|
}
|
|
247
268
|
if (!paths || paths.length === 0) {
|
|
248
|
-
this.
|
|
269
|
+
this.logEvent({ message: 'scanning: no ports detected', interface: this.ifaceName, paths: paths.map(p => p.path), timeout });
|
|
249
270
|
yield (0, utils_1.sleep)(1000);
|
|
250
271
|
}
|
|
251
272
|
if (Date.now() > toExpiresAt)
|
|
252
273
|
timeOutExpired = true;
|
|
253
274
|
} while (this.isScanning && !timeOutExpired && paths.length === 0);
|
|
254
275
|
if (paths.length === 0) {
|
|
255
|
-
this.
|
|
276
|
+
this.logEvent({ message: 'nothing to scan ' });
|
|
256
277
|
if (this.toScan) {
|
|
257
278
|
clearTimeout(this.toScan);
|
|
258
279
|
this.toScan = null;
|
|
259
280
|
}
|
|
260
281
|
return [];
|
|
261
282
|
}
|
|
262
|
-
this.
|
|
283
|
+
this.logEvent({ message: 'scanning on ', paths: paths.map(p => p.path), timeout });
|
|
263
284
|
const scanners = paths.map(p => new SinglePathScanner(p.path, this, Object.assign(Object.assign({}, props), { logger: this.logger })));
|
|
264
285
|
try {
|
|
265
286
|
yield Promise.all(scanners.map(s => s.scan()
|
|
@@ -272,14 +293,14 @@ class SerialInterface extends events_1.default {
|
|
|
272
293
|
.catch()));
|
|
273
294
|
}
|
|
274
295
|
catch (err) {
|
|
275
|
-
this.
|
|
296
|
+
this.logEvent({ message: 'error', fn: 'scan()', error: err.message || err, stack: err.stack });
|
|
276
297
|
}
|
|
277
298
|
if (this.toScan) {
|
|
278
299
|
clearTimeout(this.toScan);
|
|
279
300
|
this.toScan = null;
|
|
280
301
|
}
|
|
281
302
|
this.isScanning = false;
|
|
282
|
-
this.
|
|
303
|
+
this.logEvent({ message: 'scan finished on', interface: this.ifaceName, paths: paths.map(p => p.path), devices: detected.map(d => {
|
|
283
304
|
const res = Object.assign({}, d);
|
|
284
305
|
res.interface = this.ifaceName;
|
|
285
306
|
return res;
|