incyclist-devices 1.4.84 → 1.4.86

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.
@@ -202,6 +202,8 @@ class BleDevice extends ble_1.BleDeviceClass {
202
202
  this.peripheral = devices[0].peripheral;
203
203
  yield this.connectPeripheral(this.peripheral);
204
204
  this.logEvent({ message: 'connect result: success', mode: 'device', device: { id, name, address } });
205
+ this.connectState.isConnecting = false;
206
+ this.connectState.isConnected = true;
205
207
  return true;
206
208
  }
207
209
  }
@@ -395,6 +395,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
395
395
  this.scanState.isConnecting = true;
396
396
  const existing = this.devices.find(i => (!profile || i.device.getProfile() === profile) && (i.device.address === requested.address || i.device.id === requested.id || i.device.name === requested.name));
397
397
  if (existing) {
398
+ this.logEvent({ message: 'connect existing device' });
398
399
  yield existing.device.connect();
399
400
  this.scanState.isConnecting = false;
400
401
  return existing.device;
@@ -415,6 +416,9 @@ class BleInterface extends ble_1.BleInterfaceClass {
415
416
  }
416
417
  }
417
418
  }
419
+ const connectedDevice = this.devices.find(d => d.isConnected);
420
+ if (connectedDevice)
421
+ return connectedDevice.device;
418
422
  }
419
423
  let devices = [];
420
424
  let retry = false;
@@ -649,26 +653,26 @@ class BleInterface extends ble_1.BleInterfaceClass {
649
653
  });
650
654
  }
651
655
  stopScan() {
652
- if (!this.scanState.isScanning) {
653
- return Promise.resolve(true);
654
- }
655
- if (!this.getBinding())
656
- return Promise.reject(new Error('no binding defined'));
657
- this.getBinding().removeAllListeners('discover');
658
- const ongoing = this.peripheralCache.filter(i => i.state.isLoading);
659
- if (ongoing)
660
- ongoing.forEach(i => { i.isInterrupted = true; });
661
- this.logEvent({ message: 'scan stop request' });
662
- return new Promise(resolve => {
663
- this.getBinding().stopScanning(() => {
664
- this.scanState.isScanning = false;
665
- this.logEvent({ message: 'scan stop result: success' });
666
- resolve(true);
667
- });
656
+ return __awaiter(this, void 0, void 0, function* () {
657
+ this.logEvent({ message: 'scan stop request' });
658
+ if (!this.scanState.isScanning) {
659
+ this.logEvent({ message: 'scan stop result: not scanning' });
660
+ return true;
661
+ }
662
+ if (!this.getBinding())
663
+ throw new Error('no binding defined');
664
+ this.getBinding().removeAllListeners('discover');
665
+ const ongoing = this.peripheralCache.filter(i => i.state.isLoading);
666
+ if (ongoing)
667
+ ongoing.forEach(i => { i.isInterrupted = true; });
668
+ yield this.getBinding().stopScanning();
669
+ this.scanState.isScanning = false;
670
+ this.logEvent({ message: 'scan stop result: success' });
671
+ return true;
668
672
  });
669
673
  }
670
674
  isScanning() {
671
- return this.scanState.isScanning;
675
+ return this.scanState.isScanning === true;
672
676
  }
673
677
  addConnectedDevice(device) {
674
678
  const existigDevice = this.devices.find(i => i.device.id === device.id && i.device.getProfile() === device.getProfile());
@@ -70,9 +70,6 @@ class FtmsCyclingMode extends power_base_1.default {
70
70
  let power = bikeData.power || 0;
71
71
  const slope = (prevData.slope !== undefined ? prevData.slope : prevRequest.slope || 0);
72
72
  const distanceInternal = prevData.distanceInternal || 0;
73
- if (bikeData.pedalRpm === 0 || bikeData.isPedalling === false) {
74
- power = 0;
75
- }
76
73
  const m = this.getWeight();
77
74
  const t = this.getTimeSinceLastUpdate();
78
75
  const { speed, distance } = this.calculateSpeedAndDistance(power, slope, m, t, { bikeType });
@@ -9,3 +9,4 @@ export declare const CSP = "1818";
9
9
  export declare const CSP_MEASUREMENT = "2a63";
10
10
  export declare const CSP_FEATURE = "2a65";
11
11
  export declare const WAHOO_ADVANCED_TRAINER_CP = "a026e005";
12
+ export declare const WAHOO_ADVANCED_TRAINER_CP_FULL = "A026E005-0A7D-4AB3-97FA-F1500F9FEB8B";
package/lib/ble/consts.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WAHOO_ADVANCED_TRAINER_CP = exports.CSP_FEATURE = exports.CSP_MEASUREMENT = exports.CSP = exports.INDOOR_BIKE_DATA = exports.FTMS_STATUS = exports.FTMS_CP = exports.FTMS = exports.TACX_FE_C_TX = exports.TACX_FE_C_RX = exports.TACX_FE_C_BLE = void 0;
3
+ exports.WAHOO_ADVANCED_TRAINER_CP_FULL = exports.WAHOO_ADVANCED_TRAINER_CP = exports.CSP_FEATURE = exports.CSP_MEASUREMENT = exports.CSP = exports.INDOOR_BIKE_DATA = exports.FTMS_STATUS = exports.FTMS_CP = exports.FTMS = exports.TACX_FE_C_TX = exports.TACX_FE_C_RX = exports.TACX_FE_C_BLE = void 0;
4
4
  exports.TACX_FE_C_BLE = '6e40fec1';
5
5
  exports.TACX_FE_C_RX = '6e40fec2';
6
6
  exports.TACX_FE_C_TX = '6e40fec3';
@@ -12,3 +12,4 @@ exports.CSP = '1818';
12
12
  exports.CSP_MEASUREMENT = '2a63';
13
13
  exports.CSP_FEATURE = '2a65';
14
14
  exports.WAHOO_ADVANCED_TRAINER_CP = 'a026e005';
15
+ exports.WAHOO_ADVANCED_TRAINER_CP_FULL = 'A026E005-0A7D-4AB3-97FA-F1500F9FEB8B';
package/lib/ble/fm.js CHANGED
@@ -105,6 +105,7 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
105
105
  }
106
106
  subscribeWriteResponse(cuuid) {
107
107
  return __awaiter(this, void 0, void 0, function* () {
108
+ this.logEvent({ message: 'subscribe to CP response', characteristics: cuuid });
108
109
  const connector = this.ble.getConnector(this.peripheral);
109
110
  const isAlreadySubscribed = connector.isSubscribed(cuuid);
110
111
  if (!isAlreadySubscribed) {
@@ -610,7 +611,7 @@ class FmAdapter extends Device_1.default {
610
611
  }
611
612
  start(props) {
612
613
  return __awaiter(this, void 0, void 0, function* () {
613
- this.logger.logEvent({ message: 'start requested', profile: this.getProfile(), props });
614
+ this.logger.logEvent({ message: 'ftms: start requested', profile: this.getProfile(), props });
614
615
  if (this.ble.isScanning())
615
616
  yield this.ble.stopScan();
616
617
  try {
package/lib/ble/hrm.js CHANGED
@@ -102,7 +102,7 @@ class HrmAdapter extends Device_1.default {
102
102
  }
103
103
  start(props) {
104
104
  return __awaiter(this, void 0, void 0, function* () {
105
- this.logger.logEvent({ message: 'start requested', profile: this.getProfile(), props });
105
+ this.logger.logEvent({ message: 'hrm: start requested', profile: this.getProfile(), props });
106
106
  try {
107
107
  const bleDevice = yield this.ble.connectDevice(this.device);
108
108
  if (bleDevice) {
@@ -39,8 +39,8 @@ const ble_interface_1 = __importDefault(require("./ble-interface"));
39
39
  const fm_1 = __importStar(require("./fm"));
40
40
  const hrm_1 = __importStar(require("./hrm"));
41
41
  const pwr_1 = __importStar(require("./pwr"));
42
- const wahoo_kickr_1 = __importDefault(require("./wahoo-kickr"));
43
- const tacx_1 = __importDefault(require("./tacx"));
42
+ const wahoo_kickr_1 = __importStar(require("./wahoo-kickr"));
43
+ const tacx_1 = __importStar(require("./tacx"));
44
44
  class BleProtocol extends DeviceProtocol_1.default {
45
45
  constructor(binding) {
46
46
  super();
@@ -82,16 +82,19 @@ class BleProtocol extends DeviceProtocol_1.default {
82
82
  device = bleDevice;
83
83
  else {
84
84
  device = this.ble.findDeviceInCache(Object.assign(Object.assign({}, props()), { profile }));
85
- if (!device) {
86
- if (profile.toLowerCase() === 'wahoo smart trainer')
87
- device = new wahoo_kickr_1.default(props());
88
- else if (profile === tacx_1.default.PROFILE)
89
- device = new tacx_1.default(props());
90
- else
91
- device = new fm_1.default(props());
92
- }
93
85
  }
94
- return new fm_1.FmAdapter(device, this);
86
+ if (profile.toLowerCase() === 'wahoo smart trainer') {
87
+ device = device || new wahoo_kickr_1.default(props());
88
+ return new wahoo_kickr_1.WahooAdvancedFmAdapter(device, this);
89
+ }
90
+ else if (profile === tacx_1.default.PROFILE) {
91
+ device = device || new tacx_1.default(props());
92
+ return new tacx_1.TacxBleFEAdapter(device, this);
93
+ }
94
+ else {
95
+ device = device || new fm_1.default(props());
96
+ return new fm_1.FmAdapter(device, this);
97
+ }
95
98
  case 'cp':
96
99
  case 'power meter':
97
100
  return new pwr_1.PwrAdapter(fromDevice ? bleDevice : new pwr_1.default(props()), this);
package/lib/ble/pwr.js CHANGED
@@ -277,7 +277,7 @@ class PwrAdapter extends Device_1.default {
277
277
  this.userSettings = props.user;
278
278
  if (props && props.bikeSettings)
279
279
  this.bikeSettings = props.bikeSettings;
280
- this.logger.logEvent({ message: 'start requested', profile: this.getProfile(), props });
280
+ this.logger.logEvent({ message: 'csp: start requested', profile: this.getProfile(), props });
281
281
  try {
282
282
  const bleDevice = yield this.ble.connectDevice(this.device);
283
283
  if (bleDevice) {
package/lib/ble/tacx.js CHANGED
@@ -673,7 +673,7 @@ class TacxBleFEAdapter extends fm_1.FmAdapter {
673
673
  }
674
674
  start(props) {
675
675
  return __awaiter(this, void 0, void 0, function* () {
676
- this.logger.logEvent({ message: 'start requested', profile: this.getProfile(), props });
676
+ this.logger.logEvent({ message: 'tacx: start requested', profile: this.getProfile(), props });
677
677
  if (this.ble.isScanning())
678
678
  yield this.ble.stopScan();
679
679
  try {
@@ -36,6 +36,12 @@ export default class WahooAdvancedFitnessMachineDevice extends BleFitnessMachine
36
36
  tsPrevWrite: any;
37
37
  prevSlope: any;
38
38
  wahooCP: string;
39
+ isSimMode: boolean;
40
+ simModeSettings: {
41
+ weight: number;
42
+ crr: number;
43
+ cw: number;
44
+ };
39
45
  constructor(props?: any);
40
46
  isMatching(characteristics: string[]): boolean;
41
47
  init(): Promise<boolean>;
@@ -71,6 +71,11 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
71
71
  return __awaiter(this, void 0, void 0, function* () {
72
72
  try {
73
73
  yield this.subscribeWriteResponse(this.wahooCP);
74
+ try {
75
+ yield this.subscribeWriteResponse(consts_1.WAHOO_ADVANCED_TRAINER_CP_FULL.toLowerCase());
76
+ }
77
+ catch (err) {
78
+ }
74
79
  yield _super.initDevice.call(this);
75
80
  return true;
76
81
  }
@@ -81,6 +86,7 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
81
86
  });
82
87
  }
83
88
  setCharacteristicUUIDs(uuids) {
89
+ this.logEvent({ message: 'set uuids', uuids });
84
90
  uuids.forEach(c => {
85
91
  if ((0, ble_1.matches)(c, consts_1.WAHOO_ADVANCED_TRAINER_CP))
86
92
  this.wahooCP = c;
@@ -163,9 +169,7 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
163
169
  onData(characteristic, data) {
164
170
  super.onData(characteristic, data);
165
171
  const isDuplicate = this.checkForDuplicate(characteristic, data);
166
- if (isDuplicate)
167
- return;
168
- const uuid = characteristic.toLocaleLowerCase();
172
+ const uuid = characteristic.toLowerCase();
169
173
  let res = undefined;
170
174
  switch (uuid) {
171
175
  case '2a63':
@@ -181,6 +185,7 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
181
185
  res = this.parseFitnessMachineStatus(data);
182
186
  break;
183
187
  default:
188
+ this.logEvent({ message: 'data', uuid, data: data.toString('hex') });
184
189
  break;
185
190
  }
186
191
  if (res)
@@ -189,14 +194,13 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
189
194
  writeWahooFtmsMessage(requestedOpCode, data) {
190
195
  return __awaiter(this, void 0, void 0, function* () {
191
196
  try {
192
- this.logEvent({ message: 'wahoo cp:write', data: data.toString('hex') });
193
197
  const opcode = Buffer.alloc(1);
194
198
  opcode.writeUInt8(requestedOpCode, 0);
195
199
  const message = Buffer.concat([opcode, data]);
200
+ this.logEvent({ message: 'wahoo cp:write', data: message.toString('hex') });
196
201
  const res = yield this.write(this.wahooCP, message);
197
202
  const responseData = Buffer.from(res);
198
203
  const result = responseData.readUInt8(0);
199
- this.logEvent({ message: 'wahoo cp:response', opCode: requestedOpCode, response: responseData.toString('hex') });
200
204
  return result === 1;
201
205
  }
202
206
  catch (err) {
@@ -237,61 +241,118 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
237
241
  }
238
242
  setErgMode(power) {
239
243
  return __awaiter(this, void 0, void 0, function* () {
240
- if (this.isPowerAdjusting())
244
+ this.logger.logEvent({ message: 'setErgMode', power });
245
+ try {
246
+ if (this.isPowerAdjusting())
247
+ return false;
248
+ const data = Buffer.alloc(2);
249
+ data.writeInt16LE(Math.round(power), 0);
250
+ const res = yield this.writeWahooFtmsMessage(66, data);
251
+ if (res === true) {
252
+ this.setPowerAdjusting();
253
+ this.data.targetPower = power;
254
+ this.isSimMode = false;
255
+ this.simModeSettings = undefined;
256
+ }
257
+ return res;
258
+ }
259
+ catch (err) {
260
+ this.logEvent({ message: 'error', fn: 'setErgMode', error: err.message || err, stack: err.stack });
241
261
  return false;
242
- const data = Buffer.alloc(2);
243
- data.writeInt16LE(Math.round(power), 0);
244
- const res = yield this.writeWahooFtmsMessage(66, data);
245
- if (res === true) {
246
- this.setPowerAdjusting();
247
- this.data.targetPower = power;
248
262
  }
249
- return res;
250
263
  });
251
264
  }
252
265
  setSimMode(weight, crr, cw) {
253
266
  return __awaiter(this, void 0, void 0, function* () {
254
- const data = Buffer.alloc(6);
255
- data.writeInt16LE(Math.round(weight * 100), 0);
256
- data.writeInt16LE(Math.round(crr * 10000), 2);
257
- data.writeInt16LE(Math.round(cw * 1000), 4);
258
- const res = yield this.writeWahooFtmsMessage(67, data);
259
- return res;
267
+ this.logger.logEvent({ message: 'setSimMode', weight, crr, cw });
268
+ try {
269
+ if (this.isSimMode && this.simModeSettings) {
270
+ if (weight === this.simModeSettings.weight &&
271
+ crr === this.simModeSettings.crr &&
272
+ cw === this.simModeSettings.cw)
273
+ return true;
274
+ }
275
+ const hasControl = yield this.requestControl();
276
+ if (!hasControl) {
277
+ this.logEvent({ message: 'setSimMode failed', reason: 'control is disabled' });
278
+ return false;
279
+ }
280
+ const data = Buffer.alloc(6);
281
+ data.writeInt16LE(Math.round(weight * 100), 0);
282
+ data.writeInt16LE(Math.round(crr * 10000), 2);
283
+ data.writeInt16LE(Math.round(cw * 1000), 4);
284
+ const res = yield this.writeWahooFtmsMessage(67, data);
285
+ this.isSimMode = true;
286
+ this.simModeSettings = { weight, crr, cw };
287
+ return res;
288
+ }
289
+ catch (err) {
290
+ this.logEvent({ message: 'error', fn: 'setSimMode', error: err.message || err, stack: err.stack });
291
+ return false;
292
+ }
260
293
  });
261
294
  }
262
295
  setSimCRR(crr) {
263
296
  return __awaiter(this, void 0, void 0, function* () {
264
- const data = Buffer.alloc(2);
265
- data.writeInt16LE(Math.round(crr * 10000), 0);
266
- const res = yield this.writeWahooFtmsMessage(68, data);
267
- return res;
297
+ this.logger.logEvent({ message: 'setSimCRR', crr });
298
+ try {
299
+ const data = Buffer.alloc(2);
300
+ data.writeInt16LE(Math.round(crr * 10000), 0);
301
+ const res = yield this.writeWahooFtmsMessage(68, data);
302
+ return res;
303
+ }
304
+ catch (err) {
305
+ this.logEvent({ message: 'error', fn: 'setSimCRR', error: err.message || err, stack: err.stack });
306
+ return false;
307
+ }
268
308
  });
269
309
  }
270
310
  setSimWindResistance(cw) {
271
311
  return __awaiter(this, void 0, void 0, function* () {
272
- const data = Buffer.alloc(2);
273
- data.writeInt16LE(Math.round(cw * 1000), 0);
274
- const res = yield this.writeWahooFtmsMessage(69, data);
275
- return res;
312
+ this.logger.logEvent({ message: 'setSimWindResistance', cw });
313
+ try {
314
+ const data = Buffer.alloc(2);
315
+ data.writeInt16LE(Math.round(cw * 1000), 0);
316
+ const res = yield this.writeWahooFtmsMessage(69, data);
317
+ return res;
318
+ }
319
+ catch (err) {
320
+ this.logEvent({ message: 'error', fn: 'setSimWindResistance', error: err.message || err, stack: err.stack });
321
+ return false;
322
+ }
276
323
  });
277
324
  }
278
325
  setSimGrade(slope) {
279
326
  return __awaiter(this, void 0, void 0, function* () {
280
- const value = (Math.min(1, Math.max(-1, slope)) + 1.0) * 65535 / 2.0;
281
- const slopeVal = Math.floor(value);
282
- const data = Buffer.alloc(2);
283
- data.writeInt16LE(slopeVal, 0);
284
- const res = yield this.writeWahooFtmsMessage(70, data);
285
- return res;
327
+ this.logger.logEvent({ message: 'setSimGrade', slope });
328
+ try {
329
+ const value = (Math.min(1, Math.max(-1, slope)) + 1.0) * 65535 / 2.0;
330
+ const slopeVal = Math.floor(value);
331
+ const data = Buffer.alloc(2);
332
+ data.writeInt16LE(slopeVal, 0);
333
+ const res = yield this.writeWahooFtmsMessage(70, data);
334
+ return res;
335
+ }
336
+ catch (err) {
337
+ this.logEvent({ message: 'error', fn: 'setSimGrade', error: err.message || err, stack: err.stack });
338
+ return false;
339
+ }
286
340
  });
287
341
  }
288
342
  setSimWindSpeed(v) {
289
343
  return __awaiter(this, void 0, void 0, function* () {
290
- const value = (Math.max(-32.767, Math.min(32.767, v)) + 32.767) * 1000;
291
- const data = Buffer.alloc(2);
292
- data.writeInt16LE(Math.round(value), 0);
293
- const res = yield this.writeWahooFtmsMessage(71, data);
294
- return res;
344
+ this.logger.logEvent({ message: 'setSimWindSpeed', v });
345
+ try {
346
+ const value = (Math.max(-32.767, Math.min(32.767, v)) + 32.767) * 1000;
347
+ const data = Buffer.alloc(2);
348
+ data.writeInt16LE(Math.round(value), 0);
349
+ const res = yield this.writeWahooFtmsMessage(71, data);
350
+ return res;
351
+ }
352
+ catch (err) {
353
+ this.logEvent({ message: 'error', fn: 'setSimWindSpeed', error: err.message || err, stack: err.stack });
354
+ return false;
355
+ }
295
356
  });
296
357
  }
297
358
  setTargetPower(power) {
@@ -315,7 +376,7 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
315
376
  try {
316
377
  const hasControl = yield this.requestControl();
317
378
  if (!hasControl) {
318
- this.logEvent({ message: 'setTargetPower failed', reason: 'control is disabled' });
379
+ this.logEvent({ message: 'setSlope failed', reason: 'control is disabled' });
319
380
  return false;
320
381
  }
321
382
  const res = yield this.setSimGrade(slope);
@@ -331,6 +392,8 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
331
392
  }
332
393
  reset() {
333
394
  this.data = {};
395
+ this.isSimMode = undefined;
396
+ this.simModeSettings = undefined;
334
397
  }
335
398
  }
336
399
  exports.default = WahooAdvancedFitnessMachineDevice;
@@ -358,12 +421,14 @@ class WahooAdvancedFmAdapter extends fm_1.FmAdapter {
358
421
  }
359
422
  start(props) {
360
423
  return __awaiter(this, void 0, void 0, function* () {
361
- this.logger.logEvent({ message: 'start requested', profile: this.getProfile(), props });
362
- if (this.ble.isScanning())
363
- yield this.ble.stopScan();
424
+ this.logger.logEvent({ message: 'wahoo: start requested', profile: this.getProfile(), props, isScanning: this.ble.isScanning() });
364
425
  try {
426
+ this.logger.logEvent({ message: 'wahoo: stop previous scan', isScanning: this.ble.isScanning() });
427
+ if (this.ble.isScanning())
428
+ yield this.ble.stopScan();
429
+ this.logger.logEvent({ message: 'wahoo trying device connect' });
365
430
  const bleDevice = yield this.ble.connectDevice(this.device);
366
- bleDevice.setLogger(this.logger);
431
+ this.logger.logEvent({ message: 'wahoo device connected', connected: (bleDevice !== null && bleDevice !== undefined) });
367
432
  if (bleDevice) {
368
433
  this.device = bleDevice;
369
434
  const mode = this.getCyclingMode();
@@ -383,8 +448,8 @@ class WahooAdvancedFmAdapter extends fm_1.FmAdapter {
383
448
  }
384
449
  }
385
450
  const { user } = props || {};
386
- const weight = (user && user.weight ? user.weight : Device_1.DEFAULT_USER_WEIGHT) + Device_1.DEFAULT_BIKE_WEIGHT;
387
- this.device.setSimMode(weight, this.device.getCrr(), this.device.getCw());
451
+ const weight = (user && user.weight ? Number(user.weight) : Device_1.DEFAULT_USER_WEIGHT) + Device_1.DEFAULT_BIKE_WEIGHT;
452
+ yield this.device.setSimMode(weight, this.device.getCrr(), this.device.getCw());
388
453
  const startRequest = this.getCyclingMode().getBikeInitRequest();
389
454
  yield this.sendUpdate(startRequest);
390
455
  bleDevice.on('data', (data) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-devices",
3
- "version": "1.4.84",
3
+ "version": "1.4.86",
4
4
  "dependencies": {
5
5
  "@serialport/parser-byte-length": "^9.0.1",
6
6
  "@serialport/parser-delimiter": "^9.0.1",