incyclist-devices 1.4.18 → 1.4.21

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.
package/lib/Device.d.ts CHANGED
@@ -12,6 +12,7 @@ export declare type DeviceData = {
12
12
  timestamp?: number;
13
13
  deviceTime?: number;
14
14
  deviceDistanceCounter?: number;
15
+ internalDistanceCounter?: number;
15
16
  };
16
17
  export declare type OnDeviceDataCallback = (data: DeviceData) => void;
17
18
  export declare type OnDeviceStartCallback = (completed: number, total: number) => void;
@@ -16,7 +16,7 @@ const gd_eventlog_1 = require("gd-eventlog");
16
16
  const utils_1 = require("../utils");
17
17
  const events_1 = __importDefault(require("events"));
18
18
  const DEFAULT_RCV_TIMEOUT = 1500;
19
- const DEFAULT_OPEN_TIMEOUT = 1500;
19
+ const DEFAULT_OPEN_TIMEOUT = 3000;
20
20
  const DEBUG_LOGGER = {
21
21
  log: (e, ...args) => console.log(e, ...args),
22
22
  logEvent: (event) => console.log(JSON.stringify(event))
@@ -200,6 +200,7 @@ class KettlerSerialComms extends events_1.default {
200
200
  cmd.onError(err);
201
201
  this.sendState = SendState.Idle;
202
202
  this.currentCmd = undefined;
203
+ this.stopCurrentTimeoutCheck();
203
204
  };
204
205
  try {
205
206
  this.logger.logEvent({ message: "sendCommand:sending:", cmd: logStr, msg, port: this.getPort() });
@@ -208,16 +209,17 @@ class KettlerSerialComms extends events_1.default {
208
209
  this.sp.write(msg + CRLF, (err) => {
209
210
  this.sendState = SendState.Receiving;
210
211
  this.currentCmd = cmd;
211
- if (timeout) {
212
- this.currentTimeout = setTimeout(() => {
213
- if (this.sendState === SendState.Receiving) {
214
- onError(new Error("response timeout"));
215
- }
216
- }, timeout);
217
- }
218
212
  if (err)
219
213
  onError(err);
220
214
  });
215
+ this.currentTimeout = setTimeout(() => {
216
+ if (this.sendState === SendState.Sending) {
217
+ onError(new Error("send timeout"));
218
+ }
219
+ if (this.sendState === SendState.Receiving) {
220
+ onError(new Error("response timeout"));
221
+ }
222
+ }, timeout);
221
223
  }
222
224
  catch (err) {
223
225
  onError(err);
@@ -232,7 +234,7 @@ class KettlerSerialComms extends events_1.default {
232
234
  this.write(cmd);
233
235
  }
234
236
  send(cmd) {
235
- this.logger.logEvent({ message: 'send()', cmd: cmd.logStr, port: this.getPort(), queueSize: this.queue.size() });
237
+ this.logger.logEvent({ message: 'add command to queue', cmd: cmd.logStr, msg: cmd.message, port: this.getPort(), queueSize: this.queue.size() });
236
238
  this.queue.enqueue(cmd);
237
239
  }
238
240
  }
@@ -37,11 +37,12 @@ export default class KettlerRacerAdapter extends DeviceAdapterBase implements De
37
37
  private iv;
38
38
  private requests;
39
39
  private data;
40
- private idata;
40
+ private internalData;
41
41
  private kettlerData;
42
42
  private updateBusy;
43
43
  private requestBusy;
44
44
  private comms;
45
+ private prevDistance;
45
46
  constructor(protocol: DeviceProtocol, settings: DeviceSettings);
46
47
  isBike(): boolean;
47
48
  isPower(): boolean;
@@ -76,7 +77,7 @@ export default class KettlerRacerAdapter extends DeviceAdapterBase implements De
76
77
  parseExtendedStatus(data: string): KettlerExtendedBikeData;
77
78
  parseStatus(data: string): KettlerBikeData;
78
79
  check(): Promise<boolean>;
79
- start(props?: any): Promise<any>;
80
+ start(props?: any): Promise<IncyclistBikeData>;
80
81
  startUpdatePull(): void;
81
82
  stop(): Promise<boolean>;
82
83
  pause(): Promise<boolean>;
@@ -91,7 +92,7 @@ export default class KettlerRacerAdapter extends DeviceAdapterBase implements De
91
92
  sendData(): void;
92
93
  refreshRequests(): void;
93
94
  processClientRequest(request: any): Promise<unknown>;
94
- waitForOpened(): Promise<boolean>;
95
+ waitForOpened(retries?: boolean): Promise<boolean>;
95
96
  waitForClosed(): Promise<boolean>;
96
97
  getSupportedCyclingModes(): any[];
97
98
  setCyclingMode(mode: CyclingMode | string, settings?: any): void;
@@ -220,7 +220,7 @@ class KettlerRacerAdapter extends Device_1.default {
220
220
  }
221
221
  const distance = parseInt(states[3]);
222
222
  if (!isNaN(distance)) {
223
- result.distance = distance;
223
+ result.distance = distance * 100;
224
224
  }
225
225
  const requestedPower = parseInt(states[4]);
226
226
  if (!isNaN(requestedPower)) {
@@ -228,7 +228,7 @@ class KettlerRacerAdapter extends Device_1.default {
228
228
  }
229
229
  const energy = parseInt(states[5]);
230
230
  if (!isNaN(energy)) {
231
- result.requestedPower = energy;
231
+ result.energy = energy;
232
232
  }
233
233
  const timeStr = states[6];
234
234
  const time = timeStr.split(':');
@@ -284,47 +284,49 @@ class KettlerRacerAdapter extends Device_1.default {
284
284
  });
285
285
  }
286
286
  start(props) {
287
- this.logger.logEvent({ message: 'start()' });
288
- var info = {};
289
- return utils_1.runWithRetries(() => __awaiter(this, void 0, void 0, function* () {
290
- try {
291
- if (!info.checkDone) {
292
- info.checkDone = yield this.check();
293
- }
287
+ return __awaiter(this, void 0, void 0, function* () {
288
+ this.logger.logEvent({ message: 'start()' });
289
+ var info = {};
290
+ yield this.waitForOpened(true);
291
+ return utils_1.runWithRetries(() => __awaiter(this, void 0, void 0, function* () {
294
292
  try {
295
- if (!info.started) {
296
- info.started = yield this.startTraining();
293
+ if (!info.checkDone) {
294
+ info.checkDone = yield this.check();
297
295
  }
296
+ try {
297
+ if (!info.started) {
298
+ info.started = yield this.startTraining();
299
+ }
300
+ }
301
+ catch (e) {
302
+ this.logger.logEvent({ message: 'Error', error: e.message });
303
+ }
304
+ try {
305
+ yield this.setPower(100);
306
+ }
307
+ catch (e) {
308
+ this.logger.logEvent({ message: 'Error', error: e.message });
309
+ }
310
+ if (!info.data) {
311
+ yield this.update();
312
+ info.data = this.data;
313
+ }
314
+ return info.data;
298
315
  }
299
- catch (e) {
300
- this.logger.logEvent({ message: 'Error', error: e.message });
301
- }
302
- try {
303
- yield this.setPower(100);
304
- }
305
- catch (e) {
306
- this.logger.logEvent({ message: 'Error', error: e.message });
307
- }
308
- if (!info.data) {
309
- yield this.update();
310
- info.data = this.data;
311
- }
312
- return info.data;
313
- }
314
- catch (err) {
315
- console.log('~~~ Error', err);
316
- try {
317
- yield this.reset();
318
- }
319
- catch (e) {
320
- this.logger.logEvent({ message: 'Error', error: e.message });
316
+ catch (err) {
317
+ try {
318
+ yield this.reset();
319
+ }
320
+ catch (e) {
321
+ this.logger.logEvent({ message: 'Error', error: e.message });
322
+ }
323
+ throw (new Error(`could not start device, reason:${err.message}`));
321
324
  }
322
- throw (new Error(`could not start device, reason:${err.message}`));
323
- }
324
- }), 5, 1000)
325
- .then(data => {
326
- this.startUpdatePull();
327
- return data;
325
+ }), 5, 1000)
326
+ .then((data) => {
327
+ this.startUpdatePull();
328
+ return data;
329
+ });
328
330
  });
329
331
  }
330
332
  startUpdatePull() {
@@ -395,6 +397,10 @@ class KettlerRacerAdapter extends Device_1.default {
395
397
  }
396
398
  transformData(internalData, bikeData) {
397
399
  let data = {};
400
+ const prevDistance = this.prevDistance || 0;
401
+ let distance = internalData.distanceInternal - prevDistance;
402
+ if (distance < 0)
403
+ distance = internalData.distanceInternal < 100 ? internalData.distanceInternal : 0;
398
404
  data.heartrate = internalData.heartrate;
399
405
  data.timestamp = Date.now();
400
406
  data.deviceTime = bikeData.time;
@@ -402,8 +408,10 @@ class KettlerRacerAdapter extends Device_1.default {
402
408
  data.speed = internalData.speed;
403
409
  data.power = internalData.power;
404
410
  data.cadence = internalData.pedalRpm;
405
- data.distance = internalData.distanceInternal;
411
+ data.distance = distance;
406
412
  data.deviceDistanceCounter = bikeData.distance;
413
+ data.internalDistanceCounter = internalData.distanceInternal;
414
+ this.prevDistance = internalData.distanceInternal;
407
415
  }
408
416
  if (this.ignoreHrm)
409
417
  delete this.data.heartrate;
@@ -416,13 +424,14 @@ class KettlerRacerAdapter extends Device_1.default {
416
424
  update() {
417
425
  return __awaiter(this, void 0, void 0, function* () {
418
426
  this.updateBusy = true;
419
- this.getStatus()
427
+ return this.getStatus()
420
428
  .then((bikeData) => {
421
429
  if (bikeData) {
422
430
  try {
423
431
  this.kettlerData = bikeData;
424
432
  let data = this.mapData(bikeData);
425
433
  data = this.getCyclingMode().updateData(data);
434
+ this.internalData = data;
426
435
  this.data = this.transformData(data, bikeData);
427
436
  }
428
437
  catch (err) {
@@ -534,34 +543,38 @@ class KettlerRacerAdapter extends Device_1.default {
534
543
  resolve(bikeRequest);
535
544
  }));
536
545
  }
537
- waitForOpened() {
538
- return utils_1.runWithRetries(() => {
539
- return new Promise((resolve, reject) => {
540
- try {
541
- if (this.comms.isConnected()) {
542
- resolve(true);
543
- return;
544
- }
545
- const cleanup = () => {
546
- this.comms.removeAllListeners();
547
- };
548
- const onOpen = () => {
549
- resolve(true);
550
- cleanup();
551
- };
552
- const onError = (err) => { reject(err); cleanup(); };
553
- const onClose = () => { cleanup(); };
554
- this.comms.on('opened', onOpen);
555
- this.comms.on('closed', onClose);
556
- this.comms.on('error', onError);
557
- this.logger.logEvent({ message: 'opening', port: this.getPort() });
558
- this.comms.open();
559
- }
560
- catch (err) {
561
- this.logger.logEvent({ message: 'error', fn: 'waitForOpened()', error: err.message || err });
562
- reject(err);
546
+ waitForOpened(retries = false) {
547
+ const run = (resolve, reject) => {
548
+ try {
549
+ if (this.comms.isConnected()) {
550
+ resolve(true);
551
+ return;
563
552
  }
564
- });
553
+ const cleanup = () => {
554
+ this.comms.removeAllListeners();
555
+ };
556
+ const onOpen = () => {
557
+ resolve(true);
558
+ cleanup();
559
+ };
560
+ const onError = (err) => { reject(err); cleanup(); };
561
+ const onClose = () => { cleanup(); };
562
+ this.comms.on('opened', onOpen);
563
+ this.comms.on('closed', onClose);
564
+ this.comms.on('error', onError);
565
+ this.logger.logEvent({ message: 'opening', port: this.getPort() });
566
+ this.comms.open();
567
+ }
568
+ catch (err) {
569
+ this.logger.logEvent({ message: 'error', fn: 'waitForOpened()', error: err.message || err });
570
+ reject(err);
571
+ }
572
+ };
573
+ if (!retries) {
574
+ return new Promise((resolve, reject) => run(resolve, reject));
575
+ }
576
+ return utils_1.runWithRetries(() => {
577
+ return new Promise((resolve, reject) => run(resolve, reject));
565
578
  }, 3, 1000);
566
579
  }
567
580
  waitForClosed() {
package/lib/utils.js CHANGED
@@ -17,16 +17,18 @@ function runWithRetries(fn, maxRetries, timeBetween) {
17
17
  let retries = 0;
18
18
  let tLastFailure = undefined;
19
19
  let busy = false;
20
- const iv = setInterval(() => __awaiter(this, void 0, void 0, function* () {
20
+ let iv = setInterval(() => __awaiter(this, void 0, void 0, function* () {
21
21
  const tNow = Date.now();
22
- if (busy)
22
+ if (busy) {
23
23
  return;
24
+ }
24
25
  if (tLastFailure === undefined || tNow - tLastFailure > timeBetween) {
25
26
  try {
26
27
  busy = true;
27
28
  const data = yield fn();
28
- busy = false;
29
29
  clearInterval(iv);
30
+ iv = undefined;
31
+ busy = false;
30
32
  return resolve(data);
31
33
  }
32
34
  catch (err) {
@@ -34,6 +36,7 @@ function runWithRetries(fn, maxRetries, timeBetween) {
34
36
  retries++;
35
37
  if (retries >= maxRetries) {
36
38
  clearInterval(iv);
39
+ iv = undefined;
37
40
  busy = false;
38
41
  return reject(err);
39
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-devices",
3
- "version": "1.4.18",
3
+ "version": "1.4.21",
4
4
  "dependencies": {
5
5
  "@serialport/parser-byte-length": "^9.0.1",
6
6
  "@serialport/parser-delimiter": "^9.0.1",