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.
@@ -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.cleanupListeners();
105
+ if (!this.characteristics)
106
+ this.characteristics = [];
106
107
  if (!connected) {
107
- this.logEvent({ message: 'connect: discover characteristics start' });
108
- const res = yield peripheral.discoverSomeServicesAndCharacteristicsAsync([], []);
109
- const { characteristics } = res;
110
- this.logEvent({ message: 'connect: discover characteristics result',
111
- result: characteristics.map(c => ({ uuid: ble_1.uuid(c.uuid), properties: c.properties.join(','), service: ble_1.uuid(c._serviceUuid) }))
112
- });
113
- this.characteristics = characteristics;
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?: {
@@ -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: 5000, isBackgroundScan: true })
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(10000);
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 = 5000, deviceTypes = [], device } = props;
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
- if (!detectedPeripherals[peripheral.id]) {
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
- detectedPeripherals[peripheral.id] = peripheral;
444
- this.addPeripheralToCache(peripheral);
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
- else {
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 'Power Meter';
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-devices",
3
- "version": "1.4.41",
3
+ "version": "1.4.44",
4
4
  "dependencies": {
5
5
  "@serialport/parser-byte-length": "^9.0.1",
6
6
  "@serialport/parser-delimiter": "^9.0.1",