incyclist-devices 2.0.35 → 2.0.37
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/antv2/modes/ant-fe-adv-st-mode.d.ts +2 -2
- package/lib/antv2/modes/ant-fe-erg-mode.d.ts +2 -2
- package/lib/antv2/modes/ant-fe-st-mode.d.ts +2 -2
- package/lib/base/adpater.d.ts +2 -1
- package/lib/base/adpater.js +7 -6
- package/lib/interfaces.d.ts +1 -1
- package/lib/modes/ble-erg-mode.d.ts +2 -2
- package/lib/modes/ble-st-mode.d.ts +2 -2
- package/lib/modes/cycling-mode.d.ts +7 -7
- package/lib/modes/power-base.d.ts +3 -3
- package/lib/modes/power-base.js +3 -2
- package/lib/modes/power-meter.d.ts +2 -2
- package/lib/serial/comms.d.ts +62 -0
- package/lib/serial/comms.js +280 -0
- package/lib/serial/daum/DaumAdapter.d.ts +13 -8
- package/lib/serial/daum/DaumAdapter.js +49 -12
- package/lib/serial/daum/ERGCyclingMode.d.ts +2 -2
- package/lib/serial/daum/ERGCyclingMode.js +1 -1
- package/lib/serial/daum/SmartTrainerCyclingMode.d.ts +3 -2
- package/lib/serial/daum/SmartTrainerCyclingMode.js +10 -5
- package/lib/serial/daum/classic/adapter.d.ts +4 -6
- package/lib/serial/daum/classic/adapter.js +5 -23
- package/lib/serial/daum/classic/comms.d.ts +33 -65
- package/lib/serial/daum/classic/comms.js +148 -332
- package/lib/serial/daum/classic/mock.js +5 -3
- package/lib/serial/daum/classic/modes/daum-classic.d.ts +2 -2
- package/lib/serial/daum/classic/modes/daum-classic.js +1 -1
- package/lib/serial/daum/classic/types.d.ts +59 -0
- package/lib/serial/daum/classic/types.js +2 -0
- package/lib/serial/daum/classic/utils.d.ts +11 -10
- package/lib/serial/daum/classic/utils.js +33 -68
- package/lib/serial/daum/premium/adapter.d.ts +4 -7
- package/lib/serial/daum/premium/adapter.js +7 -30
- package/lib/serial/daum/premium/comms.d.ts +28 -105
- package/lib/serial/daum/premium/comms.js +262 -466
- package/lib/serial/daum/premium/consts.d.ts +6 -0
- package/lib/serial/daum/premium/consts.js +9 -0
- package/lib/serial/daum/premium/mock.d.ts +32 -1
- package/lib/serial/daum/premium/mock.js +131 -8
- package/lib/serial/daum/premium/modes/daum-classic.d.ts +2 -2
- package/lib/serial/daum/premium/modes/daum-classic.js +1 -1
- package/lib/serial/daum/premium/types.d.ts +35 -1
- package/lib/serial/daum/premium/types.js +29 -0
- package/lib/serial/daum/premium/utils.d.ts +12 -18
- package/lib/serial/daum/premium/utils.js +34 -19
- package/lib/serial/serial-interface.js +3 -2
- package/lib/types/adapter.d.ts +2 -0
- package/lib/types/device.d.ts +11 -0
- package/lib/types/route.d.ts +0 -5
- package/lib/types/route.js +0 -7
- package/lib/utils/calculations.js +1 -5
- package/lib/utils/utils.d.ts +2 -1
- package/lib/utils/utils.js +39 -3
- 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
|
-
|
|
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
|
|
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:
|
|
274
|
-
|
|
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
|
-
|
|
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:
|
|
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.
|
|
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,21 @@
|
|
|
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
|
|
5
|
-
|
|
5
|
+
export declare const DEBUG_LOGGER: {
|
|
6
|
+
log: (e: any, ...args: any[]) => void;
|
|
7
|
+
logEvent: (event: any) => void;
|
|
8
|
+
};
|
|
9
|
+
export declare function responseLog(str: string): string;
|
|
10
|
+
export declare const validateHost: (host: string) => string;
|
|
11
|
+
export declare const validatePath: (path: string) => string;
|
|
12
|
+
export declare function bin2esc(arr: Uint8Array): Uint8Array;
|
|
13
|
+
export declare function esc2bin(arr: Uint8Array): Uint8Array;
|
|
6
14
|
export declare function checkSum(cmdArr: any, payload: any): string;
|
|
7
15
|
export declare function buildMessage(command: any, payload?: any): any[];
|
|
8
16
|
export declare function getMessageData(command: any): any[];
|
|
9
17
|
export declare function hexstr(arr: any, start?: any, len?: any): string;
|
|
10
|
-
export declare function ascii(c:
|
|
18
|
+
export declare function ascii(c: string): number;
|
|
11
19
|
export declare function getAsciiArrayFromStr(str: any): any[];
|
|
12
20
|
export declare enum ReservedCommands {
|
|
13
21
|
RESULT_RESET = 0,
|
|
@@ -40,20 +48,6 @@ export declare const FileTimeSupport: {
|
|
|
40
48
|
fromDate: (date: Date) => any;
|
|
41
49
|
};
|
|
42
50
|
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
|
-
};
|
|
51
|
+
export declare function parseTrainingData(payload: string): IncyclistBikeData;
|
|
58
52
|
export declare function getPersonData(user: User): Buffer;
|
|
59
53
|
export declare function parsePersonData(buffer: Buffer): User;
|
|
@@ -3,14 +3,40 @@ 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.responseLog = 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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
exports.DEBUG_LOGGER = {
|
|
11
|
+
log: (e, ...args) => console.log(e, ...args),
|
|
12
|
+
logEvent: (event) => console.log(JSON.stringify(event))
|
|
13
|
+
};
|
|
14
|
+
const GS = 0x1D;
|
|
15
|
+
const GS_CHAR = String.fromCharCode(GS);
|
|
16
|
+
function responseLog(str) {
|
|
17
|
+
if (str.includes(GS_CHAR)) {
|
|
18
|
+
return str.split(GS_CHAR).join('/');
|
|
13
19
|
}
|
|
20
|
+
return str;
|
|
21
|
+
}
|
|
22
|
+
exports.responseLog = responseLog;
|
|
23
|
+
const validateHost = (host) => {
|
|
24
|
+
const ipParts = host.split('.');
|
|
25
|
+
if (ipParts.length > 1)
|
|
26
|
+
return ipParts.map(p => Number(p)).join('.');
|
|
27
|
+
return host;
|
|
28
|
+
};
|
|
29
|
+
exports.validateHost = validateHost;
|
|
30
|
+
const validatePath = (path) => {
|
|
31
|
+
const parts = path.split(':');
|
|
32
|
+
if (parts.length < 2)
|
|
33
|
+
return path;
|
|
34
|
+
const host = (0, exports.validateHost)(parts[0]);
|
|
35
|
+
const port = parts[1];
|
|
36
|
+
return `${host}:${port}`;
|
|
37
|
+
};
|
|
38
|
+
exports.validatePath = validatePath;
|
|
39
|
+
function bin2esc(arr) {
|
|
14
40
|
const res = [];
|
|
15
41
|
arr.forEach(v => {
|
|
16
42
|
switch (v) {
|
|
@@ -42,13 +68,10 @@ function bin2esc(arr) {
|
|
|
42
68
|
res.push(v);
|
|
43
69
|
}
|
|
44
70
|
});
|
|
45
|
-
return res;
|
|
71
|
+
return new Uint8Array(res);
|
|
46
72
|
}
|
|
47
73
|
exports.bin2esc = bin2esc;
|
|
48
74
|
function esc2bin(arr) {
|
|
49
|
-
if (arr === undefined) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
75
|
const res = [];
|
|
53
76
|
let escaped = false;
|
|
54
77
|
arr.forEach((v, idx) => {
|
|
@@ -84,7 +107,7 @@ function esc2bin(arr) {
|
|
|
84
107
|
res.push(v);
|
|
85
108
|
}
|
|
86
109
|
});
|
|
87
|
-
return res;
|
|
110
|
+
return new Uint8Array(res);
|
|
88
111
|
}
|
|
89
112
|
exports.esc2bin = esc2bin;
|
|
90
113
|
function checkSum(cmdArr, payload) {
|
|
@@ -147,8 +170,6 @@ function hexstr(arr, start, len) {
|
|
|
147
170
|
}
|
|
148
171
|
exports.hexstr = hexstr;
|
|
149
172
|
function ascii(c) {
|
|
150
|
-
if (c === undefined || c === null)
|
|
151
|
-
return;
|
|
152
173
|
return c.charCodeAt(0);
|
|
153
174
|
}
|
|
154
175
|
exports.ascii = ascii;
|
|
@@ -257,8 +278,6 @@ function routeToEpp(route, date) {
|
|
|
257
278
|
}
|
|
258
279
|
exports.routeToEpp = routeToEpp;
|
|
259
280
|
function parseTrainingData(payload) {
|
|
260
|
-
const GS = 0x1D;
|
|
261
|
-
const speedVals = ['ok', 'too low', 'too high'];
|
|
262
281
|
const gearVal = (v) => v > 0 ? v - 1 : undefined;
|
|
263
282
|
const vals = payload.split(String.fromCharCode(GS));
|
|
264
283
|
const data = {
|
|
@@ -267,15 +286,11 @@ function parseTrainingData(payload) {
|
|
|
267
286
|
speed: parseFloat(vals[2]) * 3.6,
|
|
268
287
|
slope: parseFloat(vals[3]),
|
|
269
288
|
distanceInternal: parseInt(vals[4]),
|
|
270
|
-
|
|
289
|
+
pedalRpm: parseFloat(vals[5]),
|
|
271
290
|
power: parseInt(vals[6]),
|
|
272
|
-
physEnergy: parseFloat(vals[7]),
|
|
273
|
-
realEnergy: parseFloat(vals[8]),
|
|
274
|
-
torque: parseFloat(vals[9]),
|
|
275
291
|
gear: gearVal(parseInt(vals[10])),
|
|
276
|
-
deviceState: parseInt(vals[11]),
|
|
277
|
-
speedStatus: speedVals[parseInt(vals[12])],
|
|
278
292
|
};
|
|
293
|
+
data.isPedalling = (data.pedalRpm > 0);
|
|
279
294
|
return data;
|
|
280
295
|
}
|
|
281
296
|
exports.parseTrainingData = parseTrainingData;
|
|
@@ -294,8 +294,9 @@ class SerialInterface extends events_1.default {
|
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
catch (err) {
|
|
297
|
-
|
|
297
|
+
this.logEvent({ message: 'error', fn: 'scan#detect ports', error: err.message, interface: this.ifaceName, port, excludes: this.inUse });
|
|
298
298
|
}
|
|
299
|
+
paths = paths.filter(p => !this.inUse.includes(p.path));
|
|
299
300
|
if (!paths || paths.length === 0) {
|
|
300
301
|
this.logEvent({ message: 'scanning: no ports detected', interface: this.ifaceName, paths: paths.map(p => p.path), timeout });
|
|
301
302
|
yield (0, utils_1.sleep)(1000);
|
|
@@ -303,7 +304,6 @@ class SerialInterface extends events_1.default {
|
|
|
303
304
|
if (Date.now() > toExpiresAt)
|
|
304
305
|
timeOutExpired = true;
|
|
305
306
|
} while (this.isScanning && !timeOutExpired && paths.length === 0);
|
|
306
|
-
paths = paths.filter(p => !this.inUse.includes(p.path));
|
|
307
307
|
if (paths.length === 0) {
|
|
308
308
|
this.logEvent({ message: 'nothing to scan ' });
|
|
309
309
|
if (this.toScan) {
|
|
@@ -352,6 +352,7 @@ class SerialInterface extends events_1.default {
|
|
|
352
352
|
clearTimeout(this.toScan);
|
|
353
353
|
this.toScan = null;
|
|
354
354
|
}
|
|
355
|
+
this.isScanning = false;
|
|
355
356
|
this.scanEvents.emit('stop');
|
|
356
357
|
return true;
|
|
357
358
|
});
|
package/lib/types/adapter.d.ts
CHANGED
|
@@ -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>;
|
package/lib/types/device.d.ts
CHANGED
|
@@ -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;
|
package/lib/types/route.d.ts
CHANGED
package/lib/types/route.js
CHANGED
|
@@ -1,9 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RouteType = void 0;
|
|
4
|
-
var RouteType;
|
|
5
|
-
(function (RouteType) {
|
|
6
|
-
RouteType["FREE_RIDE"] = "free ride";
|
|
7
|
-
RouteType["FOLLOW_ROUTE"] = "follow route";
|
|
8
|
-
RouteType["VIDEO"] = "video";
|
|
9
|
-
})(RouteType || (exports.RouteType = RouteType = {}));
|
|
@@ -22,8 +22,6 @@ class C {
|
|
|
22
22
|
throw new IllegalArgumentException("m must be a positive number");
|
|
23
23
|
if (power === undefined || power === null || power < 0)
|
|
24
24
|
throw new IllegalArgumentException("power must be a positive number");
|
|
25
|
-
if (slope === undefined || slope === null)
|
|
26
|
-
slope = 0;
|
|
27
25
|
const _rho = props.rho || rho;
|
|
28
26
|
const _cRR = props.cRR || cRR;
|
|
29
27
|
const _cwA = props.cwA || cwABike[props.bikeType || 'race'] || cwABike.race;
|
|
@@ -64,11 +62,9 @@ class C {
|
|
|
64
62
|
throw new IllegalArgumentException("m must be a positive number");
|
|
65
63
|
if (v === undefined || v === null || v < 0)
|
|
66
64
|
throw new IllegalArgumentException("v must be a positive number");
|
|
67
|
-
if (slope === undefined || slope === null)
|
|
68
|
-
slope = 0;
|
|
69
65
|
let _rho = props.rho || rho;
|
|
70
66
|
let _cRR = props.cRR || cRR;
|
|
71
|
-
let _cwA = props.cwA || cwABike[props.bikeType || 'race']
|
|
67
|
+
let _cwA = props.cwA || cwABike[props.bikeType || 'race'];
|
|
72
68
|
let sl = Math.sin(Math.atan(slope / 100));
|
|
73
69
|
let P = (0.5 * _rho * _cwA) * Math.pow(v, 3.0) + (sl + _cRR) * m * g * v;
|
|
74
70
|
return P;
|
package/lib/utils/utils.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare function floatVal(d?: number | string): number;
|
|
|
5
5
|
export declare function intVal(d?: number | string): number;
|
|
6
6
|
export declare function hexstr(arr: any, start?: any, len?: any): string;
|
|
7
7
|
export declare class Queue<T> {
|
|
8
|
-
data: Array<T>;
|
|
8
|
+
protected data: Array<T>;
|
|
9
9
|
constructor(values?: Array<T>);
|
|
10
10
|
size(): number;
|
|
11
11
|
clear(): void;
|
|
@@ -13,3 +13,4 @@ export declare class Queue<T> {
|
|
|
13
13
|
dequeue(): T;
|
|
14
14
|
enqueue(value: T): void;
|
|
15
15
|
}
|
|
16
|
+
export declare function waitWithTimeout(promise: Promise<any>, timeout: number, onTimeout?: () => void): Promise<any>;
|