incyclist-devices 2.0.34 → 2.0.36

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.
Files changed (54) hide show
  1. package/lib/antv2/modes/ant-fe-adv-st-mode.d.ts +2 -2
  2. package/lib/antv2/modes/ant-fe-erg-mode.d.ts +2 -2
  3. package/lib/antv2/modes/ant-fe-st-mode.d.ts +2 -2
  4. package/lib/base/adpater.d.ts +2 -1
  5. package/lib/base/adpater.js +7 -6
  6. package/lib/interfaces.d.ts +1 -1
  7. package/lib/modes/ble-erg-mode.d.ts +2 -2
  8. package/lib/modes/ble-st-mode.d.ts +2 -2
  9. package/lib/modes/cycling-mode.d.ts +7 -7
  10. package/lib/modes/power-base.d.ts +3 -3
  11. package/lib/modes/power-base.js +3 -2
  12. package/lib/modes/power-meter.d.ts +2 -2
  13. package/lib/serial/comms.d.ts +62 -0
  14. package/lib/serial/comms.js +280 -0
  15. package/lib/serial/daum/DaumAdapter.d.ts +13 -8
  16. package/lib/serial/daum/DaumAdapter.js +49 -12
  17. package/lib/serial/daum/ERGCyclingMode.d.ts +2 -2
  18. package/lib/serial/daum/ERGCyclingMode.js +1 -1
  19. package/lib/serial/daum/SmartTrainerCyclingMode.d.ts +3 -2
  20. package/lib/serial/daum/SmartTrainerCyclingMode.js +10 -5
  21. package/lib/serial/daum/classic/adapter.d.ts +4 -6
  22. package/lib/serial/daum/classic/adapter.js +5 -23
  23. package/lib/serial/daum/classic/comms.d.ts +33 -65
  24. package/lib/serial/daum/classic/comms.js +148 -332
  25. package/lib/serial/daum/classic/mock.js +5 -3
  26. package/lib/serial/daum/classic/modes/daum-classic.d.ts +2 -2
  27. package/lib/serial/daum/classic/modes/daum-classic.js +1 -1
  28. package/lib/serial/daum/classic/types.d.ts +59 -0
  29. package/lib/serial/daum/classic/types.js +2 -0
  30. package/lib/serial/daum/classic/utils.d.ts +11 -10
  31. package/lib/serial/daum/classic/utils.js +33 -68
  32. package/lib/serial/daum/premium/adapter.d.ts +4 -7
  33. package/lib/serial/daum/premium/adapter.js +7 -30
  34. package/lib/serial/daum/premium/comms.d.ts +28 -105
  35. package/lib/serial/daum/premium/comms.js +262 -466
  36. package/lib/serial/daum/premium/consts.d.ts +6 -0
  37. package/lib/serial/daum/premium/consts.js +9 -0
  38. package/lib/serial/daum/premium/mock.d.ts +32 -1
  39. package/lib/serial/daum/premium/mock.js +131 -8
  40. package/lib/serial/daum/premium/modes/daum-classic.d.ts +2 -2
  41. package/lib/serial/daum/premium/modes/daum-classic.js +1 -1
  42. package/lib/serial/daum/premium/types.d.ts +35 -1
  43. package/lib/serial/daum/premium/types.js +29 -0
  44. package/lib/serial/daum/premium/utils.d.ts +11 -18
  45. package/lib/serial/daum/premium/utils.js +25 -18
  46. package/lib/serial/serial-interface.js +17 -10
  47. package/lib/types/adapter.d.ts +2 -0
  48. package/lib/types/device.d.ts +11 -0
  49. package/lib/types/route.d.ts +0 -5
  50. package/lib/types/route.js +0 -7
  51. package/lib/utils/calculations.js +1 -5
  52. package/lib/utils/utils.d.ts +2 -1
  53. package/lib/utils/utils.js +39 -3
  54. package/package.json +3 -2
@@ -0,0 +1,6 @@
1
+ export declare const DEFAULT_TIMEOUT = 10000;
2
+ export declare const DEFAULT_ACK_TIMEOUT = 11000;
3
+ export declare const DEFAULT_BUSY_TIMEOUT = 5000;
4
+ export declare const MAX_DATA_BLOCK_SIZE = 512;
5
+ export declare const DS_BITS_OFF = 0;
6
+ export declare const DS_BITS_ENDLESS_RACE = 2;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DS_BITS_ENDLESS_RACE = exports.DS_BITS_OFF = exports.MAX_DATA_BLOCK_SIZE = exports.DEFAULT_BUSY_TIMEOUT = exports.DEFAULT_ACK_TIMEOUT = exports.DEFAULT_TIMEOUT = void 0;
4
+ exports.DEFAULT_TIMEOUT = 10000;
5
+ exports.DEFAULT_ACK_TIMEOUT = 11000;
6
+ exports.DEFAULT_BUSY_TIMEOUT = 5000;
7
+ exports.MAX_DATA_BLOCK_SIZE = 512;
8
+ exports.DS_BITS_OFF = 0;
9
+ exports.DS_BITS_ENDLESS_RACE = 2;
@@ -28,6 +28,26 @@ export declare class Daum8iMockImpl {
28
28
  list(): Promise<import("@serialport/bindings-interface").PortInfo[]>;
29
29
  open(options: any): Promise<Daum8iMockBinding>;
30
30
  }
31
+ type Program = {
32
+ lapMode: boolean;
33
+ id?: number;
34
+ started?: boolean;
35
+ };
36
+ type trainingData = {
37
+ time: number;
38
+ heartrate: number;
39
+ v: number;
40
+ slope: number;
41
+ distanceInternal: number;
42
+ pedalRpm: number;
43
+ power: number;
44
+ physEnergy: number;
45
+ realEnergy: number;
46
+ torque: number;
47
+ gear: number;
48
+ deviceState: number;
49
+ speedStatus: number;
50
+ };
31
51
  export declare class Daum8MockSimulator {
32
52
  protoVersion: string;
33
53
  dashboardVersion: string;
@@ -38,16 +58,21 @@ export declare class Daum8MockSimulator {
38
58
  currentPower: number;
39
59
  loadControl: number;
40
60
  person: User;
61
+ program: Program;
62
+ data: trainingData;
41
63
  _isSimulateACKTimeout: boolean;
42
64
  _isSimulateCheckSumError: boolean;
65
+ _isSimulateReservedError: boolean;
43
66
  _timeoutResponse: number;
44
67
  timeoutNAKRetry: number;
45
68
  simulateACKTimeout(): void;
46
69
  simulateTimeout(ms: number): void;
47
70
  simulateChecksumError(): void;
71
+ simulateReservedError(): void;
48
72
  onNAK(): void;
49
73
  onACK(): void;
50
74
  }
75
+ export declare function parseProgramListNewData(buffer: Buffer): Program;
51
76
  export declare class Daum8iMockBinding extends MockPortBinding {
52
77
  waitingForCommand: boolean;
53
78
  waitingForAck: boolean;
@@ -59,7 +84,7 @@ export declare class Daum8iMockBinding extends MockPortBinding {
59
84
  initHandlers(): void;
60
85
  write(buffer: Buffer): Promise<void>;
61
86
  processData(buffer: Buffer): Promise<void>;
62
- createResponse(cmd: string, payload: Buffer): Buffer;
87
+ createResponse(cmd: string, payload: Buffer, binary?: boolean): Buffer;
63
88
  emitData(data: string | Buffer): void;
64
89
  onGetProtcolVersion(_payload: Buffer): void;
65
90
  onGetDashboardVersion(_payload: Buffer): void;
@@ -71,5 +96,11 @@ export declare class Daum8iMockBinding extends MockPortBinding {
71
96
  onReservedCommand(payload: Buffer): void;
72
97
  onPersonSet(payload: Buffer): void;
73
98
  onPersonGet(): void;
99
+ onProgramListBegin(): void;
100
+ onProgramListNewProgram(payload: Buffer): void;
101
+ onProgramListEnd(): void;
102
+ onProgramListContinueProgram(): void;
103
+ onProgramListStart(payload: Buffer): void;
74
104
  onGetTrainingData(_payload: Buffer): void;
75
105
  }
106
+ export {};
@@ -9,12 +9,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.Daum8iMockBinding = exports.Daum8MockSimulator = exports.Daum8iMockImpl = exports.Daum8iMock = void 0;
12
+ exports.Daum8iMockBinding = exports.parseProgramListNewData = exports.Daum8MockSimulator = exports.Daum8iMockImpl = exports.Daum8iMock = void 0;
13
13
  const binding_mock_1 = require("@serialport/binding-mock");
14
14
  const __1 = require("../../");
15
15
  const user_1 = require("../../../types/user");
16
16
  const utils_1 = require("../../../utils/utils");
17
17
  const utils_2 = require("./utils");
18
+ const consts_1 = require("./consts");
18
19
  exports.Daum8iMock = {
19
20
  reset() {
20
21
  Daum8iMockImpl.getInstance().reset();
@@ -73,6 +74,21 @@ class Daum8iMockImpl {
73
74
  }
74
75
  }
75
76
  exports.Daum8iMockImpl = Daum8iMockImpl;
77
+ const DEFAULT_TRAINING_DATA = {
78
+ time: 0,
79
+ heartrate: 0,
80
+ v: 0,
81
+ slope: 0,
82
+ distanceInternal: 0,
83
+ pedalRpm: 0,
84
+ power: 0,
85
+ physEnergy: 0,
86
+ realEnergy: 0,
87
+ torque: 0,
88
+ gear: 10,
89
+ deviceState: 1,
90
+ speedStatus: 0
91
+ };
76
92
  class Daum8MockSimulator {
77
93
  constructor() {
78
94
  this.protoVersion = '201';
@@ -84,8 +100,10 @@ class Daum8MockSimulator {
84
100
  this.currentPower = 0;
85
101
  this.loadControl = 1;
86
102
  this.person = { weight: 75, length: 180, age: 30, sex: user_1.Gender.MALE };
103
+ this.data = DEFAULT_TRAINING_DATA;
87
104
  this._isSimulateACKTimeout = false;
88
105
  this._isSimulateCheckSumError = false;
106
+ this._isSimulateReservedError = false;
89
107
  this._timeoutResponse = 0;
90
108
  this.timeoutNAKRetry = 1000;
91
109
  }
@@ -98,10 +116,19 @@ class Daum8MockSimulator {
98
116
  simulateChecksumError() {
99
117
  this._isSimulateCheckSumError = true;
100
118
  }
119
+ simulateReservedError() {
120
+ this._isSimulateReservedError = true;
121
+ }
101
122
  onNAK() { }
102
123
  onACK() { }
103
124
  }
104
125
  exports.Daum8MockSimulator = Daum8MockSimulator;
126
+ function parseProgramListNewData(buffer) {
127
+ const wBits = buffer.readInt16LE(30);
128
+ const lapMode = wBits === consts_1.DS_BITS_ENDLESS_RACE;
129
+ return { lapMode };
130
+ }
131
+ exports.parseProgramListNewData = parseProgramListNewData;
105
132
  class Daum8iMockBinding extends binding_mock_1.MockPortBinding {
106
133
  constructor(parent) {
107
134
  super(parent.port, parent.openOptions);
@@ -214,8 +241,14 @@ class Daum8iMockBinding extends binding_mock_1.MockPortBinding {
214
241
  }
215
242
  });
216
243
  }
217
- createResponse(cmd, payload) {
218
- const buffer = Buffer.from((0, utils_2.buildMessage)(cmd, payload));
244
+ createResponse(cmd, payload, binary = false) {
245
+ let buffer;
246
+ if (binary) {
247
+ buffer = Buffer.from((0, utils_2.buildMessage)(cmd, (0, utils_2.bin2esc)(payload)));
248
+ }
249
+ else {
250
+ buffer = Buffer.from((0, utils_2.buildMessage)(cmd, payload));
251
+ }
219
252
  this.prevCommand = Buffer.from(buffer);
220
253
  if (this.simulator._isSimulateCheckSumError) {
221
254
  this.simulator._isSimulateCheckSumError = false;
@@ -267,20 +300,110 @@ class Daum8iMockBinding extends binding_mock_1.MockPortBinding {
267
300
  }
268
301
  onReservedCommand(payload) {
269
302
  const cmd = payload.readInt16LE(0);
270
- const length = payload.readUint16LE(2);
271
- const data = (0, utils_2.esc2bin)(payload.subarray(4, 4 + length - 1));
303
+ const data = (0, utils_2.esc2bin)(payload.subarray(4, 4 + payload.length - 1));
272
304
  switch (cmd) {
273
- case utils_2.ReservedCommands.PERSON_SET: this.onPersonSet(Buffer.from(data));
274
- case utils_2.ReservedCommands.PERSON_GET: this.onPersonGet();
305
+ case utils_2.ReservedCommands.PERSON_SET:
306
+ this.onPersonSet(Buffer.from(data));
307
+ break;
308
+ case utils_2.ReservedCommands.PERSON_GET:
309
+ this.onPersonGet();
310
+ break;
311
+ case utils_2.ReservedCommands.PROGRAM_LIST_BEGIN:
312
+ this.onProgramListBegin();
313
+ break;
314
+ case utils_2.ReservedCommands.PROGRAM_LIST_NEW_PROGRAM:
315
+ this.onProgramListNewProgram(Buffer.from(data));
316
+ break;
317
+ case utils_2.ReservedCommands.PROGRAM_LIST_CONTINUE_PROGRAM:
318
+ this.onProgramListContinueProgram();
319
+ break;
320
+ case utils_2.ReservedCommands.PROGRAM_LIST_END:
321
+ this.onProgramListEnd();
322
+ break;
323
+ case utils_2.ReservedCommands.PROGRAM_LIST_START:
324
+ this.onProgramListStart(Buffer.from(data));
325
+ break;
275
326
  }
276
327
  }
277
328
  onPersonSet(payload) {
278
329
  this.simulator.person = (0, utils_2.parsePersonData)(payload);
279
- this.emitData(this.createResponse('M70', Buffer.from('07000000', 'hex')));
330
+ if (this.simulator._isSimulateReservedError) {
331
+ this.emitData(this.createResponse('M70', Buffer.from('08000000', 'hex')));
332
+ this.simulator._isSimulateReservedError = false;
333
+ }
334
+ else
335
+ this.emitData(this.createResponse('M70', Buffer.from('07000000', 'hex'), true));
280
336
  }
281
337
  onPersonGet() {
282
338
  }
339
+ onProgramListBegin() {
340
+ if (this.simulator._isSimulateReservedError) {
341
+ this.emitData(this.createResponse('M70', Buffer.from('07000000', 'hex'), true));
342
+ this.simulator._isSimulateReservedError = false;
343
+ }
344
+ else
345
+ this.emitData(this.createResponse('M70', Buffer.from('08000000', 'hex'), true));
346
+ }
347
+ onProgramListNewProgram(payload) {
348
+ this.simulator.program = parseProgramListNewData(payload);
349
+ if (this.simulator._isSimulateReservedError) {
350
+ this.emitData(this.createResponse('M70', Buffer.from('08000000', 'hex'), true));
351
+ this.simulator._isSimulateReservedError = false;
352
+ }
353
+ else
354
+ this.emitData(this.createResponse('M70', Buffer.from('09000000', 'hex'), true));
355
+ }
356
+ onProgramListEnd() {
357
+ if (this.simulator._isSimulateReservedError) {
358
+ this.emitData(this.createResponse('M70', Buffer.from('08000000', 'hex'), true));
359
+ this.simulator._isSimulateReservedError = false;
360
+ }
361
+ else
362
+ this.emitData(this.createResponse('M70', Buffer.from('0B00010001', 'hex'), true));
363
+ }
364
+ onProgramListContinueProgram() {
365
+ if (this.simulator._isSimulateReservedError) {
366
+ this.emitData(this.createResponse('M70', Buffer.from('08000000', 'hex'), true));
367
+ this.simulator._isSimulateReservedError = false;
368
+ }
369
+ else
370
+ this.emitData(this.createResponse('M70', Buffer.from('0A00010001', 'hex'), true));
371
+ }
372
+ onProgramListStart(payload) {
373
+ if (this.simulator._isSimulateReservedError) {
374
+ this.emitData(this.createResponse('M70', Buffer.from('08000000', 'hex'), true));
375
+ this.simulator._isSimulateReservedError = false;
376
+ }
377
+ else {
378
+ try {
379
+ if (!this.simulator.program)
380
+ this.simulator.program = { lapMode: false };
381
+ this.simulator.program.id = payload.readInt16LE(0);
382
+ this.simulator.program.started = true;
383
+ }
384
+ catch (err) {
385
+ console.log('~~~ ERROR', payload, err, payload.toString('hex'));
386
+ }
387
+ this.emitData(this.createResponse('M70', Buffer.from('0C00000', 'hex'), true));
388
+ }
389
+ }
283
390
  onGetTrainingData(_payload) {
391
+ const GS = Buffer.from([0x1D]).toString();
392
+ const { time, heartrate, v, slope, distanceInternal, pedalRpm, power, physEnergy, realEnergy, torque, gear, deviceState, speedStatus } = this.simulator.data;
393
+ const res = `${time}` + GS +
394
+ `${heartrate}` + GS +
395
+ `${v}` + GS +
396
+ `${slope}` + GS +
397
+ `${distanceInternal}` + GS +
398
+ `${pedalRpm}` + GS +
399
+ `${power}` + GS +
400
+ `${physEnergy}` + GS +
401
+ `${realEnergy}` + GS +
402
+ `${torque}` + GS +
403
+ `${gear}` + GS +
404
+ `${deviceState}` + GS +
405
+ `${speedStatus}`;
406
+ this.emitData(this.createResponse('X70', Buffer.from(res)));
284
407
  }
285
408
  }
286
409
  exports.Daum8iMockBinding = Daum8iMockBinding;
@@ -1,8 +1,8 @@
1
1
  import CyclingMode, { CyclingModeProperty, IncyclistBikeData, Settings, UpdateRequest } from "../../../../modes/cycling-mode";
2
- import DaumAdapter from "../../DaumAdapter";
3
2
  import DaumPowerMeterCyclingMode from "../../DaumPowerMeterCyclingMode";
3
+ import { ControllableDeviceAdapter } from "../../../..";
4
4
  export default class DaumClassicCyclingMode extends DaumPowerMeterCyclingMode implements CyclingMode {
5
- constructor(adapter: DaumAdapter, props?: Settings);
5
+ constructor(adapter: ControllableDeviceAdapter, props?: Settings);
6
6
  getName(): string;
7
7
  getDescription(): string;
8
8
  getProperties(): CyclingModeProperty[];
@@ -16,7 +16,7 @@ const config = {
16
16
  class DaumClassicCyclingMode extends DaumPowerMeterCyclingMode_1.default {
17
17
  constructor(adapter, props) {
18
18
  super(adapter, props);
19
- this.logger = adapter ? adapter.logger : undefined;
19
+ this.logger = adapter ? adapter.getLogger() : undefined;
20
20
  if (!this.logger)
21
21
  this.logger = new gd_eventlog_1.EventLogger('DaumClassic');
22
22
  this.setModeProperty('eppSupport', true);
@@ -1,5 +1,21 @@
1
- import { DeviceProperties } from "../../../types/device";
1
+ import { DaumBikeData, DeviceProperties } from "../../../types/device";
2
2
  import { Route } from "../../../types/route";
3
+ import { Queue } from "../../../utils/utils";
4
+ import { Request, Response } from "../../comms";
5
+ export declare class CheckSumError extends Error {
6
+ constructor();
7
+ }
8
+ export declare class ACKTimeout extends Error {
9
+ constructor();
10
+ }
11
+ export declare class BusyTimeout extends Error {
12
+ constructor();
13
+ }
14
+ export declare class ResponseTimeout extends Error {
15
+ constructor();
16
+ }
17
+ export interface DaumPremiumBikeData extends DaumBikeData {
18
+ }
3
19
  export type OnDeviceStartCallback = (completed: number, total: number) => void;
4
20
  export type DaumPremiumAdapterProps = {
5
21
  path: string;
@@ -10,3 +26,21 @@ export interface Daum8iDeviceProperties extends DeviceProperties {
10
26
  gear?: number;
11
27
  onStatusUpdate?: OnDeviceStartCallback;
12
28
  }
29
+ export interface DaumPremiumRequest extends Request {
30
+ command: string;
31
+ payload?: string | Uint8Array;
32
+ }
33
+ export interface ResponseObject extends Response {
34
+ type: ResponseType;
35
+ cmd?: string;
36
+ data?: string;
37
+ error?: Error;
38
+ }
39
+ export type ResponseType = 'ACK' | 'NAK' | 'Response' | 'Error';
40
+ export type DaumPremiumCommsState = {
41
+ waitingForStart?: boolean;
42
+ waitingForACK?: boolean;
43
+ waitingForEnd?: boolean;
44
+ partialCmd?: any;
45
+ data: Queue<ResponseObject>;
46
+ };
@@ -1,2 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResponseTimeout = exports.BusyTimeout = exports.ACKTimeout = exports.CheckSumError = void 0;
4
+ class CheckSumError extends Error {
5
+ constructor() {
6
+ super();
7
+ this.message = 'checksum incorrect';
8
+ }
9
+ }
10
+ exports.CheckSumError = CheckSumError;
11
+ class ACKTimeout extends Error {
12
+ constructor() {
13
+ super();
14
+ this.message = 'ACK timeout';
15
+ }
16
+ }
17
+ exports.ACKTimeout = ACKTimeout;
18
+ class BusyTimeout extends Error {
19
+ constructor() {
20
+ super();
21
+ this.message = 'BUSY timeout';
22
+ }
23
+ }
24
+ exports.BusyTimeout = BusyTimeout;
25
+ class ResponseTimeout extends Error {
26
+ constructor() {
27
+ super();
28
+ this.message = 'RESP timeout';
29
+ }
30
+ }
31
+ exports.ResponseTimeout = ResponseTimeout;
@@ -1,13 +1,20 @@
1
1
  /// <reference types="node" />
2
+ import { IncyclistBikeData } from "../../..";
2
3
  import { Route } from "../../../types/route";
3
4
  import { User } from "../../../types/user";
4
- export declare function bin2esc(arr: any): any[];
5
- export declare function esc2bin(arr: any): any[];
5
+ export declare const DEBUG_LOGGER: {
6
+ log: (e: any, ...args: any[]) => void;
7
+ logEvent: (event: any) => void;
8
+ };
9
+ export declare const validateHost: (host: string) => string;
10
+ export declare const validatePath: (path: string) => string;
11
+ export declare function bin2esc(arr: Uint8Array): Uint8Array;
12
+ export declare function esc2bin(arr: Uint8Array): Uint8Array;
6
13
  export declare function checkSum(cmdArr: any, payload: any): string;
7
14
  export declare function buildMessage(command: any, payload?: any): any[];
8
15
  export declare function getMessageData(command: any): any[];
9
16
  export declare function hexstr(arr: any, start?: any, len?: any): string;
10
- export declare function ascii(c: any): any;
17
+ export declare function ascii(c: string): number;
11
18
  export declare function getAsciiArrayFromStr(str: any): any[];
12
19
  export declare enum ReservedCommands {
13
20
  RESULT_RESET = 0,
@@ -40,20 +47,6 @@ export declare const FileTimeSupport: {
40
47
  fromDate: (date: Date) => any;
41
48
  };
42
49
  export declare function routeToEpp(route: Route, date?: Date): Uint8Array;
43
- export declare function parseTrainingData(payload: string): {
44
- time: number;
45
- heartrate: number;
46
- speed: number;
47
- slope: number;
48
- distanceInternal: number;
49
- cadence: number;
50
- power: number;
51
- physEnergy: number;
52
- realEnergy: number;
53
- torque: number;
54
- gear: number;
55
- deviceState: number;
56
- speedStatus: string;
57
- };
50
+ export declare function parseTrainingData(payload: string): IncyclistBikeData;
58
51
  export declare function getPersonData(user: User): Buffer;
59
52
  export declare function parsePersonData(buffer: Buffer): User;
@@ -3,14 +3,31 @@ 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.parsePersonData = exports.getPersonData = exports.parseTrainingData = exports.routeToEpp = exports.FileTimeSupport = exports.getBikeType = exports.BikeType = exports.ReservedCommands = exports.getAsciiArrayFromStr = exports.ascii = exports.hexstr = exports.getMessageData = exports.buildMessage = exports.checkSum = exports.esc2bin = exports.bin2esc = void 0;
6
+ exports.parsePersonData = exports.getPersonData = exports.parseTrainingData = exports.routeToEpp = exports.FileTimeSupport = exports.getBikeType = exports.BikeType = exports.ReservedCommands = exports.getAsciiArrayFromStr = exports.ascii = exports.hexstr = exports.getMessageData = exports.buildMessage = exports.checkSum = exports.esc2bin = exports.bin2esc = exports.validatePath = exports.validateHost = exports.DEBUG_LOGGER = void 0;
7
7
  const user_1 = require("../../../types/user");
8
8
  const win32filetime_1 = __importDefault(require("win32filetime"));
9
9
  const sum = (arr) => arr.reduce((a, b) => a + b, 0);
10
+ exports.DEBUG_LOGGER = {
11
+ log: (e, ...args) => console.log(e, ...args),
12
+ logEvent: (event) => console.log(JSON.stringify(event))
13
+ };
14
+ const validateHost = (host) => {
15
+ const ipParts = host.split('.');
16
+ if (ipParts.length > 1)
17
+ return ipParts.map(p => Number(p)).join('.');
18
+ return host;
19
+ };
20
+ exports.validateHost = validateHost;
21
+ const validatePath = (path) => {
22
+ const parts = path.split(':');
23
+ if (parts.length < 2)
24
+ return path;
25
+ const host = (0, exports.validateHost)(parts[0]);
26
+ const port = parts[1];
27
+ return `${host}:${port}`;
28
+ };
29
+ exports.validatePath = validatePath;
10
30
  function bin2esc(arr) {
11
- if (arr === undefined) {
12
- return;
13
- }
14
31
  const res = [];
15
32
  arr.forEach(v => {
16
33
  switch (v) {
@@ -42,13 +59,10 @@ function bin2esc(arr) {
42
59
  res.push(v);
43
60
  }
44
61
  });
45
- return res;
62
+ return new Uint8Array(res);
46
63
  }
47
64
  exports.bin2esc = bin2esc;
48
65
  function esc2bin(arr) {
49
- if (arr === undefined) {
50
- return;
51
- }
52
66
  const res = [];
53
67
  let escaped = false;
54
68
  arr.forEach((v, idx) => {
@@ -84,7 +98,7 @@ function esc2bin(arr) {
84
98
  res.push(v);
85
99
  }
86
100
  });
87
- return res;
101
+ return new Uint8Array(res);
88
102
  }
89
103
  exports.esc2bin = esc2bin;
90
104
  function checkSum(cmdArr, payload) {
@@ -147,8 +161,6 @@ function hexstr(arr, start, len) {
147
161
  }
148
162
  exports.hexstr = hexstr;
149
163
  function ascii(c) {
150
- if (c === undefined || c === null)
151
- return;
152
164
  return c.charCodeAt(0);
153
165
  }
154
166
  exports.ascii = ascii;
@@ -258,7 +270,6 @@ function routeToEpp(route, date) {
258
270
  exports.routeToEpp = routeToEpp;
259
271
  function parseTrainingData(payload) {
260
272
  const GS = 0x1D;
261
- const speedVals = ['ok', 'too low', 'too high'];
262
273
  const gearVal = (v) => v > 0 ? v - 1 : undefined;
263
274
  const vals = payload.split(String.fromCharCode(GS));
264
275
  const data = {
@@ -267,15 +278,11 @@ function parseTrainingData(payload) {
267
278
  speed: parseFloat(vals[2]) * 3.6,
268
279
  slope: parseFloat(vals[3]),
269
280
  distanceInternal: parseInt(vals[4]),
270
- cadence: parseFloat(vals[5]),
281
+ pedalRpm: parseFloat(vals[5]),
271
282
  power: parseInt(vals[6]),
272
- physEnergy: parseFloat(vals[7]),
273
- realEnergy: parseFloat(vals[8]),
274
- torque: parseFloat(vals[9]),
275
283
  gear: gearVal(parseInt(vals[10])),
276
- deviceState: parseInt(vals[11]),
277
- speedStatus: speedVals[parseInt(vals[12])],
278
284
  };
285
+ data.isPedalling = (data.pedalRpm > 0);
279
286
  return data;
280
287
  }
281
288
  exports.parseTrainingData = parseTrainingData;
@@ -58,7 +58,7 @@ class SinglePathScanner {
58
58
  return;
59
59
  this.isScanning = true;
60
60
  return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
61
- this.logEvent({ message: 'starting scan', path: this.path });
61
+ this.logEvent({ message: 'starting scan', path: this.path, interface: this.serial.getName() });
62
62
  this.serial.scanEvents.on('timeout', () => this.onStopRequest(resolve));
63
63
  this.serial.scanEvents.on('stop', () => this.onStopRequest(resolve));
64
64
  let found = false;
@@ -78,6 +78,7 @@ class SinglePathScanner {
78
78
  if (found) {
79
79
  this.isFound = true;
80
80
  const name = adapter.getName();
81
+ yield adapter.close();
81
82
  resolve(Object.assign(Object.assign({}, adapterSettings), { name }));
82
83
  }
83
84
  yield (0, utils_1.sleep)(100);
@@ -166,9 +167,11 @@ class SerialInterface extends events_1.default {
166
167
  }
167
168
  connect() {
168
169
  return __awaiter(this, void 0, void 0, function* () {
170
+ this.logEvent({ message: 'connecting', interface: this.ifaceName });
169
171
  const binding = serialport_1.default.getInstance().getBinding(this.ifaceName);
170
172
  if (!binding || !this.binding) {
171
173
  this.connected = false;
174
+ this.logEvent({ message: 'connecting error', interface: this.ifaceName, reason: 'no binfing found' });
172
175
  return false;
173
176
  }
174
177
  try {
@@ -178,6 +181,7 @@ class SerialInterface extends events_1.default {
178
181
  return true;
179
182
  }
180
183
  catch (err) {
184
+ this.logEvent({ message: 'connecting error', interface: this.ifaceName, reason: err.message });
181
185
  this.connected = false;
182
186
  return false;
183
187
  }
@@ -210,7 +214,7 @@ class SerialInterface extends events_1.default {
210
214
  }
211
215
  return new Promise((resolve) => {
212
216
  port.once('error', (err) => {
213
- this.logEvent({ message: 'error', path, error: err.message || err });
217
+ this.logEvent({ message: 'error', path, error: err.message || err, stack: err.stack });
214
218
  port.removeAllListeners();
215
219
  resolve(null);
216
220
  });
@@ -273,14 +277,15 @@ class SerialInterface extends events_1.default {
273
277
  }
274
278
  this.isScanning = true;
275
279
  let attemptNo = 0;
280
+ const isTcpip = this.getName() === 'tcpip';
276
281
  do {
277
282
  if (attemptNo === 0)
278
- this.logEvent({ message: 'checking for ports', port, excludes: this.inUse });
283
+ this.logEvent({ message: 'checking for ports', interface: this.ifaceName, port, excludes: this.inUse });
279
284
  else
280
- this.logEvent({ message: 'checking for ports retry', retry: attemptNo });
285
+ this.logEvent({ message: 'checking for ports retry', interface: this.ifaceName, retry: attemptNo });
281
286
  attemptNo++;
282
287
  try {
283
- if (this.getName() === 'tcpip') {
288
+ if (isTcpip) {
284
289
  const _binding = binding;
285
290
  paths = (yield _binding.list(port, this.inUse)) || [];
286
291
  }
@@ -289,8 +294,9 @@ class SerialInterface extends events_1.default {
289
294
  }
290
295
  }
291
296
  catch (err) {
292
- console.log('~~~ERROR', err);
297
+ this.logEvent({ message: 'error', fn: 'scan#detect ports', error: err.message, interface: this.ifaceName, port, excludes: this.inUse });
293
298
  }
299
+ paths = paths.filter(p => !this.inUse.includes(p.path));
294
300
  if (!paths || paths.length === 0) {
295
301
  this.logEvent({ message: 'scanning: no ports detected', interface: this.ifaceName, paths: paths.map(p => p.path), timeout });
296
302
  yield (0, utils_1.sleep)(1000);
@@ -298,7 +304,6 @@ class SerialInterface extends events_1.default {
298
304
  if (Date.now() > toExpiresAt)
299
305
  timeOutExpired = true;
300
306
  } while (this.isScanning && !timeOutExpired && paths.length === 0);
301
- paths = paths.filter(p => !this.inUse.includes(p.path));
302
307
  if (paths.length === 0) {
303
308
  this.logEvent({ message: 'nothing to scan ' });
304
309
  if (this.toScan) {
@@ -307,19 +312,20 @@ class SerialInterface extends events_1.default {
307
312
  }
308
313
  return [];
309
314
  }
310
- this.logEvent({ message: 'scanning on ', paths: paths.map(p => p.path), timeout });
315
+ this.logEvent({ message: 'scanning on ', interface: this.ifaceName, paths: paths.map(p => p.path).join(','), timeout });
311
316
  const scanners = paths.map(p => new SinglePathScanner(p.path, this, Object.assign(Object.assign({}, props), { logger: this.logger })));
312
317
  try {
313
318
  yield Promise.all(scanners.map(s => s.scan()
314
- .then(device => {
319
+ .then((device) => __awaiter(this, void 0, void 0, function* () {
315
320
  if (device) {
316
321
  const adapter = adapter_factory_1.default.getInstance().createInstance(device);
317
322
  const path = adapter.getPort();
318
323
  this.inUse.push(path);
324
+ yield adapter.stop();
319
325
  detected.push(device);
320
326
  this.emit('device', device);
321
327
  }
322
- })
328
+ }))
323
329
  .catch()));
324
330
  }
325
331
  catch (err) {
@@ -346,6 +352,7 @@ class SerialInterface extends events_1.default {
346
352
  clearTimeout(this.toScan);
347
353
  this.toScan = null;
348
354
  }
355
+ this.isScanning = false;
349
356
  this.scanEvents.emit('stop');
350
357
  return true;
351
358
  });
@@ -5,8 +5,10 @@ import { IncyclistCapability } from "./capabilities";
5
5
  import { DeviceData } from "./data";
6
6
  import { DeviceProperties, DeviceSettings } from "./device";
7
7
  import { User } from "./user";
8
+ import { EventLogger } from "gd-eventlog";
8
9
  export type OnDeviceDataCallback = (data: DeviceData) => void;
9
10
  export interface IncyclistDeviceAdapter extends EventEmitter {
11
+ getLogger(): EventLogger;
10
12
  connect(): Promise<boolean>;
11
13
  close(): Promise<boolean>;
12
14
  check(): Promise<boolean>;
@@ -9,11 +9,22 @@ export declare const INTERFACE: {
9
9
  USB: string;
10
10
  SIMULATOR: string;
11
11
  };
12
+ export type DeviceType = 'race' | 'mountain' | 'triathlon';
12
13
  export type Device = {
13
14
  getID(): string;
14
15
  getName(): string;
15
16
  getInterface(): string;
16
17
  };
18
+ export type DaumBikeData = {
19
+ cadence: number;
20
+ speed: number;
21
+ power: number;
22
+ heartrate: number;
23
+ distanceInternal: number;
24
+ gear: number;
25
+ time: number;
26
+ slope?: number;
27
+ };
17
28
  export type DeviceProperties = {
18
29
  user?: User;
19
30
  userWeight?: number;