incyclist-devices 2.1.7 → 2.1.9

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.
@@ -176,15 +176,17 @@ class AntInterface extends events_1.default {
176
176
  }
177
177
  }
178
178
  };
179
+ const onData = this.onData.bind(this);
180
+ const onError = this.onError.bind(this);
179
181
  const addListeners = (channel) => {
180
182
  channel.on('detected', onDetected);
181
- channel.on('data', this.onData.bind(this));
182
- channel.on('error', this.onError.bind(this));
183
+ channel.on('data', onData);
184
+ channel.on('error', onError);
183
185
  };
184
186
  const removeListeners = (channel) => {
185
187
  channel.off('detected', onDetected);
186
- channel.off('data', this.onData.bind(this));
187
- channel.off('error', this.onError.bind(this));
188
+ channel.off('data', onData);
189
+ channel.off('error', onError);
188
190
  };
189
191
  yield this.scannerWaitForConnection();
190
192
  if (!this.isConnected()) {
@@ -255,8 +257,10 @@ class AntInterface extends events_1.default {
255
257
  stopScan() {
256
258
  return __awaiter(this, void 0, void 0, function* () {
257
259
  this.logEvent({ message: 'stopping scan ..' });
258
- if (!this.isScanning())
260
+ if (!this.isScanning()) {
261
+ this.logEvent({ message: 'stopping scan done ..' });
259
262
  return true;
263
+ }
260
264
  return new Promise(done => {
261
265
  this.activeScan.emitter.emit('stop');
262
266
  this.once('scan stopped', (res) => {
@@ -76,9 +76,10 @@ class IncyclistDevice extends events_1.default {
76
76
  });
77
77
  }
78
78
  resume() {
79
+ var _a;
79
80
  return __awaiter(this, void 0, void 0, function* () {
80
81
  if (this.isStarted() && !this.isStopped())
81
- this.logger.logEvent({ message: 'resuming device', device: this.getName() });
82
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.logEvent({ message: 'resuming device', device: this.getName() });
82
83
  this.paused = false;
83
84
  return true;
84
85
  });
@@ -12,6 +12,7 @@ export default class BleAdapter<TDeviceData extends BleDeviceData, TDevice exten
12
12
  protected dataMsgCount: number;
13
13
  protected lastDataTS: number;
14
14
  protected device: TDevice;
15
+ protected onDeviceDataHandler: any;
15
16
  constructor(settings: BleDeviceSettings, props?: DeviceProperties);
16
17
  getUniqueName(): string;
17
18
  connect(): Promise<boolean>;
@@ -32,7 +33,8 @@ export default class BleAdapter<TDeviceData extends BleDeviceData, TDevice exten
32
33
  getSettings(): BleDeviceSettings;
33
34
  setProperties(props: BleDeviceProperties): void;
34
35
  check(): Promise<boolean>;
35
- start(props?: BleStartProperties): Promise<any>;
36
+ startPreChecks(props: BleStartProperties): Promise<'done' | 'connected' | 'connection-failed'>;
37
+ start(props?: BleStartProperties): Promise<boolean>;
36
38
  stop(): Promise<boolean>;
37
39
  pause(): Promise<boolean>;
38
40
  resume(): Promise<boolean>;
@@ -18,6 +18,7 @@ const INTERFACE_NAME = 'ble';
18
18
  class BleAdapter extends adpater_1.default {
19
19
  constructor(settings, props) {
20
20
  super(settings, props);
21
+ this.onDeviceDataHandler = this.onDeviceData.bind(this);
21
22
  if (this.settings.interface !== INTERFACE_NAME)
22
23
  throw new Error('Incorrect interface');
23
24
  this.deviceData = {};
@@ -139,23 +140,38 @@ class BleAdapter extends adpater_1.default {
139
140
  check() {
140
141
  return this.start({ scanOnly: true });
141
142
  }
142
- start(props = {}) {
143
+ startPreChecks(props) {
143
144
  return __awaiter(this, void 0, void 0, function* () {
145
+ const wasPaused = this.paused;
144
146
  const wasStopped = this.stopped;
145
- this.resume();
146
- if (this.started && !wasStopped)
147
- return true;
148
147
  this.stopped = false;
148
+ if (wasPaused)
149
+ this.resume();
150
+ if (this.started && !wasPaused && !wasStopped) {
151
+ return 'done';
152
+ }
153
+ if (this.started && wasPaused) {
154
+ return 'done';
155
+ }
149
156
  const connected = yield this.connect();
150
157
  if (!connected)
158
+ return 'connection-failed';
159
+ return 'connected';
160
+ });
161
+ }
162
+ start(props = {}) {
163
+ var _a;
164
+ return __awaiter(this, void 0, void 0, function* () {
165
+ const preCheckResult = yield this.startPreChecks(props);
166
+ if (preCheckResult === 'done')
167
+ return this.started;
168
+ if (preCheckResult === 'connection-failed')
151
169
  throw new Error(`could not start device, reason:could not connect`);
152
- this.logger.logEvent({ message: 'start requested', protocol: this.getProtocolName(), props });
170
+ this.logEvent({ message: 'starting device', device: this.getName(), props, isStarted: this.started });
153
171
  try {
154
172
  const comms = this.device;
155
173
  if (comms) {
156
- comms.on('data', (data) => {
157
- this.onDeviceData(data);
158
- });
174
+ comms.on('data', this.onDeviceDataHandler);
159
175
  this.resetData();
160
176
  this.stopped = false;
161
177
  this.started = true;
@@ -165,14 +181,16 @@ class BleAdapter extends adpater_1.default {
165
181
  }
166
182
  catch (err) {
167
183
  this.logger.logEvent({ message: 'start result: error', error: err.message, protocol: this.getProtocolName() });
184
+ (_a = this.getComms()) === null || _a === void 0 ? void 0 : _a.pause();
168
185
  throw new Error(`could not start device, reason:${err.message}`);
169
186
  }
170
187
  });
171
188
  }
172
189
  stop() {
173
190
  return __awaiter(this, void 0, void 0, function* () {
174
- this.logger.logEvent({ message: 'stop requested', protocol: this.getProtocolName() });
191
+ this.logger.logEvent({ message: 'stopping device', device: this.getName() });
175
192
  this.device.reset();
193
+ this.device.off('data', this.onDeviceDataHandler);
176
194
  const stopped = this.device.disconnect();
177
195
  if (stopped) {
178
196
  this.stopped = true;
@@ -9,6 +9,7 @@ export declare class BleLinuxBinding extends EventEmitter implements BleBinding
9
9
  static getInstance(): any;
10
10
  startScanning(serviceUUIDs?: string[] | undefined, allowDuplicates?: boolean | undefined, callback?: ((error?: Error | undefined) => void) | undefined): void;
11
11
  stopScanning(callback?: (() => void) | undefined): void;
12
+ setServerDebug(enabled: boolean): void;
12
13
  pauseLogging(): void;
13
14
  resumeLogging(): void;
14
15
  on(eventName: string | symbol, listener: (...args: any[]) => void): this;
@@ -23,6 +23,8 @@ class BleLinuxBinding extends events_1.default {
23
23
  stopScanning(callback) {
24
24
  throw new Error('Method not implemented.');
25
25
  }
26
+ setServerDebug(enabled) {
27
+ }
26
28
  pauseLogging() {
27
29
  }
28
30
  resumeLogging() {
@@ -29,6 +29,8 @@ class Binding extends events_1.default {
29
29
  return Binding._instance;
30
30
  }
31
31
  init() { }
32
+ setServerDebug(enabled) {
33
+ }
32
34
  pauseLogging() {
33
35
  }
34
36
  resumeLogging() {
@@ -14,6 +14,7 @@ export interface ScanState {
14
14
  timeout?: NodeJS.Timeout;
15
15
  peripherals?: Map<string, BlePeripheral>;
16
16
  detected?: string[];
17
+ emitter?: EventEmitter;
17
18
  }
18
19
  export interface ConnectState {
19
20
  isConnecting: boolean;
@@ -54,24 +55,25 @@ export default class BleInterface extends EventEmitter implements IncyclistInter
54
55
  getBinding(): BleBinding;
55
56
  setBinding(binding: BleBinding): void;
56
57
  getName(): string;
58
+ protected getReconnectPause(): number;
57
59
  startConnectSensor(): void;
58
60
  stopConnectSensor(): void;
59
61
  waitForSensorConnectionFinish(): Promise<void>;
60
62
  getAdapterFactory(): BleAdapterFactory;
61
- pauseLogging(): void;
63
+ pauseLogging(debugOnly?: boolean): void;
62
64
  resumeLogging(): void;
63
- isDebugEnabled(): boolean;
64
- logEvent(event: any): void;
65
- onStateChange(state: BleInterfaceState): void;
66
- onError(err: any): void;
65
+ protected isDebugEnabled(): boolean;
66
+ protected logEvent(event: any): void;
67
+ protected onStateChange(state: BleInterfaceState): void;
68
+ protected onError(err: any): void;
67
69
  connect(to?: number): Promise<boolean>;
68
70
  disconnect(): Promise<boolean>;
69
71
  isConnected(): boolean;
70
- waitForConnectFinished(timeout: any): Promise<unknown>;
71
72
  onDisconnect(peripheral: any): void;
72
- getCharacteristics(peripheral: BlePeripheral): Promise<BleCharacteristic[]>;
73
- waitForScanFinished(timeout: any): Promise<unknown>;
74
- onPeripheralFound(p: BlePeripheral, callback: any, props?: {
73
+ protected scannerWaitForConnection(tsTimeoutExpired?: number): Promise<void>;
74
+ protected getCharacteristics(peripheral: BlePeripheral): Promise<BleCharacteristic[]>;
75
+ protected waitForScanFinished(timeout: any): Promise<unknown>;
76
+ protected onPeripheralFound(p: BlePeripheral, callback: any, props?: {
75
77
  request?: BleDeviceSettings;
76
78
  comms?: BleComms;
77
79
  protocolFilter?: BleProtocol[] | null;
@@ -59,6 +59,9 @@ class BleInterface extends events_1.default {
59
59
  getName() {
60
60
  return 'ble';
61
61
  }
62
+ getReconnectPause() {
63
+ return 1000;
64
+ }
62
65
  startConnectSensor() {
63
66
  this.sensorIsConnecting = true;
64
67
  }
@@ -76,15 +79,19 @@ class BleInterface extends events_1.default {
76
79
  getAdapterFactory() {
77
80
  return adapter_factory_1.default.getInstance();
78
81
  }
79
- pauseLogging() {
80
- this.logEvent({ message: 'pause logging on BLE Interface' });
81
- this.loggingPaused = true;
82
+ pauseLogging(debugOnly = false) {
83
+ if (this.loggingPaused)
84
+ return;
85
+ this.logEvent({ message: 'pause logging on BLE Interface', debugOnly });
86
+ this.loggingPaused = debugOnly;
82
87
  try {
83
88
  this.getBinding().pauseLogging();
84
89
  }
85
90
  catch (_a) { }
86
91
  }
87
92
  resumeLogging() {
93
+ if (!this.loggingPaused)
94
+ return;
88
95
  const event = { message: 'resume logging on BLE Interface' };
89
96
  this.logger.logEvent(event);
90
97
  if (this.isDebugEnabled()) {
@@ -221,25 +228,23 @@ class BleInterface extends events_1.default {
221
228
  isConnected() {
222
229
  return this.connectState.isConnected;
223
230
  }
224
- waitForConnectFinished(timeout) {
225
- const waitStart = Date.now();
226
- const waitTimeout = waitStart + timeout;
227
- return new Promise((resolve, reject) => {
228
- const waitIv = setInterval(() => {
229
- if (this.scanState.isConnecting && Date.now() > waitTimeout) {
230
- clearInterval(waitIv);
231
- return reject(new Error('Connecting already in progress'));
232
- }
233
- if (!this.scanState.isConnecting) {
234
- clearInterval(waitIv);
235
- return resolve(true);
236
- }
237
- }, 100);
238
- });
239
- }
240
231
  onDisconnect(peripheral) {
241
232
  this.peripheralCache.remove(peripheral);
242
233
  }
234
+ scannerWaitForConnection(tsTimeoutExpired) {
235
+ return __awaiter(this, void 0, void 0, function* () {
236
+ const timeoutExpired = () => {
237
+ if (!tsTimeoutExpired)
238
+ return false;
239
+ return Date.now() >= tsTimeoutExpired;
240
+ };
241
+ while (!this.isConnected() && this.scanState.isScanning && !timeoutExpired()) {
242
+ const connected = yield this.connect();
243
+ if (!connected)
244
+ yield (0, utils_2.sleep)(this.getReconnectPause());
245
+ }
246
+ });
247
+ }
243
248
  getCharacteristics(peripheral) {
244
249
  return __awaiter(this, void 0, void 0, function* () {
245
250
  let characteristics = undefined;
@@ -369,6 +374,10 @@ class BleInterface extends events_1.default {
369
374
  const request = comms.getSettings();
370
375
  const { protocol } = request;
371
376
  const ble = this.getBinding();
377
+ try {
378
+ this.getBinding().setServerDebug(true);
379
+ }
380
+ catch (_a) { }
372
381
  if (!this.isConnected()) {
373
382
  yield this.connect();
374
383
  }
@@ -401,6 +410,10 @@ class BleInterface extends events_1.default {
401
410
  this.logEvent({ message: `${opStr}: stop scanning`, request });
402
411
  ble.stopScanning(() => {
403
412
  this.scanState.isScanning = false;
413
+ try {
414
+ this.getBinding().setServerDebug(false);
415
+ }
416
+ catch (_a) { }
404
417
  reject(new Error('device not found'));
405
418
  return;
406
419
  });
@@ -430,6 +443,10 @@ class BleInterface extends events_1.default {
430
443
  ble.stopScanning(() => {
431
444
  ble.removeAllListeners('discover');
432
445
  this.scanState.isScanning = false;
446
+ try {
447
+ this.getBinding().setServerDebug(false);
448
+ }
449
+ catch (_a) { }
433
450
  resolve(peripheral);
434
451
  });
435
452
  });
@@ -447,13 +464,17 @@ class BleInterface extends events_1.default {
447
464
  }
448
465
  scan(props = {}) {
449
466
  return __awaiter(this, void 0, void 0, function* () {
450
- const { timeout = DEFAULT_SCAN_TIMEOUT, protocol, protocols } = props;
467
+ this.resumeLogging();
468
+ this.logEvent({ message: 'starting scan ..' });
469
+ const { timeout, protocol, protocols } = props;
451
470
  const requestedProtocols = protocols || [];
452
471
  if (protocol && !requestedProtocols.find(p => p === protocol))
453
472
  requestedProtocols.push(protocol);
454
473
  const protocolFilter = requestedProtocols.length > 0 ? requestedProtocols : null;
455
474
  const services = protocolFilter === null ? this.getAdapterFactory().getAllSupportedServices() : (0, comms_utils_1.getServicesFromProtocols)(protocolFilter);
456
475
  const ble = this.getBinding();
476
+ if (!ble)
477
+ throw new Error('no binding defined');
457
478
  const opStr = 'scan';
458
479
  if (this.scanState.isScanning) {
459
480
  try {
@@ -466,49 +487,49 @@ class BleInterface extends events_1.default {
466
487
  }
467
488
  }
468
489
  this.scanState.isScanning = true;
490
+ this.scanState.emitter = new events_1.default();
469
491
  const tsStart = Date.now();
470
- const tsTimeoutExpired = tsStart + timeout;
471
- while (!this.isConnected() && this.scanState.isScanning && Date.now() < tsTimeoutExpired) {
472
- const connected = yield this.connect();
473
- if (!connected)
474
- yield (0, utils_2.sleep)(1000);
475
- }
476
- if (Date.now() > tsTimeoutExpired) {
477
- return [];
478
- }
479
- if (!this.scanState.isScanning) {
492
+ const tsTimeoutExpired = timeout ? tsStart + timeout : undefined;
493
+ yield this.scannerWaitForConnection(tsTimeoutExpired);
494
+ if (Date.now() > tsTimeoutExpired || !this.scanState.isScanning) {
480
495
  return [];
481
496
  }
482
- const adjustedScanTimeout = tsStart - Date.now() + timeout;
497
+ const adjustedScanTimeout = timeout;
483
498
  const supported = adapter_factory_1.default.getInstance().getAll().map(i => i.protocol);
484
499
  this.logEvent({ message: 'scan start', services, supported });
485
500
  return new Promise((resolve, reject) => {
486
501
  this.scanState.peripherals = new Map();
487
502
  const detected = [];
488
503
  const requested = protocolFilter;
489
- const onTimeout = () => {
504
+ const onTimeoutOrStopped = (wasTimeout = false) => __awaiter(this, void 0, void 0, function* () {
490
505
  if (!this.scanState.isScanning || !this.scanState.timeout)
491
506
  return;
492
- this.scanState.timeout = null;
507
+ if (this.scanState.timeout) {
508
+ clearTimeout(this.scanState.timeout);
509
+ this.scanState.timeout = null;
510
+ }
493
511
  const devices = detected.map(d => {
494
512
  const { id, name, address, protocol } = d;
495
513
  return { id, name, address, protocol };
496
514
  });
497
- this.logEvent({ message: `${opStr} result: timeout, devices found`, requested, devices });
515
+ if (wasTimeout)
516
+ this.logEvent({ message: `${opStr} result: timeout, devices found`, requested, devices });
498
517
  ble.removeAllListeners('discover');
499
- this.logEvent({ message: `${opStr}: stop scanning`, requested });
500
- ble.stopScanning(() => {
501
- this.scanState.isScanning = false;
502
- resolve(detected);
503
- });
518
+ yield ble.stopScanning();
519
+ resolve(detected);
504
520
  this.emittingAdapters.forEach(a => {
505
521
  a.comms.off('data', a.cb);
506
522
  a.comms.unsubscribeAll();
507
523
  });
508
524
  this.emittingAdapters = [];
509
- };
510
- this.logEvent({ message: `${opStr}: start scanning`, requested, timeout });
511
- this.scanState.timeout = setTimeout(onTimeout, adjustedScanTimeout);
525
+ this.emit('scan stopped', true);
526
+ });
527
+ if (timeout)
528
+ this.scanState.timeout = setTimeout(onTimeoutOrStopped, adjustedScanTimeout);
529
+ this.scanState.emitter.on('stop', () => {
530
+ this.emit('stop-scan');
531
+ onTimeoutOrStopped();
532
+ });
512
533
  ble.startScanning(protocolFilter ? services : [], false, (err) => {
513
534
  if (err) {
514
535
  this.logEvent({ message: `${opStr} result: error`, requested, error: err.message });
@@ -546,24 +567,21 @@ class BleInterface extends events_1.default {
546
567
  }
547
568
  stopScan() {
548
569
  return __awaiter(this, void 0, void 0, function* () {
549
- this.logEvent({ message: 'scan stop request' });
550
- if (!this.scanState.isScanning) {
551
- this.logEvent({ message: 'scan stop result: not scanning' });
570
+ this.logEvent({ message: 'stopping scan ..' });
571
+ this.pauseLogging(true);
572
+ if (!this.isScanning()) {
573
+ this.logEvent({ message: 'stopping scan done ..' });
552
574
  return true;
553
575
  }
554
- const ble = this.getBinding();
555
- if (!ble)
556
- throw new Error('no binding defined');
557
- ble.removeAllListeners('discover');
558
- this.peripheralCache.handleStopScan();
559
- ble.stopScanning();
560
- this.emittingAdapters.forEach(a => {
561
- a.comms.unsubscribeAll();
562
- a.comms.off('data', a.cb);
576
+ yield new Promise(done => {
577
+ var _a;
578
+ (_a = this.scanState.emitter) === null || _a === void 0 ? void 0 : _a.emit('stop');
579
+ this.once('scan stopped', (res) => {
580
+ done(res);
581
+ });
563
582
  });
564
- this.emittingAdapters = [];
565
583
  this.scanState.isScanning = false;
566
- this.logEvent({ message: 'scan stop result: success' });
584
+ this.logEvent({ message: 'stopping scan done ..' });
567
585
  return true;
568
586
  });
569
587
  }
@@ -18,8 +18,9 @@ class BleCyclingPowerDevice extends comms_1.BleComms {
18
18
  static isMatching(characteristics) {
19
19
  if (!characteristics)
20
20
  return false;
21
- const hasCPMeasurement = characteristics.find(c => c === consts_1.CSP_MEASUREMENT) !== undefined;
22
- const hasCPFeature = characteristics.find(c => c === consts_1.CSP_FEATURE) !== undefined;
21
+ const announced = characteristics.map(c => (0, utils_1.uuid)(c));
22
+ const hasCPMeasurement = announced.find(c => c === consts_1.CSP_MEASUREMENT) !== undefined;
23
+ const hasCPFeature = announced.find(c => c === consts_1.CSP_FEATURE) !== undefined;
23
24
  return hasCPMeasurement && hasCPFeature;
24
25
  }
25
26
  getProfile() {
@@ -19,8 +19,9 @@ class BleEliteDevice extends comms_1.BleComms {
19
19
  static isMatching(characteristics) {
20
20
  if (!characteristics)
21
21
  return false;
22
- const hasCPMeasurement = characteristics.find(c => c === consts_1.CSP_MEASUREMENT) !== undefined;
23
- const hasCPFeature = characteristics.find(c => c === consts_1.CSP_FEATURE) !== undefined;
22
+ const announced = characteristics.map(c => (0, utils_1.uuid)(c));
23
+ const hasCPMeasurement = announced.find(c => c === consts_1.CSP_MEASUREMENT) !== undefined;
24
+ const hasCPFeature = announced.find(c => c === consts_1.CSP_FEATURE) !== undefined;
24
25
  return hasCPMeasurement && hasCPFeature;
25
26
  }
26
27
  getProfile() {
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const consts_1 = require("../consts");
13
13
  const comms_1 = require("../base/comms");
14
+ const utils_1 = require("../utils");
14
15
  const bit = (nr) => (1 << nr);
15
16
  const IndoorBikeDataFlag = {
16
17
  MoreData: bit(0),
@@ -82,9 +83,10 @@ class BleFitnessMachineDevice extends comms_1.BleComms {
82
83
  static isMatching(characteristics) {
83
84
  if (!characteristics)
84
85
  return false;
85
- const hasStatus = characteristics.find(c => c === consts_1.FTMS_STATUS) !== undefined;
86
- const hasCP = characteristics.find(c => c === consts_1.FTMS_CP) !== undefined;
87
- const hasIndoorBike = characteristics.find(c => c === consts_1.INDOOR_BIKE_DATA) !== undefined;
86
+ const announced = characteristics.map(c => (0, utils_1.uuid)(c));
87
+ const hasStatus = announced.find(c => c === consts_1.FTMS_STATUS) !== undefined;
88
+ const hasCP = announced.find(c => c === consts_1.FTMS_CP) !== undefined;
89
+ const hasIndoorBike = announced.find(c => c === consts_1.INDOOR_BIKE_DATA) !== undefined;
88
90
  return hasStatus && hasCP && hasIndoorBike;
89
91
  }
90
92
  subscribeWriteResponse(cuuid) {
@@ -14,6 +14,7 @@ export default class BleHrmDevice extends BleComms {
14
14
  getProfile(): LegacyProfile;
15
15
  getProtocol(): BleProtocol;
16
16
  getServiceUUids(): string[];
17
+ static isMatching(characteristics: string[]): boolean;
17
18
  parseHrm(_data: Uint8Array): HrmData;
18
19
  onData(characteristic: string, data: Buffer): boolean;
19
20
  }
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const comms_1 = require("../base/comms");
4
+ const consts_1 = require("../consts");
5
+ const utils_1 = require("../utils");
4
6
  class BleHrmDevice extends comms_1.BleComms {
5
7
  constructor(props) {
6
8
  super(props);
@@ -16,6 +18,13 @@ class BleHrmDevice extends comms_1.BleComms {
16
18
  getServiceUUids() {
17
19
  return BleHrmDevice.services;
18
20
  }
21
+ static isMatching(characteristics) {
22
+ if (!characteristics)
23
+ return false;
24
+ const announced = characteristics.map(c => (0, utils_1.uuid)(c));
25
+ const hasHRMeasurement = announced.find(c => c === consts_1.HR_MEASUREMENT) !== undefined;
26
+ return hasHRMeasurement;
27
+ }
19
28
  parseHrm(_data) {
20
29
  const data = Buffer.from(_data);
21
30
  try {
@@ -51,6 +60,6 @@ class BleHrmDevice extends comms_1.BleComms {
51
60
  }
52
61
  BleHrmDevice.protocol = 'hr';
53
62
  BleHrmDevice.services = ['180d'];
54
- BleHrmDevice.characteristics = ['2a37', '2a38', '2a39', '2a3c'];
63
+ BleHrmDevice.characteristics = [consts_1.HR_MEASUREMENT, '2a38', '2a39', '2a3c'];
55
64
  BleHrmDevice.detectionPriority = 1;
56
65
  exports.default = BleHrmDevice;
@@ -2,7 +2,7 @@ import { BleFmAdapter } from '../fm';
2
2
  import { BleDeviceSettings, BleStartProperties } from '../types';
3
3
  import { DeviceProperties, IAdapter } from '../../types';
4
4
  import { LegacyProfile } from '../../antv2/types';
5
- export default class BleTacxFEAdapter extends BleFmAdapter {
5
+ export default class BleTacxAdapter extends BleFmAdapter {
6
6
  protected static INCYCLIST_PROFILE_NAME: LegacyProfile;
7
7
  constructor(settings: BleDeviceSettings, props?: DeviceProperties);
8
8
  isSame(device: IAdapter): boolean;
@@ -17,7 +17,7 @@ const fm_1 = require("../fm");
17
17
  const comms_1 = __importDefault(require("./comms"));
18
18
  const consts_1 = require("../../base/consts");
19
19
  const types_1 = require("../../types");
20
- class BleTacxFEAdapter extends fm_1.BleFmAdapter {
20
+ class BleTacxAdapter extends fm_1.BleFmAdapter {
21
21
  constructor(settings, props) {
22
22
  super(settings, props);
23
23
  this.logger = new gd_eventlog_1.EventLogger('BLE-FEC-Tacx');
@@ -31,7 +31,7 @@ class BleTacxFEAdapter extends fm_1.BleFmAdapter {
31
31
  ];
32
32
  }
33
33
  isSame(device) {
34
- if (!(device instanceof BleTacxFEAdapter))
34
+ if (!(device instanceof BleTacxAdapter))
35
35
  return false;
36
36
  return this.isEqual(device.settings);
37
37
  }
@@ -102,5 +102,5 @@ class BleTacxFEAdapter extends fm_1.BleFmAdapter {
102
102
  });
103
103
  }
104
104
  }
105
- BleTacxFEAdapter.INCYCLIST_PROFILE_NAME = 'Smart Trainer';
106
- exports.default = BleTacxFEAdapter;
105
+ BleTacxAdapter.INCYCLIST_PROFILE_NAME = 'Smart Trainer';
106
+ exports.default = BleTacxAdapter;
@@ -53,8 +53,9 @@ class TacxAdvancedFitnessMachineDevice extends comms_1.default {
53
53
  static isMatching(characteristics) {
54
54
  if (!characteristics)
55
55
  return false;
56
- const hasTacxCP = characteristics.find(c => (0, utils_1.matches)(c, consts_1.TACX_FE_C_RX)) !== undefined &&
57
- characteristics.find(c => (0, utils_1.matches)(c, consts_1.TACX_FE_C_TX)) !== undefined;
56
+ const announced = characteristics.map(c => (0, utils_1.uuid)(c));
57
+ const hasTacxCP = announced.find(c => (0, utils_1.matches)(c, consts_1.TACX_FE_C_RX)) !== undefined &&
58
+ announced.find(c => (0, utils_1.matches)(c, consts_1.TACX_FE_C_TX)) !== undefined;
58
59
  return hasTacxCP;
59
60
  }
60
61
  setCharacteristicUUIDs(uuids) {
@@ -10,6 +10,7 @@ export interface BleBinding extends EventEmitter {
10
10
  stopScanning(callback?: () => void): void;
11
11
  pauseLogging(): any;
12
12
  resumeLogging(): any;
13
+ setServerDebug(enabled: boolean): any;
13
14
  _bindings: any;
14
15
  state: BleInterfaceState;
15
16
  on(eventName: string | symbol, listener: (...args: any[]) => void): this;
@@ -34,8 +34,9 @@ class BleWahooDevice extends comms_1.default {
34
34
  static isMatching(characteristics) {
35
35
  if (!characteristics)
36
36
  return false;
37
- const hasWahooCP = characteristics.find(c => (0, utils_1.matches)(c, consts_2.WAHOO_ADVANCED_TRAINER_CP)) !== undefined;
38
- const hasFTMS = characteristics.find(c => (0, utils_1.matches)(c, consts_2.FTMS_CP)) !== undefined;
37
+ const announced = characteristics.map(c => (0, utils_1.uuid)(c));
38
+ const hasWahooCP = announced.find(c => (0, utils_1.matches)(c, consts_2.WAHOO_ADVANCED_TRAINER_CP)) !== undefined;
39
+ const hasFTMS = announced.find(c => (0, utils_1.matches)(c, consts_2.FTMS_CP)) !== undefined;
39
40
  return hasWahooCP && !hasFTMS;
40
41
  }
41
42
  init() {
@@ -33,7 +33,7 @@ export default class DaumAdapter<S extends SerialDeviceSettings, P extends Devic
33
33
  performCheck(): Promise<boolean>;
34
34
  waitForPrevStartFinished(): Promise<void>;
35
35
  start(props?: P): Promise<boolean>;
36
- performStart(props?: P, isRelaunch?: boolean): Promise<boolean>;
36
+ performStart(props?: P, isRelaunch?: boolean, wasPaused?: boolean): Promise<boolean>;
37
37
  startUpdatePull(): void;
38
38
  stopUpdatePull(): void;
39
39
  connect(): Promise<boolean>;
@@ -112,9 +112,10 @@ class DaumAdapter extends adapter_1.SerialIncyclistDevice {
112
112
  const _super = Object.create(null, {
113
113
  pause: { get: () => super.pause }
114
114
  });
115
+ var _a;
115
116
  return __awaiter(this, void 0, void 0, function* () {
116
117
  const paused = yield _super.pause.call(this);
117
- this.comms.pauseLogging();
118
+ (_a = this.comms) === null || _a === void 0 ? void 0 : _a.pauseLogging();
118
119
  return paused;
119
120
  });
120
121
  }
@@ -122,9 +123,10 @@ class DaumAdapter extends adapter_1.SerialIncyclistDevice {
122
123
  const _super = Object.create(null, {
123
124
  resume: { get: () => super.resume }
124
125
  });
126
+ var _a;
125
127
  return __awaiter(this, void 0, void 0, function* () {
126
128
  const resumed = yield _super.resume.call(this);
127
- this.comms.resumeLogging();
129
+ (_a = this.comms) === null || _a === void 0 ? void 0 : _a.resumeLogging();
128
130
  return resumed;
129
131
  });
130
132
  }
@@ -178,16 +180,20 @@ class DaumAdapter extends adapter_1.SerialIncyclistDevice {
178
180
  });
179
181
  }
180
182
  start(props) {
183
+ var _a;
181
184
  return __awaiter(this, void 0, void 0, function* () {
182
185
  yield this.waitForPrevCheckFinished();
183
186
  yield this.waitForPrevStartFinished();
184
187
  const isRelaunch = this.started;
185
188
  const message = isRelaunch ? 'relaunch of device' : 'initial start of device';
186
- this.logEvent({ message });
189
+ (_a = this.logger) === null || _a === void 0 ? void 0 : _a.logEvent({ message });
187
190
  try {
188
- if (isRelaunch && this.isPaused())
191
+ let wasPaused = false;
192
+ if (isRelaunch && this.isPaused()) {
189
193
  this.resume();
190
- this.startPromise = this.performStart(props, isRelaunch).then((started) => __awaiter(this, void 0, void 0, function* () {
194
+ wasPaused = true;
195
+ }
196
+ this.startPromise = this.performStart(props, isRelaunch, wasPaused).then((started) => __awaiter(this, void 0, void 0, function* () {
191
197
  if (!started) {
192
198
  this.logEvent({ message: 'start result: not started' });
193
199
  this.started = false;
@@ -198,7 +204,7 @@ class DaumAdapter extends adapter_1.SerialIncyclistDevice {
198
204
  const deviceInfo = yield this.getDeviceInfo();
199
205
  this.logEvent({ message: 'device info', deviceInfo });
200
206
  }
201
- catch (_a) { }
207
+ catch (_b) { }
202
208
  }
203
209
  this.logEvent({ message: 'start result: success' });
204
210
  this.started = true;
@@ -216,7 +222,7 @@ class DaumAdapter extends adapter_1.SerialIncyclistDevice {
216
222
  }
217
223
  });
218
224
  }
219
- performStart(props, isRelaunch = false) {
225
+ performStart(props, isRelaunch = false, wasPaused = false) {
220
226
  throw new Error('Method not implemented.');
221
227
  }
222
228
  startUpdatePull() {
@@ -14,7 +14,7 @@ export default class DaumClassicAdapter extends DaumAdapter<SerialDeviceSettings
14
14
  setName(name: string): void;
15
15
  getProtocolName(): string;
16
16
  performCheck(): Promise<boolean>;
17
- performStart(props?: DaumClassicProperties, isRelaunch?: boolean): Promise<boolean>;
17
+ performStart(props?: DaumClassicProperties, isRelaunch?: boolean, wasPaused?: boolean): Promise<boolean>;
18
18
  getCurrentBikeData(): Promise<IncyclistBikeData>;
19
19
  getDeviceInfo(): Promise<any>;
20
20
  }
@@ -92,7 +92,7 @@ class DaumClassicAdapter extends DaumAdapter_1.default {
92
92
  });
93
93
  });
94
94
  }
95
- performStart(props = {}, isRelaunch = false) {
95
+ performStart(props = {}, isRelaunch = false, wasPaused = false) {
96
96
  this.stopUpdatePull();
97
97
  this.setBikeProps(props);
98
98
  const user = this.getUser();
@@ -20,7 +20,7 @@ export default class DaumPremiumAdapter extends DaumAdapter<SerialDeviceSettings
20
20
  performCheck(): Promise<boolean>;
21
21
  getStartRetries(): number;
22
22
  getStartRetryTimeout(): number;
23
- performStart(props?: DaumPremiumDeviceProperties, _isRelaunch?: boolean): Promise<boolean>;
23
+ performStart(props?: DaumPremiumDeviceProperties, _isRelaunch?: boolean, wasPaused?: boolean): Promise<boolean>;
24
24
  requiresProgramUpload(): boolean;
25
25
  getCurrentBikeData(): Promise<IncyclistBikeData>;
26
26
  getDeviceInfo(): Promise<any>;
@@ -122,14 +122,19 @@ class DaumPremiumAdapter extends DaumAdapter_1.default {
122
122
  getStartRetryTimeout() {
123
123
  return START_RETRY_TIMEOUT;
124
124
  }
125
- performStart(props = {}, _isRelaunch = false) {
125
+ performStart(props = {}, _isRelaunch = false, wasPaused = false) {
126
126
  return __awaiter(this, void 0, void 0, function* () {
127
127
  this.setBikeProps(props);
128
128
  this.initData();
129
- yield this.stop();
129
+ if (!wasPaused)
130
+ yield this.stop();
130
131
  var info = {};
131
132
  yield (0, utils_1.runWithRetries)(() => __awaiter(this, void 0, void 0, function* () {
132
133
  try {
134
+ if (wasPaused) {
135
+ info.deviceType = 'Resumed';
136
+ info.version = "Resumed";
137
+ }
133
138
  info.connected = yield this.connect();
134
139
  if (!info.connected)
135
140
  throw new Error('not connected');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-devices",
3
- "version": "2.1.7",
3
+ "version": "2.1.9",
4
4
  "dependencies": {
5
5
  "@serialport/bindings-interface": "^1.2.2",
6
6
  "@serialport/parser-byte-length": "^9.0.1",