incyclist-devices 2.3.0-beta.10 → 2.3.0-beta.12

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.
@@ -42,7 +42,7 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
42
42
  getBinding(): BleBinding;
43
43
  protected autoConnect(): void;
44
44
  connect(reconnect?: boolean): Promise<boolean>;
45
- disconnect(cleanup?: boolean): Promise<boolean>;
45
+ disconnect(connectionLost?: boolean): Promise<boolean>;
46
46
  isConnected(): boolean;
47
47
  registerConnected(peripheral: IBlePeripheral): void;
48
48
  protected isConnecting(): boolean;
@@ -59,6 +59,8 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
59
59
  protected reconnect(): Promise<void>;
60
60
  protected startPeripheralScan(retry?: boolean): Promise<void>;
61
61
  protected stopPeripheralScan(): Promise<void>;
62
+ protected emitDisconnectAllPeripherals(): void;
63
+ protected disconnectAllPeripherals(): Promise<void>;
62
64
  protected isDiscovering(): boolean;
63
65
  protected discoverPeripherals(): Promise<void>;
64
66
  protected onPeripheralFound(peripheral: BleRawPeripheral): void;
@@ -110,21 +110,24 @@ class BleInterface extends events_1.default {
110
110
  return success;
111
111
  });
112
112
  }
113
- disconnect(cleanup) {
113
+ disconnect(connectionLost) {
114
114
  return __awaiter(this, void 0, void 0, function* () {
115
115
  var _a;
116
116
  if (!this.getBinding()) {
117
117
  return false;
118
118
  }
119
- if (!this.isConnected() && !cleanup)
119
+ if (!this.isConnected() && !connectionLost)
120
120
  return true;
121
- if (!cleanup)
121
+ if (!connectionLost)
122
122
  this.logEvent({ message: 'disconnect request' });
123
123
  this.emit('disconnect-request');
124
124
  yield this.stopPeripheralScan();
125
- const promises = this.connectedPeripherals.map(p => p.disconnect());
126
- yield Promise.allSettled(promises);
127
- this.connectedPeripherals = [];
125
+ if (connectionLost) {
126
+ this.emitDisconnectAllPeripherals();
127
+ }
128
+ else {
129
+ yield this.disconnectAllPeripherals();
130
+ }
128
131
  if (this.isConnecting())
129
132
  yield ((_a = this.connectTask) === null || _a === void 0 ? void 0 : _a.stop());
130
133
  this.getBinding().removeAllListeners();
@@ -274,6 +277,20 @@ class BleInterface extends events_1.default {
274
277
  });
275
278
  });
276
279
  }
280
+ emitDisconnectAllPeripherals() {
281
+ this.connectedPeripherals.forEach(p => {
282
+ const peripheral = p.getPeripheral();
283
+ peripheral.emit('disconnect');
284
+ });
285
+ this.connectedPeripherals = [];
286
+ }
287
+ disconnectAllPeripherals() {
288
+ return __awaiter(this, void 0, void 0, function* () {
289
+ const promises = this.connectedPeripherals.map(p => p.disconnect());
290
+ yield Promise.allSettled(promises);
291
+ this.connectedPeripherals = [];
292
+ });
293
+ }
277
294
  isDiscovering() {
278
295
  var _a;
279
296
  return ((_a = this.discoverTask) === null || _a === void 0 ? void 0 : _a.isRunning()) === true;
@@ -369,11 +386,11 @@ class BleInterface extends events_1.default {
369
386
  try {
370
387
  peripheral.on('error', (err) => {
371
388
  peripheral.removeAllListeners();
372
- this.logEvent({ message: 'Device error', error: err.message });
389
+ this.logEvent({ message: 'peripheral error', error: err.message });
373
390
  });
374
391
  peripheral.on('disconnect', () => {
375
392
  peripheral.removeAllListeners();
376
- this.logEvent({ message: 'Device disconnected' });
393
+ this.logEvent({ message: 'peripheral disconnected' });
377
394
  });
378
395
  yield peripheral.connectAsync();
379
396
  if (peripheral.discoverServicesAsync !== undefined) {
@@ -11,14 +11,17 @@ export declare class BlePeripheral implements IBlePeripheral {
11
11
  callback: (data: Buffer) => void;
12
12
  }>;
13
13
  protected disconnecting: boolean;
14
+ protected onErrorHandler: any;
14
15
  constructor(announcement: BlePeripheralAnnouncement);
15
16
  get services(): BleService[];
16
- protected getPeripheral(): BleRawPeripheral;
17
+ getPeripheral(): BleRawPeripheral;
17
18
  connect(): Promise<boolean>;
18
- disconnect(): Promise<boolean>;
19
+ disconnect(connectionLost?: boolean): Promise<boolean>;
19
20
  isConnected(): boolean;
20
21
  isConnecting(): boolean;
21
22
  onDisconnect(callback: () => void): void;
23
+ protected onPeripheralDisconnect(): Promise<void>;
24
+ protected onPeripheralError(err: Error): void;
22
25
  discoverServices(): Promise<string[]>;
23
26
  discoverCharacteristics(serviceUUID: string): Promise<BleCharacteristic[]>;
24
27
  subscribe(characteristicUUID: string, callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
@@ -27,7 +30,7 @@ export declare class BlePeripheral implements IBlePeripheral {
27
30
  discoverAllCharacteristics(): Promise<string[]>;
28
31
  discoverSomeCharacteristics(characteristics: string[]): Promise<string[]>;
29
32
  subscribeAll(callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
30
- unsubscribeAll(): Promise<boolean>;
33
+ unsubscribeAll(connectionLost?: boolean): Promise<void>;
31
34
  read(characteristicUUID: string): Promise<Buffer>;
32
35
  write(characteristicUUID: string, data: Buffer, options?: BleWriteProps): Promise<Buffer>;
33
36
  protected getRawCharacteristic(uuid: string): BleRawCharacteristic;
@@ -19,6 +19,7 @@ class BlePeripheral {
19
19
  this.characteristics = {};
20
20
  this.subscribed = [];
21
21
  this.disconnecting = false;
22
+ this.onErrorHandler = this.onPeripheralError.bind(this);
22
23
  this.ble = interface_1.BleInterface.getInstance();
23
24
  }
24
25
  get services() {
@@ -31,28 +32,37 @@ class BlePeripheral {
31
32
  return __awaiter(this, void 0, void 0, function* () {
32
33
  if (this.isConnected())
33
34
  return true;
34
- yield this.getPeripheral().connectAsync();
35
+ const peripheral = this.getPeripheral();
36
+ yield peripheral.connectAsync();
35
37
  this.ble.registerConnected(this);
38
+ peripheral.once('disconnect', () => { this.onPeripheralDisconnect(); });
39
+ peripheral.on('error', this.onErrorHandler);
36
40
  this.connected = true;
37
41
  return this.connected;
38
42
  });
39
43
  }
40
44
  disconnect() {
41
- return __awaiter(this, void 0, void 0, function* () {
45
+ return __awaiter(this, arguments, void 0, function* (connectionLost = false) {
42
46
  this.disconnecting = true;
43
47
  if (!this.isConnected())
44
48
  return true;
45
- yield this.unsubscribeAll();
49
+ yield this.unsubscribeAll(connectionLost);
46
50
  Object.keys(this.characteristics).forEach(uuid => {
47
51
  const c = this.characteristics[uuid];
48
52
  c.removeAllListeners();
49
53
  });
50
- if (!this.getPeripheral().disconnectAsync) {
51
- this.getPeripheral().disconnectAsync = () => {
52
- return new Promise((done) => { this.getPeripheral().disconnect(() => { done(); }); });
53
- };
54
+ const peripheral = this.getPeripheral();
55
+ if (peripheral) {
56
+ if (!connectionLost) {
57
+ if (!peripheral.disconnectAsync) {
58
+ peripheral.disconnectAsync = () => {
59
+ return new Promise((done) => { this.getPeripheral().disconnect(() => { done(); }); });
60
+ };
61
+ }
62
+ yield this.getPeripheral().disconnectAsync();
63
+ }
64
+ peripheral.removeAllListeners();
54
65
  }
55
- yield this.getPeripheral().disconnectAsync();
56
66
  this.connected = false;
57
67
  this.disconnecting = false;
58
68
  return !this.connected;
@@ -67,6 +77,20 @@ class BlePeripheral {
67
77
  onDisconnect(callback) {
68
78
  this.onDisconnectHandler = callback;
69
79
  }
80
+ onPeripheralDisconnect() {
81
+ return __awaiter(this, void 0, void 0, function* () {
82
+ this.logEvent({ message: 'disconnect' });
83
+ try {
84
+ yield this.disconnect(true);
85
+ }
86
+ catch (_a) { }
87
+ if (this.onDisconnectHandler)
88
+ this.onDisconnectHandler();
89
+ });
90
+ }
91
+ onPeripheralError(err) {
92
+ this.logEvent({ message: 'peripheral error', error: err.message });
93
+ }
70
94
  discoverServices() {
71
95
  return __awaiter(this, void 0, void 0, function* () {
72
96
  if (this.getPeripheral().discoverServicesAsync) {
@@ -184,16 +208,16 @@ class BlePeripheral {
184
208
  yield this.discoverAllCharacteristics();
185
209
  }
186
210
  const retry = [];
187
- for (let i = 0; i < characteristics.length; i++) {
188
- const c = this.getRawCharacteristic(characteristics[i]);
211
+ for (const element of characteristics) {
212
+ const c = this.getRawCharacteristic(element);
189
213
  if (c === null || c === void 0 ? void 0 : c.properties.includes('notify')) {
190
214
  const success = yield this.subscribe(c.uuid, callback);
191
215
  if (!success)
192
216
  retry.push(c);
193
217
  }
194
218
  }
195
- for (let i = 0; i < retry.length; i++) {
196
- const c = retry[i];
219
+ for (const element of retry) {
220
+ const c = element;
197
221
  yield this.subscribe(c.uuid, callback);
198
222
  }
199
223
  return true;
@@ -247,13 +271,16 @@ class BlePeripheral {
247
271
  });
248
272
  }
249
273
  unsubscribeAll() {
250
- return __awaiter(this, void 0, void 0, function* () {
274
+ return __awaiter(this, arguments, void 0, function* (connectionLost = false) {
275
+ if (connectionLost) {
276
+ this.subscribed = [];
277
+ return;
278
+ }
251
279
  const promises = [];
252
280
  this.subscribed.forEach(d => {
253
281
  promises.push(this.unsubscribe(d.uuid));
254
282
  });
255
283
  yield Promise.allSettled(promises);
256
- return true;
257
284
  });
258
285
  }
259
286
  read(characteristicUUID) {
@@ -305,6 +332,8 @@ class BlePeripheral {
305
332
  return this.characteristics[(0, utils_1.beautifyUUID)(uuid)];
306
333
  }
307
334
  logEvent(event) {
335
+ var _a;
336
+ event.peripheral = (_a = this.announcement) === null || _a === void 0 ? void 0 : _a.name;
308
337
  this.ble.logEvent(event);
309
338
  }
310
339
  }
@@ -101,11 +101,19 @@ class TBleSensor extends events_1.default {
101
101
  }
102
102
  reconnectSensor() {
103
103
  return __awaiter(this, void 0, void 0, function* () {
104
+ let connected = false;
105
+ let subscribed = false;
104
106
  let success = false;
105
107
  do {
106
- success = yield this.startSensor(true);
108
+ if (!connected) {
109
+ connected = yield this.startSensor(true);
110
+ }
111
+ if (connected && !subscribed) {
112
+ subscribed = yield this.subscribe();
113
+ }
114
+ success = connected && subscribed;
107
115
  if (!success) {
108
- yield (0, utils_1.sleep)(5000);
116
+ yield (0, utils_1.sleep)(1000);
109
117
  }
110
118
  } while (!success || this.stopRequested);
111
119
  });
@@ -119,10 +127,16 @@ class TBleSensor extends events_1.default {
119
127
  }
120
128
  read(characteristicUUID) {
121
129
  var _a;
130
+ if (!this.isConnected()) {
131
+ return Promise.reject(new Error('not connected'));
132
+ }
122
133
  return (_a = this.peripheral) === null || _a === void 0 ? void 0 : _a.read(characteristicUUID);
123
134
  }
124
135
  write(characteristicUUID, data, options) {
125
136
  var _a;
137
+ if (!this.isConnected()) {
138
+ return Promise.reject(new Error('not connected'));
139
+ }
126
140
  return (_a = this.peripheral) === null || _a === void 0 ? void 0 : _a.write(characteristicUUID, data, options);
127
141
  }
128
142
  onData(characteristic, data) {
@@ -100,8 +100,6 @@ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
100
100
  this.logEvent({ message: 'setTargetPower', power, skip: (this.data.targetPower !== undefined && this.data.targetPower === power) });
101
101
  if (this.data.targetPower !== undefined && this.data.targetPower === power)
102
102
  return true;
103
- if (!this.hasControl)
104
- return;
105
103
  const hasControl = yield this.requestControl();
106
104
  if (!hasControl) {
107
105
  this.logEvent({ message: 'setTargetPower failed', reason: 'control is disabled' });
@@ -111,15 +109,15 @@ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
111
109
  data.writeUInt8(5, 0);
112
110
  data.writeInt16LE(Math.round(power), 1);
113
111
  const res = yield this.writeFtmsMessage(5, data);
112
+ if (res === 5) {
113
+ this.hasControl = false;
114
+ }
114
115
  return (res === 1);
115
116
  });
116
117
  }
117
118
  setSlope(slope) {
118
119
  return __awaiter(this, void 0, void 0, function* () {
119
120
  this.logEvent({ message: 'setSlope', slope });
120
- const hasControl = yield this.requestControl();
121
- if (!hasControl)
122
- return;
123
121
  const { windSpeed, crr, cw } = this;
124
122
  return yield this.setIndoorBikeSimulation(windSpeed, slope, crr, cw);
125
123
  });
@@ -331,6 +329,9 @@ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
331
329
  data.writeUInt8(Math.round(crr * 10000), 5);
332
330
  data.writeUInt8(Math.round(cw * 100), 6);
333
331
  const res = yield this.writeFtmsMessage(17, data);
332
+ if (res === 5) {
333
+ this.hasControl = false;
334
+ }
334
335
  return (res === 1);
335
336
  });
336
337
  }
@@ -452,8 +452,14 @@ class TacxAdvancedFitnessMachineDevice extends sensor_1.default {
452
452
  sendMessage(message) {
453
453
  return __awaiter(this, void 0, void 0, function* () {
454
454
  this.logEvent({ message: 'write', characteristic: this.tacxTx, data: message.toString('hex') });
455
- yield this.write(this.tacxTx, message, { withoutResponse: true });
456
- return true;
455
+ try {
456
+ yield this.write(this.tacxTx, message, { withoutResponse: true });
457
+ return true;
458
+ }
459
+ catch (err) {
460
+ this.logEvent({ message: 'write failed', characteristic: this.tacxTx, reason: err.message });
461
+ return false;
462
+ }
457
463
  });
458
464
  }
459
465
  sendUserConfiguration(userWeight, bikeWeight, wheelDiameter, gearRatio) {
@@ -21,7 +21,7 @@ export declare class DirectConnectPeripheral implements IBlePeripheral {
21
21
  constructor(announcement: MulticastDnsAnnouncement);
22
22
  get services(): BleService[];
23
23
  connect(): Promise<boolean>;
24
- disconnect(): Promise<boolean>;
24
+ disconnect(connectionLost?: boolean): Promise<boolean>;
25
25
  isConnected(): boolean;
26
26
  isConnecting(): boolean;
27
27
  onDisconnect(callback: () => void): void;
@@ -31,14 +31,14 @@ export declare class DirectConnectPeripheral implements IBlePeripheral {
31
31
  unsubscribe(characteristicUUID: string): Promise<boolean>;
32
32
  subscribeAll(callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
33
33
  subscribeSelected(characteristics: string[], callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
34
- unsubscribeAll(): Promise<boolean>;
34
+ unsubscribeAll(connectionLost?: boolean): Promise<void>;
35
35
  read(characteristicUUID: string): Promise<Buffer>;
36
36
  write(characteristicUUID: string, data: Buffer, options?: BleWriteProps): Promise<Buffer>;
37
37
  protected startConnection(): Promise<boolean>;
38
38
  protected onPortError(err: Error): void;
39
39
  protected onPortClose(): Promise<void>;
40
40
  protected getPath(): string;
41
- protected stopConnection(): Promise<boolean>;
41
+ protected stopConnection(connectionLost?: boolean): Promise<boolean>;
42
42
  protected getNextSeqNo(): number;
43
43
  protected send(seqNo: number, data: Buffer): Promise<Buffer>;
44
44
  protected getNextMessage(data: Buffer): Buffer;
@@ -55,10 +55,10 @@ class DirectConnectPeripheral {
55
55
  });
56
56
  }
57
57
  disconnect() {
58
- return __awaiter(this, void 0, void 0, function* () {
58
+ return __awaiter(this, arguments, void 0, function* (connectionLost = false) {
59
59
  try {
60
60
  yield this.connectTask.stop();
61
- yield this.stopConnection();
61
+ yield this.stopConnection(connectionLost);
62
62
  delete this.socket;
63
63
  }
64
64
  catch (err) {
@@ -285,13 +285,16 @@ class DirectConnectPeripheral {
285
285
  });
286
286
  }
287
287
  unsubscribeAll() {
288
- return __awaiter(this, void 0, void 0, function* () {
288
+ return __awaiter(this, arguments, void 0, function* (connectionLost = false) {
289
+ if (connectionLost) {
290
+ this.subscribed = [];
291
+ return;
292
+ }
289
293
  const promises = [];
290
294
  this.subscribed.forEach(characteristicUUID => {
291
295
  promises.push(this.unsubscribe((0, utils_1.parseUUID)(characteristicUUID)));
292
296
  });
293
297
  yield Promise.allSettled(promises);
294
- return true;
295
298
  });
296
299
  }
297
300
  read(characteristicUUID) {
@@ -397,9 +400,10 @@ class DirectConnectPeripheral {
397
400
  onPortClose() {
398
401
  return __awaiter(this, void 0, void 0, function* () {
399
402
  this.socket.removeAllListeners();
403
+ this.socket.on('error', () => { });
400
404
  this.logEvent({ message: 'port closed', path: this.getPath() });
401
405
  try {
402
- yield this.disconnect();
406
+ yield this.disconnect(true);
403
407
  }
404
408
  catch (_a) { }
405
409
  if (this.onDisconnectHandler)
@@ -412,11 +416,11 @@ class DirectConnectPeripheral {
412
416
  return path;
413
417
  }
414
418
  stopConnection() {
415
- return __awaiter(this, void 0, void 0, function* () {
419
+ return __awaiter(this, arguments, void 0, function* (connectionLost = false) {
416
420
  this.eventEmitter.removeAllListeners();
417
421
  if (!this.isConnected())
418
422
  return true;
419
- yield this.unsubscribeAll();
423
+ yield this.unsubscribeAll(connectionLost);
420
424
  this.socket.removeAllListeners();
421
425
  return new Promise(done => {
422
426
  const onClosed = () => {
@@ -3,8 +3,8 @@ import SmartTrainerCyclingMode from "./antble-smarttrainer";
3
3
  import { UpdateRequest } from "./types";
4
4
  export default class AntAdvSimCyclingMode extends SmartTrainerCyclingMode {
5
5
  constructor(adapter: IncyclistDeviceAdapter, props?: any);
6
- getName(): string;
7
6
  getDescription(): string;
7
+ getConfig(): import("./types").CyclingModeConfig;
8
8
  checkForResetOrEmpty(request: UpdateRequest): UpdateRequest | undefined;
9
9
  protected checkForTempPowerAdjustments(request: UpdateRequest, newRequest?: UpdateRequest): void;
10
10
  protected checkEmptyRequest(newRequest: UpdateRequest): void;
@@ -10,12 +10,14 @@ class AntAdvSimCyclingMode extends antble_smarttrainer_1.default {
10
10
  super(adapter, props);
11
11
  this.initLogger('AdvmartTrainerMode');
12
12
  }
13
- getName() {
14
- return 'Advanced Smart Trainer';
15
- }
16
13
  getDescription() {
17
14
  return 'Sends Slope to device. Respects Limits (from workout or settings). Calculates speed based on power and slope. ';
18
15
  }
16
+ getConfig() {
17
+ const config = super.getConfig();
18
+ config.name = 'Advanced Smart Trainer';
19
+ return config;
20
+ }
19
21
  checkForResetOrEmpty(request) {
20
22
  if (!request || request.reset) {
21
23
  this.prevRequest = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-devices",
3
- "version": "2.3.0-beta.10",
3
+ "version": "2.3.0-beta.12",
4
4
  "dependencies": {
5
5
  "@serialport/bindings-interface": "^1.2.2",
6
6
  "@serialport/parser-byte-length": "^9.0.1",