incyclist-devices 1.4.41 → 1.4.44
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/ble/ble-device.js +14 -9
- package/lib/ble/ble-interface.d.ts +1 -0
- package/lib/ble/ble-interface.js +49 -15
- package/lib/ble/fm.js +4 -4
- package/lib/ble/incyclist-protocol.js +1 -1
- package/package.json +1 -1
package/lib/ble/ble-device.js
CHANGED
|
@@ -93,7 +93,7 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
93
93
|
const connectPeripheral = (peripheral) => __awaiter(this, void 0, void 0, function* () {
|
|
94
94
|
this.connectState.isConnecting = true;
|
|
95
95
|
const connected = this.ble.findConnected(peripheral);
|
|
96
|
-
if (!connected) {
|
|
96
|
+
if (!connected && peripheral.state !== 'connected') {
|
|
97
97
|
try {
|
|
98
98
|
yield peripheral.connectAsync();
|
|
99
99
|
}
|
|
@@ -102,15 +102,20 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
try {
|
|
105
|
-
this.
|
|
105
|
+
if (!this.characteristics)
|
|
106
|
+
this.characteristics = [];
|
|
106
107
|
if (!connected) {
|
|
107
|
-
this.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
108
|
+
if (!this.characteristics || this.characteristics.length === 0) {
|
|
109
|
+
this.logEvent({ message: 'connect: discover characteristics start' });
|
|
110
|
+
const res = yield peripheral.discoverSomeServicesAndCharacteristicsAsync([], []);
|
|
111
|
+
const { characteristics } = res;
|
|
112
|
+
this.logEvent({ message: 'connect: discover characteristics result',
|
|
113
|
+
result: characteristics.map(c => ({ uuid: ble_1.uuid(c.uuid), properties: c.properties.join(','), service: ble_1.uuid(c._serviceUuid) }))
|
|
114
|
+
});
|
|
115
|
+
this.characteristics = characteristics;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
}
|
|
114
119
|
}
|
|
115
120
|
else {
|
|
116
121
|
this.characteristics = connected.characteristics;
|
|
@@ -29,6 +29,7 @@ export default class BleInterface extends BleInterfaceClass {
|
|
|
29
29
|
devices: BleDeviceInfo[];
|
|
30
30
|
logger: EventLogger;
|
|
31
31
|
deviceCache: any[];
|
|
32
|
+
peripheralCache: any[];
|
|
32
33
|
static deviceClasses: BleDeviceClassInfo[];
|
|
33
34
|
static _instance: BleInterface;
|
|
34
35
|
static getInstance(props?: {
|
package/lib/ble/ble-interface.js
CHANGED
|
@@ -13,6 +13,8 @@ const gd_eventlog_1 = require("gd-eventlog");
|
|
|
13
13
|
const utils_1 = require("../utils");
|
|
14
14
|
const ble_1 = require("./ble");
|
|
15
15
|
const CONNECT_TIMEOUT = 5000;
|
|
16
|
+
const DEFAULT_SCAN_TIMEOUT = 20000;
|
|
17
|
+
const BACKGROUND_SCAN_TIMEOUT = 30000;
|
|
16
18
|
class BleInterface extends ble_1.BleInterfaceClass {
|
|
17
19
|
constructor(props = {}) {
|
|
18
20
|
super(props);
|
|
@@ -20,6 +22,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
20
22
|
this.connectState = { isConnecting: false, isConnected: false, isInitSuccess: false };
|
|
21
23
|
this.devices = [];
|
|
22
24
|
this.deviceCache = [];
|
|
25
|
+
this.peripheralCache = [];
|
|
23
26
|
if (props.logger)
|
|
24
27
|
this.logger = props.logger;
|
|
25
28
|
else if (props.log) {
|
|
@@ -71,7 +74,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
71
74
|
const timeout = props.timeout || 2000;
|
|
72
75
|
const runBackgroundScan = () => {
|
|
73
76
|
this.scanState.isBackgroundScan = true;
|
|
74
|
-
this.scan({ timeout:
|
|
77
|
+
this.scan({ timeout: BACKGROUND_SCAN_TIMEOUT, isBackgroundScan: true })
|
|
75
78
|
.then(() => {
|
|
76
79
|
this.scanState.isBackgroundScan = false;
|
|
77
80
|
})
|
|
@@ -260,13 +263,13 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
260
263
|
}, 100);
|
|
261
264
|
});
|
|
262
265
|
}
|
|
263
|
-
connectDevice(requested, timeout = CONNECT_TIMEOUT) {
|
|
266
|
+
connectDevice(requested, timeout = DEFAULT_SCAN_TIMEOUT + CONNECT_TIMEOUT) {
|
|
264
267
|
return __awaiter(this, void 0, void 0, function* () {
|
|
265
268
|
const { id, name, address, getProfile } = requested;
|
|
266
269
|
const profile = getProfile && typeof (getProfile) === 'function' ? getProfile() : undefined;
|
|
267
270
|
this.logEvent({ message: 'connectDevice', id, name, address, profile, isbusy: this.scanState.isConnecting });
|
|
268
271
|
if (this.scanState.isConnecting) {
|
|
269
|
-
yield this.waitForConnectFinished(
|
|
272
|
+
yield this.waitForConnectFinished(CONNECT_TIMEOUT);
|
|
270
273
|
}
|
|
271
274
|
this.scanState.isConnecting = true;
|
|
272
275
|
let devices = [];
|
|
@@ -277,7 +280,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
277
280
|
this.logEvent({ message: 'retry connect device', id, name, address, profile, retryCount });
|
|
278
281
|
}
|
|
279
282
|
try {
|
|
280
|
-
devices = yield this.scan({ timeout, device: requested });
|
|
283
|
+
devices = yield this.scan({ timeout: DEFAULT_SCAN_TIMEOUT, device: requested });
|
|
281
284
|
if (devices.length === 0) {
|
|
282
285
|
retryCount++;
|
|
283
286
|
retry = retryCount < 5;
|
|
@@ -347,7 +350,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
347
350
|
}
|
|
348
351
|
scan(props) {
|
|
349
352
|
return __awaiter(this, void 0, void 0, function* () {
|
|
350
|
-
const { timeout =
|
|
353
|
+
const { timeout = DEFAULT_SCAN_TIMEOUT, deviceTypes = [], device } = props;
|
|
351
354
|
const scanForDevice = (device !== null && device !== undefined);
|
|
352
355
|
const services = this.getServicesFromDeviceTypes(deviceTypes);
|
|
353
356
|
const bleBinding = this.getBinding();
|
|
@@ -356,12 +359,12 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
356
359
|
if (!this.isConnected()) {
|
|
357
360
|
yield this.connect();
|
|
358
361
|
}
|
|
362
|
+
const peripheralsProcessed = [];
|
|
359
363
|
this.logEvent({ message: 'scan()', props, scanState: this.scanState, cache: this.deviceCache.map(p => ({ name: p.advertisement ? p.advertisement.localName : '', address: p.address })) });
|
|
360
364
|
if (!props.isBackgroundScan && this.scanState.isBackgroundScan) {
|
|
361
365
|
yield this.stopScan();
|
|
362
366
|
this.scanState.isBackgroundScan = false;
|
|
363
367
|
}
|
|
364
|
-
const detectedPeripherals = {};
|
|
365
368
|
let opStr;
|
|
366
369
|
if (scanForDevice) {
|
|
367
370
|
opStr = 'search device';
|
|
@@ -374,6 +377,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
374
377
|
}
|
|
375
378
|
if (this.scanState.isScanning) {
|
|
376
379
|
try {
|
|
380
|
+
this.logEvent({ message: `${opStr}: waiting for previous scan to finish` });
|
|
377
381
|
yield this.waitForScanFinished(timeout);
|
|
378
382
|
}
|
|
379
383
|
catch (err) {
|
|
@@ -383,6 +387,8 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
383
387
|
}
|
|
384
388
|
return new Promise((resolve, reject) => {
|
|
385
389
|
this.scanState.isScanning = true;
|
|
390
|
+
if (props.isBackgroundScan)
|
|
391
|
+
this.scanState.isBackgroundScan = true;
|
|
386
392
|
if (scanForDevice && device instanceof ble_1.BleDeviceClass) {
|
|
387
393
|
if (this.devices && this.devices.length > 0) {
|
|
388
394
|
const connectedDevices = this.devices.map(i => ({ name: i.device.name, address: i.device.address, isConnected: i.isConnected, connectState: i.device.getConnectState() }));
|
|
@@ -432,16 +438,46 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
432
438
|
}
|
|
433
439
|
}
|
|
434
440
|
}
|
|
435
|
-
const onPeripheralFound = (peripheral, fromCache = false) => {
|
|
441
|
+
const onPeripheralFound = (peripheral, fromCache = false) => __awaiter(this, void 0, void 0, function* () {
|
|
436
442
|
if (fromCache)
|
|
437
443
|
this.logEvent({ message: 'adding from Cache', peripheral: peripheral.address });
|
|
438
444
|
if (!peripheral || !peripheral.advertisement)
|
|
439
445
|
return;
|
|
440
|
-
|
|
446
|
+
let existingPeripheral = this.peripheralCache.find(i => i.address === peripheral.address);
|
|
447
|
+
if (existingPeripheral && Date.now() - existingPeripheral.ts > 600000) {
|
|
448
|
+
existingPeripheral.ts = Date.now();
|
|
449
|
+
}
|
|
450
|
+
if (!existingPeripheral) {
|
|
451
|
+
this.peripheralCache.push({ address: peripheral.address, ts: Date.now(), peripheral });
|
|
452
|
+
existingPeripheral = this.peripheralCache.find(i => i.address === peripheral.address);
|
|
453
|
+
}
|
|
454
|
+
let shouldAddDevice = peripheralsProcessed.find(p => p === peripheral.address) === undefined;
|
|
455
|
+
if (shouldAddDevice) {
|
|
441
456
|
if (process.env.BLE_DEBUG)
|
|
442
|
-
console.log('discovered', peripheral);
|
|
443
|
-
|
|
444
|
-
|
|
457
|
+
console.log('discovered', peripheral.id, peripheral.address, peripheral.advertisement.localName);
|
|
458
|
+
peripheralsProcessed.push(peripheral.address);
|
|
459
|
+
let characteristics;
|
|
460
|
+
if (!existingPeripheral.characteristics) {
|
|
461
|
+
try {
|
|
462
|
+
if (existingPeripheral.peripheral && existingPeripheral.peripheral.state !== 'connected')
|
|
463
|
+
yield peripheral.connectAsync();
|
|
464
|
+
const res = yield peripheral.discoverSomeServicesAndCharacteristicsAsync([], []);
|
|
465
|
+
this.logEvent({ message: 'characteristic info (+):', info: res.characteristics.map(c => `${peripheral.address} ${c.uuid} ${c.properties}`) });
|
|
466
|
+
if (peripheral.disconnect && typeof (peripheral.disconnect) === 'function')
|
|
467
|
+
peripheral.disconnect(() => { });
|
|
468
|
+
existingPeripheral.characteristics = res.characteristics;
|
|
469
|
+
characteristics = res.characteristics;
|
|
470
|
+
}
|
|
471
|
+
catch (err) {
|
|
472
|
+
console.log(err);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
characteristics = existingPeripheral.characteristics;
|
|
477
|
+
this.logEvent({ message: 'characteristic info (+):', info: characteristics.map(c => `${peripheral.address} ${c.uuid} ${c.properties}`) });
|
|
478
|
+
}
|
|
479
|
+
if (!fromCache)
|
|
480
|
+
this.addPeripheralToCache(peripheral);
|
|
445
481
|
let DeviceClasses;
|
|
446
482
|
if (scanForDevice && (!deviceTypes || deviceTypes.length === 0)) {
|
|
447
483
|
const classes = BleInterface.deviceClasses.map(c => c.Class);
|
|
@@ -461,6 +497,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
461
497
|
if (device && device.getProfile && device.getProfile() !== d.getProfile())
|
|
462
498
|
return;
|
|
463
499
|
d.setInterface(this);
|
|
500
|
+
d.characteristics = characteristics;
|
|
464
501
|
if (scanForDevice) {
|
|
465
502
|
if ((device.id && device.id !== '' && d.id === device.id) ||
|
|
466
503
|
(device.address && device.address !== '' && d.address === device.address) ||
|
|
@@ -496,9 +533,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
496
533
|
}
|
|
497
534
|
});
|
|
498
535
|
}
|
|
499
|
-
|
|
500
|
-
}
|
|
501
|
-
};
|
|
536
|
+
});
|
|
502
537
|
this.logEvent({ message: `${opStr}: start scanning`, requested: scanForDevice ? { name: device.name, address: device.address } : undefined, timeout });
|
|
503
538
|
this.deviceCache.forEach(peripheral => {
|
|
504
539
|
onPeripheralFound(peripheral, true);
|
|
@@ -510,7 +545,6 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
510
545
|
return reject(err);
|
|
511
546
|
}
|
|
512
547
|
bleBinding.on('discover', (p) => {
|
|
513
|
-
console.log('~~~ discovered:', p.address, p.advertisement ? p.advertisement.localName : '');
|
|
514
548
|
onPeripheralFound(p);
|
|
515
549
|
});
|
|
516
550
|
});
|
package/lib/ble/fm.js
CHANGED
|
@@ -53,7 +53,7 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
53
53
|
offset += 2;
|
|
54
54
|
}
|
|
55
55
|
if (flags & IndoorBikeDataFlag.AverageSpeedPresent) {
|
|
56
|
-
this.data.averageSpeed = data.readUInt16LE(offset);
|
|
56
|
+
this.data.averageSpeed = data.readUInt16LE(offset) / 100;
|
|
57
57
|
offset += 2;
|
|
58
58
|
}
|
|
59
59
|
if (flags & IndoorBikeDataFlag.InstantaneousCadence) {
|
|
@@ -61,7 +61,7 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
61
61
|
offset += 2;
|
|
62
62
|
}
|
|
63
63
|
if (flags & IndoorBikeDataFlag.AverageCadencePresent) {
|
|
64
|
-
this.data.averageCadence = data.readUInt16LE(offset);
|
|
64
|
+
this.data.averageCadence = data.readUInt16LE(offset) / 2;
|
|
65
65
|
offset += 2;
|
|
66
66
|
}
|
|
67
67
|
if (flags & IndoorBikeDataFlag.TotalDistancePresent) {
|
|
@@ -89,7 +89,7 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
89
89
|
offset += 2;
|
|
90
90
|
}
|
|
91
91
|
if (flags & IndoorBikeDataFlag.MetabolicEquivalentPresent) {
|
|
92
|
-
this.data.metabolicEquivalent = data.readUInt16LE(offset);
|
|
92
|
+
this.data.metabolicEquivalent = data.readUInt16LE(offset) / 10;
|
|
93
93
|
offset += 2;
|
|
94
94
|
}
|
|
95
95
|
if (flags & IndoorBikeDataFlag.ElapsedTimePresent) {
|
|
@@ -140,7 +140,7 @@ class FmAdapter extends Device_1.default {
|
|
|
140
140
|
isHrm() { return false; }
|
|
141
141
|
isPower() { return true; }
|
|
142
142
|
getProfile() {
|
|
143
|
-
return '
|
|
143
|
+
return 'Smart Trainer';
|
|
144
144
|
}
|
|
145
145
|
getName() {
|
|
146
146
|
return `${this.device.name}`;
|
|
@@ -88,7 +88,7 @@ class BleProtocol extends DeviceProtocol_1.default {
|
|
|
88
88
|
}
|
|
89
89
|
});
|
|
90
90
|
this.logger.logEvent({ message: 'scan started' });
|
|
91
|
-
yield this.ble.scan({ deviceTypes: supportedDeviceTypes });
|
|
91
|
+
yield this.ble.scan({ deviceTypes: supportedDeviceTypes, timeout: 20000 });
|
|
92
92
|
if (props && props.onScanFinished) {
|
|
93
93
|
props.onScanFinished(props.id);
|
|
94
94
|
}
|