incyclist-devices 1.4.88 → 1.4.90

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.
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { EventLogger } from "gd-eventlog";
3
- import { BleInterfaceClass, BleDeviceClass, BlePeripheral, BleDeviceProps, ConnectProps, BleDeviceInfo } from "./ble";
3
+ import { BleInterfaceClass, BleDeviceClass, BlePeripheral, BleDeviceProps, ConnectProps, BleDeviceInfo, BleWriteProps } from "./ble";
4
4
  import BlePeripheralConnector from "./ble-peripheral";
5
5
  interface BleDeviceConstructProps extends BleDeviceProps {
6
6
  log?: boolean;
@@ -55,7 +55,7 @@ export declare abstract class BleDevice extends BleDeviceClass {
55
55
  timeoutCheck(): void;
56
56
  startWorker(): void;
57
57
  stopWorker(): void;
58
- write(characteristicUuid: string, data: Buffer, withoutResponse?: boolean): Promise<ArrayBuffer>;
58
+ write(characteristicUuid: string, data: Buffer, props?: BleWriteProps): Promise<ArrayBuffer>;
59
59
  read(characteristicUuid: string): Promise<Uint8Array>;
60
60
  getDeviceInfo(): Promise<BleDeviceInfo>;
61
61
  }
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.BleDevice = void 0;
13
13
  const gd_eventlog_1 = require("gd-eventlog");
14
14
  const ble_1 = require("./ble");
15
+ const ble_2 = require("./ble");
15
16
  const CONNECT_WAIT_TIMEOUT = 10000;
16
17
  const BLE_TIMEOUT = 1000;
17
18
  class BleDevice extends ble_1.BleDeviceClass {
@@ -273,8 +274,13 @@ class BleDevice extends ble_1.BleDeviceClass {
273
274
  return false;
274
275
  }
275
276
  onData(characteristic, data) {
277
+ const isDuplicate = this.checkForDuplicate(characteristic, data);
278
+ if (isDuplicate) {
279
+ return;
280
+ }
281
+ this.logEvent({ message: 'got data', characteristic, data: data.toString('hex'), writeQueue: this.writeQueue.length });
276
282
  if (this.writeQueue.length > 0) {
277
- const writeIdx = this.writeQueue.findIndex(i => i.uuid === characteristic.toLocaleLowerCase());
283
+ const writeIdx = this.writeQueue.findIndex(i => (0, ble_2.matches)(i.uuid, characteristic));
278
284
  if (writeIdx !== -1) {
279
285
  const writeItem = this.writeQueue[writeIdx];
280
286
  this.writeQueue.splice(writeIdx, 1);
@@ -312,9 +318,10 @@ class BleDevice extends ble_1.BleDeviceClass {
312
318
  clearInterval(this.workerIv);
313
319
  this.workerIv = null;
314
320
  }
315
- write(characteristicUuid, data, withoutResponse = false) {
321
+ write(characteristicUuid, data, props) {
316
322
  return __awaiter(this, void 0, void 0, function* () {
317
323
  try {
324
+ const { withoutResponse, timeout } = props || {};
318
325
  const connector = this.ble.getConnector(this.peripheral);
319
326
  const isAlreadySubscribed = connector.isSubscribed(characteristicUuid);
320
327
  if (!withoutResponse && !this.workerIv) {
@@ -345,7 +352,8 @@ class BleDevice extends ble_1.BleDeviceClass {
345
352
  else {
346
353
  const writeId = this.writeQueue.length;
347
354
  let messageDeleted = false;
348
- this.writeQueue.push({ uuid: characteristicUuid.toLocaleLowerCase(), data, timeout: Date.now() + BLE_TIMEOUT, resolve, reject });
355
+ const writeTimeout = timeout !== undefined ? timeout : BLE_TIMEOUT;
356
+ this.writeQueue.push({ uuid: characteristicUuid.toLocaleLowerCase(), data, timeout: Date.now() + writeTimeout, resolve, reject });
349
357
  const to = setTimeout(() => {
350
358
  if (this.writeQueue.length > writeId && !messageDeleted)
351
359
  this.writeQueue.splice(writeId, 1);
@@ -100,9 +100,6 @@ class BleERGCyclingMode extends power_base_1.default {
100
100
  let power = bikeData.power || 0;
101
101
  const slope = (prevData.slope !== undefined ? prevData.slope : prevRequest.slope || 0);
102
102
  const distanceInternal = prevData.distanceInternal || 0;
103
- if (bikeData.pedalRpm === 0 || bikeData.isPedalling === false) {
104
- power = 0;
105
- }
106
103
  const m = this.getWeight();
107
104
  const t = this.getTimeSinceLastUpdate();
108
105
  const { speed, distance } = this.calculateSpeedAndDistance(power, slope, m, t, { bikeType });
package/lib/ble/ble.d.ts CHANGED
@@ -44,6 +44,10 @@ export declare abstract class BleDeviceClass extends EventEmitter {
44
44
  abstract getDeviceInfo(): Promise<BleDeviceInfo>;
45
45
  setCharacteristicUUIDs(uuids: string[]): void;
46
46
  }
47
+ export interface BleWriteProps {
48
+ withoutResponse?: boolean;
49
+ timeout?: number;
50
+ }
47
51
  export interface BleBinding extends EventEmitter {
48
52
  startScanning(serviceUUIDs?: string[], allowDuplicates?: boolean, callback?: (error?: Error) => void): void;
49
53
  stopScanning(callback?: () => void): void;
package/lib/ble/fm.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  import { BleDevice } from './ble-device';
3
3
  import BleInterface from './ble-interface';
4
4
  import BleProtocol from './incyclist-protocol';
5
- import { BleDeviceClass } from './ble';
5
+ import { BleDeviceClass, BleWriteProps } from './ble';
6
6
  import DeviceAdapter, { DeviceData } from '../Device';
7
7
  import { DeviceProtocol } from '../DeviceProtocol';
8
8
  import { EventLogger } from 'gd-eventlog';
@@ -72,7 +72,7 @@ export default class BleFitnessMachineDevice extends BleDevice {
72
72
  parseFitnessMachineStatus(_data: Uint8Array): IndoorBikeData;
73
73
  getFitnessMachineFeatures(): Promise<IndoorBikeFeatures>;
74
74
  onData(characteristic: string, data: Buffer): void;
75
- writeFtmsMessage(requestedOpCode: any, data: any): Promise<number>;
75
+ writeFtmsMessage(requestedOpCode: any, data: any, props?: BleWriteProps): Promise<number>;
76
76
  requestControl(): Promise<boolean>;
77
77
  setTargetPower(power: number): Promise<boolean>;
78
78
  setSlope(slope: any): Promise<boolean>;
package/lib/ble/fm.js CHANGED
@@ -307,9 +307,6 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
307
307
  }
308
308
  onData(characteristic, data) {
309
309
  super.onData(characteristic, data);
310
- const isDuplicate = this.checkForDuplicate(characteristic, data);
311
- if (isDuplicate)
312
- return;
313
310
  const uuid = characteristic.toLocaleLowerCase();
314
311
  let res = undefined;
315
312
  switch (uuid) {
@@ -332,11 +329,11 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
332
329
  if (res)
333
330
  this.emit('data', res);
334
331
  }
335
- writeFtmsMessage(requestedOpCode, data) {
332
+ writeFtmsMessage(requestedOpCode, data, props) {
336
333
  return __awaiter(this, void 0, void 0, function* () {
337
334
  try {
338
335
  this.logEvent({ message: 'fmts:write', data: data.toString('hex') });
339
- const res = yield this.write(consts_1.FTMS_CP, data);
336
+ const res = yield this.write(consts_1.FTMS_CP, data, props);
340
337
  const responseData = Buffer.from(res);
341
338
  const opCode = responseData.readUInt8(0);
342
339
  const request = responseData.readUInt8(1);
@@ -364,7 +361,7 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
364
361
  this.isCheckingControl = true;
365
362
  const data = Buffer.alloc(1);
366
363
  data.writeUInt8(0, 0);
367
- const res = yield this.writeFtmsMessage(0, data);
364
+ const res = yield this.writeFtmsMessage(0, data, { timeout: 5000 });
368
365
  if (res === 1) {
369
366
  this.hasControl = true;
370
367
  }
package/lib/ble/tacx.js CHANGED
@@ -496,7 +496,7 @@ class TacxAdvancedFitnessMachineDevice extends fm_1.default {
496
496
  }
497
497
  sendMessage(message) {
498
498
  return __awaiter(this, void 0, void 0, function* () {
499
- yield this.write(this.tacxTx, message, true);
499
+ yield this.write(this.tacxTx, message, { withoutResponse: true });
500
500
  return true;
501
501
  });
502
502
  }
@@ -1,8 +1,20 @@
1
1
  /// <reference types="node" />
2
2
  import BleProtocol from './incyclist-protocol';
3
- import { BleDeviceClass } from './ble';
3
+ import { BleDeviceClass, BleWriteProps } from './ble';
4
4
  import DeviceAdapter from '../Device';
5
5
  import BleFitnessMachineDevice, { FmAdapter } from './fm';
6
+ export declare const enum OpCode {
7
+ unlock = 32,
8
+ setResistanceMode = 64,
9
+ setStandardMode = 65,
10
+ setErgMode = 66,
11
+ setSimMode = 67,
12
+ setSimCRR = 68,
13
+ setSimWindResistance = 69,
14
+ setSimGrade = 70,
15
+ setSimWindSpeed = 71,
16
+ setWheelCircumference = 72
17
+ }
6
18
  declare type IndoorBikeData = {
7
19
  speed?: number;
8
20
  averageSpeed?: number;
@@ -37,6 +49,7 @@ export default class WahooAdvancedFitnessMachineDevice extends BleFitnessMachine
37
49
  prevSlope: any;
38
50
  wahooCP: string;
39
51
  isSimMode: boolean;
52
+ isRequestControlBusy: boolean;
40
53
  weight: number;
41
54
  simModeSettings: {
42
55
  weight: number;
@@ -58,7 +71,7 @@ export default class WahooAdvancedFitnessMachineDevice extends BleFitnessMachine
58
71
  };
59
72
  parsePower(_data: Buffer): IndoorBikeData;
60
73
  onData(characteristic: string, data: Buffer): void;
61
- writeWahooFtmsMessage(requestedOpCode: number, data: Buffer): Promise<boolean>;
74
+ writeWahooFtmsMessage(requestedOpCode: number, data: Buffer, props?: BleWriteProps): Promise<boolean>;
62
75
  requestControl(): Promise<boolean>;
63
76
  setPowerAdjusting(): void;
64
77
  isPowerAdjusting(): boolean;
@@ -54,6 +54,7 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
54
54
  this.timeOffset = 0;
55
55
  this.tsPrevWrite = undefined;
56
56
  this.prevSlope = undefined;
57
+ this.isRequestControlBusy = false;
57
58
  this.weight = Device_1.DEFAULT_BIKE_WEIGHT + Device_1.DEFAULT_USER_WEIGHT;
58
59
  this.data = {};
59
60
  this.wahooCP = consts_1.WAHOO_ADVANCED_TRAINER_CP;
@@ -73,7 +74,8 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
73
74
  try {
74
75
  yield this.subscribeWriteResponse(this.wahooCP);
75
76
  try {
76
- yield this.subscribeWriteResponse(consts_1.WAHOO_ADVANCED_TRAINER_CP_FULL.toLowerCase());
77
+ if (this.wahooCP !== consts_1.WAHOO_ADVANCED_TRAINER_CP_FULL.toLowerCase())
78
+ yield this.subscribeWriteResponse(consts_1.WAHOO_ADVANCED_TRAINER_CP_FULL.toLowerCase());
77
79
  }
78
80
  catch (err) {
79
81
  }
@@ -169,7 +171,6 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
169
171
  }
170
172
  onData(characteristic, data) {
171
173
  super.onData(characteristic, data);
172
- const isDuplicate = this.checkForDuplicate(characteristic, data);
173
174
  const uuid = characteristic.toLowerCase();
174
175
  let res = undefined;
175
176
  switch (uuid) {
@@ -192,14 +193,14 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
192
193
  if (res)
193
194
  this.emit('data', res);
194
195
  }
195
- writeWahooFtmsMessage(requestedOpCode, data) {
196
+ writeWahooFtmsMessage(requestedOpCode, data, props) {
196
197
  return __awaiter(this, void 0, void 0, function* () {
197
198
  try {
198
199
  const opcode = Buffer.alloc(1);
199
200
  opcode.writeUInt8(requestedOpCode, 0);
200
201
  const message = Buffer.concat([opcode, data]);
201
202
  this.logEvent({ message: 'wahoo cp:write', data: message.toString('hex') });
202
- const res = yield this.write(this.wahooCP, message);
203
+ const res = yield this.write(this.wahooCP, message, props);
203
204
  const responseData = Buffer.from(res);
204
205
  const result = responseData.readUInt8(0);
205
206
  return result === 1;
@@ -215,16 +216,25 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
215
216
  if (this.hasControl)
216
217
  return true;
217
218
  this.logEvent({ message: 'requestControl' });
218
- const data = Buffer.alloc(2);
219
- data.writeUInt8(0xEE, 0);
220
- data.writeUInt8(0xFC, 1);
221
- const res = yield this.writeWahooFtmsMessage(32, data);
222
- if (res === true) {
223
- this.hasControl = true;
219
+ if (this.isRequestControlBusy)
220
+ return false;
221
+ this.isRequestControlBusy = true;
222
+ try {
223
+ const data = Buffer.alloc(2);
224
+ data.writeUInt8(0xEE, 0);
225
+ data.writeUInt8(0xFC, 1);
226
+ const res = yield this.writeWahooFtmsMessage(32, data, { timeout: 10000 });
227
+ if (res === true) {
228
+ this.hasControl = true;
229
+ }
230
+ else {
231
+ this.logEvent({ message: 'requestControl failed' });
232
+ }
224
233
  }
225
- else {
226
- this.logEvent({ message: 'requestControl failed' });
234
+ catch (err) {
235
+ this.logEvent({ message: 'error', fn: 'requestControl()', error: err.message || err, stack: err.stack });
227
236
  }
237
+ this.isRequestControlBusy = false;
228
238
  return this.hasControl;
229
239
  });
230
240
  }
@@ -330,8 +340,12 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
330
340
  return __awaiter(this, void 0, void 0, function* () {
331
341
  this.logger.logEvent({ message: 'setSimGrade', slope });
332
342
  try {
333
- const value = (slope / 100.0 + 1.0) * 32768;
334
- const slopeVal = Math.floor(value);
343
+ let s = slope;
344
+ if (s < -100)
345
+ s = -100;
346
+ if (s > 100)
347
+ s = 100;
348
+ const slopeVal = Math.min(Math.floor(327.68 * s), 32767);
335
349
  const data = Buffer.alloc(2);
336
350
  data.writeInt16LE(slopeVal, 0);
337
351
  const res = yield this.writeWahooFtmsMessage(70, data);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-devices",
3
- "version": "1.4.88",
3
+ "version": "1.4.90",
4
4
  "dependencies": {
5
5
  "@serialport/parser-byte-length": "^9.0.1",
6
6
  "@serialport/parser-delimiter": "^9.0.1",