incyclist-devices 2.3.7 → 2.3.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.
@@ -143,7 +143,7 @@ class AntAdapter extends adpater_1.default {
143
143
  this.emit('device-info', this.getSettings(), { manufacturer: (0, utils_2.getBrand)(deviceData.ManId) });
144
144
  }
145
145
  const logData = this.getLogData(deviceData, ['PairedDevices', 'RawData', '_RawData']);
146
- this.logEvent({ message: 'onDeviceData', data: logData, paused: this.paused, started: this.started, canEmit: this.canEmitData() });
146
+ this.logEvent({ message: 'onDeviceData', device: this.getName(), interface: this.getInterface(), data: logData, paused: this.paused, started: this.started, canEmit: this.canEmitData() });
147
147
  if (this.isStopped() || !this.canEmitData())
148
148
  return;
149
149
  if (this.isControllable()) {
@@ -171,7 +171,7 @@ class AntAdapter extends adpater_1.default {
171
171
  clearInterval(iv);
172
172
  resolve(true);
173
173
  }
174
- if (!this.promiseWaitForData) {
174
+ if (!this.promiseWaitForData || this.stopped) {
175
175
  resolve(false);
176
176
  clearInterval(iv);
177
177
  }
@@ -31,7 +31,10 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
31
31
  protected discoverTask: InteruptableTask<TaskState, void>;
32
32
  protected onDiscovered: (peripheral: BleRawPeripheral) => void;
33
33
  protected instanceId: number;
34
- protected connectedPeripherals: IBlePeripheral[];
34
+ protected connectedPeripherals: {
35
+ id: string;
36
+ peripheral: IBlePeripheral;
37
+ }[];
35
38
  protected connectAttemptCnt: number;
36
39
  protected emitted: BlePeripheralAnnouncement[];
37
40
  static getInstance(props?: InterfaceProps): BleInterface;
@@ -46,7 +49,8 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
46
49
  connect(reconnect?: boolean): Promise<boolean>;
47
50
  disconnect(connectionLost?: boolean): Promise<boolean>;
48
51
  isConnected(): boolean;
49
- registerConnected(peripheral: IBlePeripheral): void;
52
+ registerConnected(peripheral: IBlePeripheral, id: string): void;
53
+ unregisterConnected(id: string): void;
50
54
  protected isConnecting(): boolean;
51
55
  scan(props: BleScanProps): Promise<DeviceSettings[]>;
52
56
  stopScan(): Promise<boolean>;
@@ -147,8 +147,19 @@ class BleInterface extends events_1.default {
147
147
  var _a;
148
148
  return this.connectAttemptCnt > 0 && ((_a = this.getBinding()) === null || _a === void 0 ? void 0 : _a.state) === 'poweredOn';
149
149
  }
150
- registerConnected(peripheral) {
151
- this.connectedPeripherals.push(peripheral);
150
+ registerConnected(peripheral, id) {
151
+ const p = this.connectedPeripherals.find(p => p.id === id);
152
+ if (p) {
153
+ p.peripheral = peripheral;
154
+ }
155
+ else
156
+ this.connectedPeripherals.push({ peripheral, id });
157
+ }
158
+ unregisterConnected(id) {
159
+ const p = this.connectedPeripherals.find(p => p.id === id);
160
+ if (p) {
161
+ this.connectedPeripherals.splice(this.connectedPeripherals.indexOf(p), 1);
162
+ }
152
163
  }
153
164
  isConnecting() {
154
165
  var _a;
@@ -298,14 +309,14 @@ class BleInterface extends events_1.default {
298
309
  }
299
310
  emitDisconnectAllPeripherals() {
300
311
  this.connectedPeripherals.forEach(p => {
301
- const peripheral = p.getPeripheral();
312
+ const peripheral = p.peripheral.getPeripheral();
302
313
  peripheral.emit('disconnect');
303
314
  });
304
315
  this.connectedPeripherals = [];
305
316
  }
306
317
  disconnectAllPeripherals() {
307
318
  return __awaiter(this, void 0, void 0, function* () {
308
- const promises = this.connectedPeripherals.map(p => p.disconnect());
319
+ const promises = this.connectedPeripherals.map(p => p.peripheral.disconnect());
309
320
  yield Promise.allSettled(promises);
310
321
  this.connectedPeripherals = [];
311
322
  });
@@ -406,11 +417,11 @@ class BleInterface extends events_1.default {
406
417
  try {
407
418
  peripheral.on('error', (err) => {
408
419
  peripheral.removeAllListeners();
409
- this.logEvent({ message: 'peripheral error', error: err.message });
420
+ this.logEvent({ message: 'discover services: peripheral error', error: err.message });
410
421
  });
411
422
  peripheral.on('disconnect', () => {
412
423
  peripheral.removeAllListeners();
413
- this.logEvent({ message: 'peripheral disconnected' });
424
+ this.logEvent({ message: 'discover services: peripheral disconnected' });
414
425
  });
415
426
  yield peripheral.connectAsync();
416
427
  if (peripheral.discoverServicesAsync !== undefined) {
@@ -3,6 +3,7 @@ import { BleInterface } from "./interface";
3
3
  export declare class BlePeripheral implements IBlePeripheral {
4
4
  protected announcement: BlePeripheralAnnouncement;
5
5
  protected connected: boolean;
6
+ protected connectPromise: Promise<void>;
6
7
  protected characteristics: Record<string, BleRawCharacteristic>;
7
8
  protected onDisconnectHandler?: () => void;
8
9
  protected ble: BleInterface;
@@ -11,6 +12,7 @@ export declare class BlePeripheral implements IBlePeripheral {
11
12
  callback: (data: Buffer) => void;
12
13
  }>;
13
14
  protected disconnecting: boolean;
15
+ protected disconnectedSignalled: boolean;
14
16
  protected onErrorHandler: any;
15
17
  constructor(announcement: BlePeripheralAnnouncement);
16
18
  get services(): BleService[];
@@ -33,6 +35,7 @@ export declare class BlePeripheral implements IBlePeripheral {
33
35
  unsubscribeAll(connectionLost?: boolean): Promise<void>;
34
36
  read(characteristicUUID: string): Promise<Buffer>;
35
37
  write(characteristicUUID: string, data: Buffer, options?: BleWriteProps): Promise<Buffer>;
36
- protected getRawCharacteristic(uuid: string): BleRawCharacteristic;
38
+ protected queryRawCharacteristic(uuid: string): Promise<BleRawCharacteristic>;
39
+ protected getRawCharacteristic(uuid: string, query?: boolean): BleRawCharacteristic;
37
40
  logEvent(event: any): void;
38
41
  }
@@ -19,6 +19,7 @@ class BlePeripheral {
19
19
  this.characteristics = {};
20
20
  this.subscribed = [];
21
21
  this.disconnecting = false;
22
+ this.disconnectedSignalled = false;
22
23
  this.onErrorHandler = this.onPeripheralError.bind(this);
23
24
  this.ble = interface_1.BleInterface.getInstance();
24
25
  }
@@ -32,28 +33,42 @@ class BlePeripheral {
32
33
  return __awaiter(this, void 0, void 0, function* () {
33
34
  if (this.isConnected())
34
35
  return true;
35
- const peripheral = this.getPeripheral();
36
- yield peripheral.connectAsync();
37
- this.ble.registerConnected(this);
38
- peripheral.once('disconnect', () => { this.onPeripheralDisconnect(); });
39
- peripheral.on('error', this.onErrorHandler);
40
- this.connected = true;
36
+ if (this.connectPromise !== undefined) {
37
+ return this.connectPromise.then(() => this.connected);
38
+ }
39
+ this.connectPromise = new Promise((done) => {
40
+ const peripheral = this.getPeripheral();
41
+ this.logEvent({ message: 'connect peripheral', address: peripheral.address });
42
+ peripheral.connectAsync().then(() => {
43
+ this.ble.registerConnected(this, peripheral.id);
44
+ peripheral.once('disconnect', () => { this.onPeripheralDisconnect(); });
45
+ peripheral.on('error', this.onErrorHandler);
46
+ this.connected = true;
47
+ done();
48
+ });
49
+ });
50
+ yield this.connectPromise;
51
+ delete this.connectPromise;
41
52
  return this.connected;
42
53
  });
43
54
  }
44
55
  disconnect() {
45
56
  return __awaiter(this, arguments, void 0, function* (connectionLost = false) {
46
57
  this.disconnecting = true;
47
- if (!this.isConnected())
58
+ if (!this.isConnected()) {
48
59
  return true;
60
+ }
49
61
  yield this.unsubscribeAll(connectionLost);
50
62
  Object.keys(this.characteristics).forEach(uuid => {
51
63
  const c = this.characteristics[uuid];
52
64
  c.removeAllListeners();
53
65
  });
66
+ this.characteristics = {};
67
+ this.subscribed = [];
54
68
  const peripheral = this.getPeripheral();
55
69
  if (peripheral) {
56
70
  if (!connectionLost) {
71
+ this.logEvent({ message: 'disconnect peripheral', address: peripheral.address });
57
72
  if (!peripheral.disconnectAsync) {
58
73
  peripheral.disconnectAsync = () => {
59
74
  return new Promise((done) => { this.getPeripheral().disconnect(() => { done(); }); });
@@ -63,6 +78,7 @@ class BlePeripheral {
63
78
  }
64
79
  peripheral.removeAllListeners();
65
80
  }
81
+ this.ble.unregisterConnected(peripheral.id);
66
82
  this.connected = false;
67
83
  this.disconnecting = false;
68
84
  return !this.connected;
@@ -79,27 +95,35 @@ class BlePeripheral {
79
95
  }
80
96
  onPeripheralDisconnect() {
81
97
  return __awaiter(this, void 0, void 0, function* () {
82
- this.logEvent({ message: 'peripheral disconnected' });
98
+ var _a;
99
+ if (this.disconnectedSignalled || this.disconnecting)
100
+ return;
101
+ this.disconnectedSignalled = true;
102
+ this.logEvent({ message: 'peripheral disconnected', address: (_a = this.getPeripheral()) === null || _a === void 0 ? void 0 : _a.address });
83
103
  try {
84
104
  yield this.disconnect(true);
105
+ this.disconnectedSignalled = false;
85
106
  }
86
- catch (_a) { }
107
+ catch (_b) { }
87
108
  if (this.onDisconnectHandler)
88
109
  this.onDisconnectHandler();
89
110
  });
90
111
  }
91
112
  onPeripheralError(err) {
92
- this.logEvent({ message: 'peripheral error', error: err.message });
113
+ var _a;
114
+ this.logEvent({ message: 'peripheral error', address: (_a = this.getPeripheral()) === null || _a === void 0 ? void 0 : _a.address, error: err.message });
93
115
  }
94
116
  discoverServices() {
95
117
  return __awaiter(this, void 0, void 0, function* () {
118
+ if (!this.getPeripheral())
119
+ return [];
96
120
  if (this.getPeripheral().discoverServicesAsync) {
97
- this.logEvent({ message: 'discover services' });
121
+ this.logEvent({ message: 'discover services', address: this.getPeripheral().address });
98
122
  const services = yield this.getPeripheral().discoverServicesAsync([]);
99
123
  return services.map(s => s.uuid);
100
124
  }
101
125
  else {
102
- this.logEvent({ message: 'discover services and characteristics' });
126
+ this.logEvent({ message: 'discover services and characteristics', address: this.getPeripheral().address });
103
127
  const res = yield this.getPeripheral().discoverSomeServicesAndCharacteristicsAsync([], []);
104
128
  return res.services.map(s => s.uuid);
105
129
  }
@@ -107,6 +131,9 @@ class BlePeripheral {
107
131
  }
108
132
  discoverCharacteristics(serviceUUID) {
109
133
  return __awaiter(this, void 0, void 0, function* () {
134
+ if (!this.getPeripheral())
135
+ return [];
136
+ this.logEvent({ message: 'discover services and characteristics', service: serviceUUID, address: this.getPeripheral().address });
110
137
  const res = yield this.getPeripheral().discoverSomeServicesAndCharacteristicsAsync([serviceUUID], []);
111
138
  res.characteristics.forEach(c => this.characteristics[(0, utils_1.beautifyUUID)(c.uuid)] = c);
112
139
  return res.characteristics.map(c => {
@@ -120,20 +147,23 @@ class BlePeripheral {
120
147
  try {
121
148
  if (this.disconnecting || !this.connected)
122
149
  return false;
150
+ const uuid = (0, utils_1.beautifyUUID)(characteristicUUID);
123
151
  const onData = (data) => {
124
152
  try {
125
153
  callback(characteristicUUID, data);
126
154
  }
127
155
  catch (_a) { }
128
156
  };
129
- const subscription = this.subscribed.find(s => s.uuid === characteristicUUID);
157
+ const subscription = this.subscribed.find(s => s.uuid === uuid);
130
158
  if (subscription) {
131
159
  const c = this.getRawCharacteristic(characteristicUUID);
132
- if (c)
160
+ if (c) {
161
+ c.off('data', onData);
133
162
  c.on('data', onData);
163
+ }
134
164
  return true;
135
165
  }
136
- const c = this.getRawCharacteristic(characteristicUUID);
166
+ let c = yield this.queryRawCharacteristic(characteristicUUID);
137
167
  if (!c) {
138
168
  return false;
139
169
  }
@@ -142,22 +172,22 @@ class BlePeripheral {
142
172
  if (info) {
143
173
  return Promise.resolve(true);
144
174
  }
145
- const uuid = (0, utils_1.beautifyUUID)(characteristicUUID);
146
- this.logEvent({ message: 'subscribe request', characteristic: uuid, success: true });
175
+ this.logEvent({ message: 'subscribe request', address: this.getPeripheral().address, characteristic: uuid, success: true });
147
176
  c.subscribe((err) => {
148
177
  if (err) {
149
- this.logEvent({ message: 'subscribe result', characteristic: uuid, success: false, reason: err.message });
178
+ this.logEvent({ message: 'subscribe result', address: this.getPeripheral().address, characteristic: uuid, success: false, reason: err.message });
150
179
  resolve(false);
151
180
  }
152
181
  else {
153
182
  if (callback) {
154
- this.subscribed.push({ uuid: characteristicUUID, callback: onData });
183
+ this.subscribed.push({ uuid, callback: onData });
184
+ c.off('data', onData);
155
185
  c.on('data', onData);
156
186
  }
157
187
  else {
158
- this.subscribed.push({ uuid: characteristicUUID, callback: null });
188
+ this.subscribed.push({ uuid, callback: null });
159
189
  }
160
- this.logEvent({ message: 'subscribe result', characteristic: uuid, success: true });
190
+ this.logEvent({ message: 'subscribe result', address: this.getPeripheral().address, characteristic: uuid, success: true });
161
191
  resolve(true);
162
192
  }
163
193
  });
@@ -171,7 +201,8 @@ class BlePeripheral {
171
201
  }
172
202
  unsubscribe(characteristicUUID) {
173
203
  try {
174
- const subscription = this.subscribed.find(s => s.uuid === characteristicUUID);
204
+ const uuid = (0, utils_1.beautifyUUID)(characteristicUUID);
205
+ const subscription = this.subscribed.find(s => s.uuid === uuid);
175
206
  if (!subscription) {
176
207
  return Promise.resolve(true);
177
208
  }
@@ -185,7 +216,7 @@ class BlePeripheral {
185
216
  resolve(false);
186
217
  }
187
218
  else {
188
- const info = this.subscribed.find(s => s.uuid === characteristicUUID);
219
+ const info = this.subscribed.find(s => s.uuid === uuid);
189
220
  if (info) {
190
221
  this.subscribed.splice(this.subscribed.indexOf(info), 1);
191
222
  if (info.callback)
@@ -328,7 +359,24 @@ class BlePeripheral {
328
359
  });
329
360
  });
330
361
  }
331
- getRawCharacteristic(uuid) {
362
+ queryRawCharacteristic(uuid) {
363
+ return __awaiter(this, void 0, void 0, function* () {
364
+ const characteristicUUID = (0, utils_1.beautifyUUID)(uuid);
365
+ let c = this.characteristics[(0, utils_1.beautifyUUID)(uuid)];
366
+ if (c)
367
+ return c;
368
+ const res = yield this.getPeripheral().discoverSomeServicesAndCharacteristicsAsync([], [characteristicUUID]);
369
+ if (res.characteristics.length === 0) {
370
+ return;
371
+ }
372
+ c = res.characteristics.find(dc => (0, utils_1.beautifyUUID)(dc.uuid) === (0, utils_1.beautifyUUID)(characteristicUUID));
373
+ if (c) {
374
+ this.characteristics[characteristicUUID] = c;
375
+ }
376
+ return c;
377
+ });
378
+ }
379
+ getRawCharacteristic(uuid, query = false) {
332
380
  return this.characteristics[(0, utils_1.beautifyUUID)(uuid)];
333
381
  }
334
382
  logEvent(event) {
@@ -51,7 +51,7 @@ export default class TacxAdvancedFitnessMachineDevice extends BleFitnessMachineD
51
51
  private parseFERealSpeed;
52
52
  protected parseTrainerData(data: Buffer): BleFeBikeData;
53
53
  protected parseProductInformation(data: Buffer): BleFeBikeData;
54
- protected parseFECMessage(_data: Buffer): BleFeBikeData;
54
+ protected parseFECMessage(data: Buffer): BleFeBikeData;
55
55
  protected getChecksum(message: any[]): number;
56
56
  protected buildMessage(payload?: number[], msgID?: number): Buffer;
57
57
  protected sendMessage(message: Buffer): Promise<boolean>;
@@ -76,7 +76,7 @@ class TacxAdvancedFitnessMachineDevice extends sensor_1.default {
76
76
  return res;
77
77
  }
78
78
  catch (err) {
79
- this.logEvent({ message: 'error', fn: 'tacx.onData()', error: err.message || err, stack: err.stack, dataType: typeof (characteristicData) });
79
+ this.logEvent({ message: 'error', fn: 'tacx.onData()', error: err.message || err, stack: err.stack, dataType: typeof (characteristicData), characteristicData });
80
80
  }
81
81
  }
82
82
  isDuplicate(characteristic, data) {
@@ -401,8 +401,7 @@ class TacxAdvancedFitnessMachineDevice extends sensor_1.default {
401
401
  }
402
402
  return this.data;
403
403
  }
404
- parseFECMessage(_data) {
405
- const data = Buffer.from(_data);
404
+ parseFECMessage(data) {
406
405
  this.logEvent({ message: 'FE-C message', data: data.toString('hex') });
407
406
  const c = data.readUInt8(0);
408
407
  if (c !== consts_2.SYNC_BYTE) {
@@ -415,13 +414,13 @@ class TacxAdvancedFitnessMachineDevice extends sensor_1.default {
415
414
  try {
416
415
  switch (messageId) {
417
416
  case consts_2.ANTMessages.generalFE:
418
- res = this.parseGeneralFE(data.subarray(4, len + 3));
417
+ res = this.parseGeneralFE(Buffer.from(data.subarray(4, len + 3)));
419
418
  break;
420
419
  case consts_2.ANTMessages.trainerData:
421
- res = this.parseTrainerData(data.subarray(4, len + 3));
420
+ res = this.parseTrainerData(Buffer.from(data.subarray(4, len + 3)));
422
421
  break;
423
422
  case consts_2.ANTMessages.productInformation:
424
- res = this.parseProductInformation(data.subarray(4, len + 3));
423
+ res = this.parseProductInformation(Buffer.from(data.subarray(4, len + 3)));
425
424
  break;
426
425
  }
427
426
  if (res)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-devices",
3
- "version": "2.3.7",
3
+ "version": "2.3.9",
4
4
  "dependencies": {
5
5
  "@serialport/bindings-interface": "^1.2.2",
6
6
  "@serialport/parser-byte-length": "^9.0.1",