incyclist-devices 1.4.79 → 1.4.81

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.
@@ -13,6 +13,11 @@ declare type CommandQueueItem = {
13
13
  resolve: any;
14
14
  reject: any;
15
15
  };
16
+ export interface MessageLog {
17
+ uuid: string;
18
+ timestamp: any;
19
+ data: string;
20
+ }
16
21
  export declare abstract class BleDevice extends BleDeviceClass {
17
22
  id: string;
18
23
  address: string;
@@ -28,6 +33,7 @@ export declare abstract class BleDevice extends BleDeviceClass {
28
33
  subscribedCharacteristics: string[];
29
34
  writeQueue: CommandQueueItem[];
30
35
  workerIv: NodeJS.Timeout;
36
+ prevMessages: MessageLog[];
31
37
  constructor(props?: BleDeviceConstructProps);
32
38
  logEvent(event: any): void;
33
39
  setLogger(logger: EventLogger): void;
@@ -44,6 +50,7 @@ export declare abstract class BleDevice extends BleDeviceClass {
44
50
  connect(props?: ConnectProps): Promise<boolean>;
45
51
  disconnect(): Promise<boolean>;
46
52
  abstract getProfile(): string;
53
+ checkForDuplicate(characteristic: string, data: Buffer): boolean;
47
54
  onData(characteristic: string, data: Buffer): void;
48
55
  timeoutCheck(): void;
49
56
  startWorker(): void;
@@ -28,6 +28,7 @@ class BleDevice extends ble_1.BleDeviceClass {
28
28
  this.isInitialized = false;
29
29
  this.writeQueue = [];
30
30
  this.workerIv = null;
31
+ this.prevMessages = [];
31
32
  if (props.peripheral) {
32
33
  const { id, address, advertisement, state } = props.peripheral;
33
34
  this.peripheral = props.peripheral;
@@ -251,6 +252,23 @@ class BleDevice extends ble_1.BleDeviceClass {
251
252
  }
252
253
  });
253
254
  }
255
+ checkForDuplicate(characteristic, data) {
256
+ const prev = this.prevMessages.find(i => i.uuid === characteristic);
257
+ if (prev) {
258
+ if (prev.data === data.toString('hex') && prev.timestamp > Date.now() - 500) {
259
+ prev.timestamp = Date.now();
260
+ return true;
261
+ }
262
+ else {
263
+ prev.data = data.toString('hex');
264
+ prev.timestamp = Date.now();
265
+ }
266
+ }
267
+ else {
268
+ this.prevMessages.push({ uuid: characteristic, timestamp: Date.now(), data: data.toString('hex') });
269
+ }
270
+ return false;
271
+ }
254
272
  onData(characteristic, data) {
255
273
  if (this.writeQueue.length > 0) {
256
274
  const writeIdx = this.writeQueue.findIndex(i => i.uuid === characteristic.toLocaleLowerCase());
@@ -79,7 +79,7 @@ export default class BleInterface extends BleInterfaceClass {
79
79
  profile?: string;
80
80
  services?: string[];
81
81
  }): (typeof BleDeviceClass)[];
82
- createDevice(DeviceClass: (typeof BleDeviceClass), peripheral: BlePeripheral, characteristics?: BleCharacteristic[]): any;
82
+ createDevice(DeviceClass: (typeof BleDeviceClass), peripheral: BlePeripheral, characteristics?: BleCharacteristic[]): BleDeviceClass;
83
83
  connectDevice(requested: BleDeviceClass | BleDeviceDescription, timeout?: number): Promise<BleDeviceClass>;
84
84
  waitForScanFinished(timeout: any): Promise<unknown>;
85
85
  scan(props: ScanProps): Promise<BleDeviceClass[]>;
@@ -15,6 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const gd_eventlog_1 = require("gd-eventlog");
16
16
  const utils_1 = require("../utils");
17
17
  const ble_1 = require("./ble");
18
+ const ble_2 = require("./ble");
18
19
  const ble_peripheral_1 = __importDefault(require("./ble-peripheral"));
19
20
  const CONNECT_TIMEOUT = 5000;
20
21
  const DEFAULT_SCAN_TIMEOUT = 20000;
@@ -206,13 +207,13 @@ class BleInterface extends ble_1.BleInterfaceClass {
206
207
  return types;
207
208
  };
208
209
  if (typeof services === 'string') {
209
- return get(deviceTypes, (s) => (0, ble_1.uuid)(s) === (0, ble_1.uuid)(services));
210
+ return get(deviceTypes, (s) => (0, ble_2.matches)(s, services));
210
211
  }
211
212
  if (Array.isArray(services)) {
212
213
  const sids = services.map(ble_1.uuid);
213
214
  return get(deviceTypes, s => {
214
- const res = sids.includes((0, ble_1.uuid)(s));
215
- return res;
215
+ const res = sids.find((s) => (0, ble_2.matches)(s, services));
216
+ return res !== undefined;
216
217
  });
217
218
  }
218
219
  return [];
@@ -370,6 +371,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
370
371
  device.setInterface(this);
371
372
  if (characteristics && device.isMatching(cids)) {
372
373
  device.characteristics = characteristics;
374
+ device.setCharacteristicUUIDs(characteristics.map(c => c.uuid));
373
375
  return device;
374
376
  }
375
377
  else {
package/lib/ble/ble.d.ts CHANGED
@@ -42,6 +42,7 @@ export declare abstract class BleDeviceClass extends EventEmitter {
42
42
  abstract connect(props?: ConnectProps): Promise<boolean>;
43
43
  abstract disconnect(): Promise<boolean>;
44
44
  abstract getDeviceInfo(): Promise<BleDeviceInfo>;
45
+ setCharacteristicUUIDs(uuids: string[]): void;
45
46
  }
46
47
  export interface BleBinding extends EventEmitter {
47
48
  startScanning(serviceUUIDs?: string[], allowDuplicates?: boolean, callback?: (error?: Error) => void): void;
@@ -118,3 +119,4 @@ export declare enum BleState {
118
119
  POWERED_ON = "poweredOn"
119
120
  }
120
121
  export declare const uuid: (s: any) => any;
122
+ export declare const matches: (uuid1: any, uuid2: any) => boolean;
package/lib/ble/ble.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.uuid = exports.BleState = exports.BleInterfaceClass = exports.BleBindingWrapper = exports.BleDeviceClass = void 0;
6
+ exports.matches = exports.uuid = exports.BleState = exports.BleInterfaceClass = exports.BleBindingWrapper = exports.BleDeviceClass = void 0;
7
7
  const events_1 = __importDefault(require("events"));
8
8
  class BleDeviceClass extends events_1.default {
9
9
  constructor() {
@@ -16,6 +16,7 @@ class BleDeviceClass extends events_1.default {
16
16
  isConnected() {
17
17
  return this.connectState.isConnected;
18
18
  }
19
+ setCharacteristicUUIDs(uuids) { }
19
20
  }
20
21
  exports.BleDeviceClass = BleDeviceClass;
21
22
  BleDeviceClass.services = [];
@@ -71,3 +72,15 @@ const uuid = (s) => {
71
72
  }
72
73
  };
73
74
  exports.uuid = uuid;
75
+ const matches = (uuid1, uuid2) => {
76
+ if ((0, exports.uuid)(uuid1) === (0, exports.uuid)(uuid2))
77
+ return true;
78
+ const ul1 = uuid1.toLowerCase();
79
+ const ul2 = uuid2.toLowerCase();
80
+ if (ul1.length < ul2.length && ul2.startsWith(ul1))
81
+ return true;
82
+ if (ul1.length > ul2.length && ul1.startsWith(ul2))
83
+ return true;
84
+ return false;
85
+ };
86
+ exports.matches = matches;
package/lib/ble/fm.js CHANGED
@@ -306,6 +306,9 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
306
306
  }
307
307
  onData(characteristic, data) {
308
308
  super.onData(characteristic, data);
309
+ const isDuplicate = this.checkForDuplicate(characteristic, data);
310
+ if (isDuplicate)
311
+ return;
309
312
  const uuid = characteristic.toLocaleLowerCase();
310
313
  let res = undefined;
311
314
  switch (uuid) {
@@ -321,7 +324,6 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
321
324
  case '2a63':
322
325
  case '2a5b':
323
326
  case '347b0011-7635-408b-8918-8ff3949ce592':
324
- this.logger.logEvent({ message: 'onBleData', raw: `uuid:${data.toString('hex')}` });
325
327
  break;
326
328
  default:
327
329
  break;
package/lib/ble/hrm.js CHANGED
@@ -52,6 +52,9 @@ class BleHrmDevice extends ble_device_1.BleDevice {
52
52
  }
53
53
  onData(characteristic, data) {
54
54
  super.onData(characteristic, data);
55
+ const isDuplicate = this.checkForDuplicate(characteristic, data);
56
+ if (isDuplicate)
57
+ return;
55
58
  if (characteristic.toLocaleLowerCase() === '2a37') {
56
59
  const res = this.parseHrm(data);
57
60
  this.emit('data', res);
package/lib/ble/pwr.js CHANGED
@@ -140,6 +140,9 @@ class BleCyclingPowerDevice extends ble_device_1.BleDevice {
140
140
  }
141
141
  onData(characteristic, data) {
142
142
  super.onData(characteristic, data);
143
+ const isDuplicate = this.checkForDuplicate(characteristic, data);
144
+ if (isDuplicate)
145
+ return;
143
146
  if (characteristic.toLocaleLowerCase() === CP_MEASUREMENT) {
144
147
  const res = this.parsePower(data);
145
148
  this.emit('data', res);
package/lib/ble/tacx.d.ts CHANGED
@@ -24,14 +24,6 @@ declare type CrankData = {
24
24
  time?: number;
25
25
  cntUpdateMissing?: number;
26
26
  };
27
- declare type MessageInfo = {
28
- message: string;
29
- ts: number;
30
- uuid: string;
31
- };
32
- declare type MessageLog = {
33
- [uuid: string]: MessageInfo;
34
- };
35
27
  export default class TacxAdvancedFitnessMachineDevice extends BleFitnessMachineDevice {
36
28
  static services: string[];
37
29
  static characteristics: string[];
@@ -42,10 +34,12 @@ export default class TacxAdvancedFitnessMachineDevice extends BleFitnessMachineD
42
34
  tsPrevWrite: any;
43
35
  data: BleFeBikeData;
44
36
  hasFECData: boolean;
45
- prevMessages: MessageLog;
46
37
  messageCnt: number;
38
+ tacxRx: string;
39
+ tacxTx: string;
47
40
  constructor(props?: any);
48
41
  isMatching(characteristics: string[]): boolean;
42
+ setCharacteristicUUIDs(uuids: string[]): void;
49
43
  init(): Promise<boolean>;
50
44
  getProfile(): string;
51
45
  getServiceUUids(): string[];
package/lib/ble/tacx.js CHANGED
@@ -33,6 +33,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
33
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
34
  exports.TacxBleFEAdapter = void 0;
35
35
  const ble_interface_1 = __importDefault(require("./ble-interface"));
36
+ const ble_1 = require("./ble");
36
37
  const Device_1 = require("../Device");
37
38
  const gd_eventlog_1 = require("gd-eventlog");
38
39
  const fm_1 = __importStar(require("./fm"));
@@ -75,15 +76,25 @@ class TacxAdvancedFitnessMachineDevice extends fm_1.default {
75
76
  this.data = {};
76
77
  this.hasFECData = false;
77
78
  this.messageCnt = 0;
78
- this.prevMessages = {};
79
+ this.tacxRx = consts_1.TACX_FE_C_RX;
80
+ this.tacxTx = consts_1.TACX_FE_C_TX;
79
81
  }
80
82
  isMatching(characteristics) {
81
83
  if (!characteristics)
82
84
  return false;
83
- const hasTacxCP = characteristics.find(c => c === consts_1.TACX_FE_C_RX) !== undefined && characteristics.find(c => c === consts_1.TACX_FE_C_TX) !== undefined;
84
- const hasFTMS = characteristics.find(c => c === consts_1.FTMS_CP) !== undefined;
85
+ const hasTacxCP = characteristics.find(c => (0, ble_1.matches)(c, consts_1.TACX_FE_C_RX)) !== undefined &&
86
+ characteristics.find(c => (0, ble_1.matches)(c, consts_1.TACX_FE_C_TX)) !== undefined;
87
+ const hasFTMS = characteristics.find(c => (0, ble_1.matches)(c, consts_1.FTMS_CP)) !== undefined;
85
88
  return hasTacxCP;
86
89
  }
90
+ setCharacteristicUUIDs(uuids) {
91
+ uuids.forEach(c => {
92
+ if ((0, ble_1.matches)(c, consts_1.TACX_FE_C_RX))
93
+ this.tacxRx = c;
94
+ if ((0, ble_1.matches)(c, consts_1.TACX_FE_C_TX))
95
+ this.tacxTx = c;
96
+ });
97
+ }
87
98
  init() {
88
99
  const _super = Object.create(null, {
89
100
  initDevice: { get: () => super.initDevice }
@@ -423,20 +434,13 @@ class TacxAdvancedFitnessMachineDevice extends fm_1.default {
423
434
  return res;
424
435
  }
425
436
  onData(characteristic, data) {
437
+ const isDuplicate = this.checkForDuplicate(characteristic, data);
438
+ if (isDuplicate)
439
+ return;
426
440
  try {
427
441
  const uuid = characteristic.toLocaleLowerCase();
428
- const message = data.toString('hex');
429
- const ts = Date.now();
430
- if (this.prevMessages[uuid]) {
431
- const prev = this.prevMessages[uuid];
432
- if (prev.message === message && prev.ts > ts - 500) {
433
- return;
434
- }
435
- }
436
- this.prevMessages[uuid] = { uuid, ts, message };
437
- this.messageCnt++;
438
442
  let res = undefined;
439
- if (uuid && uuid.startsWith(consts_1.TACX_FE_C_RX)) {
443
+ if (uuid && (0, ble_1.matches)(uuid, this.tacxRx)) {
440
444
  res = this.parseFECMessage(data);
441
445
  }
442
446
  else {
@@ -492,7 +496,7 @@ class TacxAdvancedFitnessMachineDevice extends fm_1.default {
492
496
  }
493
497
  sendMessage(message) {
494
498
  return __awaiter(this, void 0, void 0, function* () {
495
- yield this.write(consts_1.TACX_FE_C_TX, message, true);
499
+ yield this.write(this.tacxTx, message, true);
496
500
  return true;
497
501
  });
498
502
  }
@@ -35,9 +35,11 @@ export default class WahooAdvancedFitnessMachineDevice extends BleFitnessMachine
35
35
  timeOffset: number;
36
36
  tsPrevWrite: any;
37
37
  prevSlope: any;
38
+ wahooCP: string;
38
39
  constructor(props?: any);
39
40
  isMatching(characteristics: string[]): boolean;
40
41
  init(): Promise<boolean>;
42
+ setCharacteristicUUIDs(uuids: string[]): void;
41
43
  getProfile(): string;
42
44
  getServiceUUids(): string[];
43
45
  isBike(): boolean;
@@ -33,6 +33,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
33
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
34
  exports.WahooAdvancedFmAdapter = void 0;
35
35
  const ble_interface_1 = __importDefault(require("./ble-interface"));
36
+ const ble_1 = require("./ble");
36
37
  const Device_1 = require("../Device");
37
38
  const gd_eventlog_1 = require("gd-eventlog");
38
39
  const fm_1 = __importStar(require("./fm"));
@@ -55,12 +56,13 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
55
56
  this.tsPrevWrite = undefined;
56
57
  this.prevSlope = undefined;
57
58
  this.data = {};
59
+ this.wahooCP = WAHOO_ADVANCED_TRAINER_CP;
58
60
  }
59
61
  isMatching(characteristics) {
60
62
  if (!characteristics)
61
63
  return false;
62
- const hasWahooCP = characteristics.find(c => c === WAHOO_ADVANCED_TRAINER_CP) !== undefined;
63
- const hasFTMS = characteristics.find(c => c === consts_1.FTMS_CP) !== undefined;
64
+ const hasWahooCP = characteristics.find(c => (0, ble_1.matches)(c, WAHOO_ADVANCED_TRAINER_CP)) !== undefined;
65
+ const hasFTMS = characteristics.find(c => (0, ble_1.matches)(c, consts_1.FTMS_CP)) !== undefined;
64
66
  return hasWahooCP && !hasFTMS;
65
67
  }
66
68
  init() {
@@ -69,7 +71,7 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
69
71
  });
70
72
  return __awaiter(this, void 0, void 0, function* () {
71
73
  try {
72
- yield this.subscribeWriteResponse(WAHOO_ADVANCED_TRAINER_CP);
74
+ yield this.subscribeWriteResponse(this.wahooCP);
73
75
  yield _super.initDevice.call(this);
74
76
  return true;
75
77
  }
@@ -79,6 +81,12 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
79
81
  }
80
82
  });
81
83
  }
84
+ setCharacteristicUUIDs(uuids) {
85
+ uuids.forEach(c => {
86
+ if ((0, ble_1.matches)(c, WAHOO_ADVANCED_TRAINER_CP))
87
+ this.wahooCP = c;
88
+ });
89
+ }
82
90
  getProfile() {
83
91
  return 'Wahoo Smart Trainer';
84
92
  }
@@ -155,6 +163,9 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
155
163
  }
156
164
  onData(characteristic, data) {
157
165
  super.onData(characteristic, data);
166
+ const isDuplicate = this.checkForDuplicate(characteristic, data);
167
+ if (isDuplicate)
168
+ return;
158
169
  const uuid = characteristic.toLocaleLowerCase();
159
170
  let res = undefined;
160
171
  switch (uuid) {
@@ -182,7 +193,7 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
182
193
  const opcode = Buffer.alloc(1);
183
194
  opcode.writeUInt8(requestedOpCode, 0);
184
195
  const message = Buffer.concat([opcode, data]);
185
- const res = yield this.write(WAHOO_ADVANCED_TRAINER_CP, message);
196
+ const res = yield this.write(this.wahooCP, message);
186
197
  const responseData = Buffer.from(res);
187
198
  const result = responseData.readUInt8(0);
188
199
  this.logEvent({ message: 'response', opCode: requestedOpCode, response: responseData.toString('hex') });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-devices",
3
- "version": "1.4.79",
3
+ "version": "1.4.81",
4
4
  "dependencies": {
5
5
  "@serialport/parser-byte-length": "^9.0.1",
6
6
  "@serialport/parser-delimiter": "^9.0.1",