incyclist-devices 1.4.4 → 1.4.7
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/CyclingMode.d.ts +0 -1
- package/lib/Device.d.ts +14 -1
- package/lib/Device.js +1 -0
- package/lib/daum/DaumAdapter.d.ts +5 -4
- package/lib/daum/DaumAdapter.js +40 -33
- package/lib/daum/ERGCyclingMode.js +2 -5
- package/lib/daum/PowerMeterCyclingMode.js +0 -1
- package/lib/daum/classic/DaumClassicAdapter.js +6 -1
- package/lib/daum/classic/DaumClassicCyclingMode.js +0 -1
- package/lib/daum/classic/utils.js +1 -1
- package/lib/daum/premium/DaumClassicCyclingMode.js +0 -1
- package/lib/daum/premium/DaumPremiumAdapter.d.ts +0 -2
- package/lib/daum/premium/DaumPremiumAdapter.js +11 -25
- package/lib/daum/premium/bike.d.ts +5 -4
- package/lib/daum/premium/bike.js +35 -18
- package/lib/daum/premium/utils.d.ts +1 -1
- package/lib/daum/premium/utils.js +42 -41
- package/lib/types/route.d.ts +3 -0
- package/package.json +1 -1
package/lib/CyclingMode.d.ts
CHANGED
package/lib/Device.d.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { DeviceProtocol, Device } from './DeviceProtocol';
|
|
2
2
|
import CyclingMode from './CyclingMode';
|
|
3
|
-
export declare type
|
|
3
|
+
export declare type DeviceData = {
|
|
4
|
+
speed?: number;
|
|
5
|
+
slope?: number;
|
|
6
|
+
power?: number;
|
|
7
|
+
cadence?: number;
|
|
8
|
+
heartrate?: number;
|
|
9
|
+
distance?: number;
|
|
10
|
+
timestamp?: number;
|
|
11
|
+
deviceTime?: number;
|
|
12
|
+
deviceDistanceCounter?: number;
|
|
13
|
+
};
|
|
14
|
+
export declare type OnDeviceDataCallback = (data: DeviceData) => void;
|
|
15
|
+
export declare type OnDeviceStartCallback = (completed: number, total: number) => void;
|
|
4
16
|
export interface Bike {
|
|
5
17
|
setCyclingMode(mode: CyclingMode | string, settings?: any): void;
|
|
6
18
|
getSupportedCyclingModes(): Array<any>;
|
|
@@ -49,6 +61,7 @@ export default class DeviceAdapterBase implements DeviceAdapter {
|
|
|
49
61
|
getPort(): string;
|
|
50
62
|
getProtocol(): DeviceProtocol;
|
|
51
63
|
getProtocolName(): string | undefined;
|
|
64
|
+
setCyclingMode(mode: CyclingMode | string, settings?: any): void;
|
|
52
65
|
setIgnoreHrm(ignore: any): void;
|
|
53
66
|
setIgnorePower(ignore: any): void;
|
|
54
67
|
setIgnoreBike(ignore: any): void;
|
package/lib/Device.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EventLogger } from 'gd-eventlog';
|
|
2
|
-
import CyclingMode from '../CyclingMode';
|
|
3
|
-
import DeviceAdapterBase, { Bike, DeviceAdapter } from '../Device';
|
|
2
|
+
import CyclingMode, { IncyclistBikeData } from '../CyclingMode';
|
|
3
|
+
import DeviceAdapterBase, { Bike, DeviceAdapter, DeviceData } from '../Device';
|
|
4
4
|
import { User } from '../types/user';
|
|
5
5
|
interface DaumAdapter {
|
|
6
6
|
getCurrentBikeData(): Promise<any>;
|
|
@@ -13,7 +13,8 @@ export default class DaumAdapterBase extends DeviceAdapterBase implements Device
|
|
|
13
13
|
distanceInternal: number;
|
|
14
14
|
paused: boolean;
|
|
15
15
|
stopped: boolean;
|
|
16
|
-
|
|
16
|
+
daumRunData: IncyclistBikeData;
|
|
17
|
+
deviceData: DeviceData;
|
|
17
18
|
currentRequest: any;
|
|
18
19
|
requests: Array<any>;
|
|
19
20
|
iv: any;
|
|
@@ -56,7 +57,7 @@ export default class DaumAdapterBase extends DeviceAdapterBase implements Device
|
|
|
56
57
|
sendRequests(): Promise<void>;
|
|
57
58
|
bikeSync(): Promise<void>;
|
|
58
59
|
updateData(prev: any, bikeData: any): void;
|
|
59
|
-
transformData():
|
|
60
|
+
transformData(): DeviceData;
|
|
60
61
|
sendRequest(request: any): Promise<any>;
|
|
61
62
|
refreshRequests(): void;
|
|
62
63
|
processClientRequest(request: any): Promise<unknown>;
|
package/lib/daum/DaumAdapter.js
CHANGED
|
@@ -29,7 +29,16 @@ class DaumAdapterBase extends Device_1.default {
|
|
|
29
29
|
this.bike = bike;
|
|
30
30
|
this.stopped = false;
|
|
31
31
|
this.paused = false;
|
|
32
|
-
this.
|
|
32
|
+
this.daumRunData = {
|
|
33
|
+
isPedalling: false,
|
|
34
|
+
time: 0,
|
|
35
|
+
power: 0,
|
|
36
|
+
pedalRpm: 0,
|
|
37
|
+
speed: 0,
|
|
38
|
+
distanceInternal: 0,
|
|
39
|
+
heartrate: 0
|
|
40
|
+
};
|
|
41
|
+
this.deviceData = {};
|
|
33
42
|
const options = props || {};
|
|
34
43
|
this.cyclingMode = options.cyclingMode;
|
|
35
44
|
this.setUserSettings(options.userSettings);
|
|
@@ -114,15 +123,16 @@ class DaumAdapterBase extends Device_1.default {
|
|
|
114
123
|
this.distanceInternal = undefined;
|
|
115
124
|
this.paused = false;
|
|
116
125
|
this.stopped = false;
|
|
117
|
-
this.
|
|
118
|
-
time: 0,
|
|
119
|
-
slope: 0,
|
|
120
|
-
distance: 0,
|
|
121
|
-
speed: 0,
|
|
126
|
+
this.daumRunData = {
|
|
122
127
|
isPedalling: false,
|
|
128
|
+
time: 0,
|
|
123
129
|
power: 0,
|
|
124
|
-
|
|
130
|
+
pedalRpm: 0,
|
|
131
|
+
speed: 0,
|
|
132
|
+
distanceInternal: 0,
|
|
133
|
+
heartrate: 0
|
|
125
134
|
};
|
|
135
|
+
this.deviceData = {};
|
|
126
136
|
this.currentRequest = {};
|
|
127
137
|
this.requests = [];
|
|
128
138
|
const name = this.getCyclingMode().getName();
|
|
@@ -200,14 +210,14 @@ class DaumAdapterBase extends Device_1.default {
|
|
|
200
210
|
}
|
|
201
211
|
sendData() {
|
|
202
212
|
if (this.onDataFn)
|
|
203
|
-
this.onDataFn(this.
|
|
213
|
+
this.onDataFn(this.deviceData);
|
|
204
214
|
}
|
|
205
215
|
update() {
|
|
206
216
|
return __awaiter(this, void 0, void 0, function* () {
|
|
207
217
|
this.updateBusy = true;
|
|
208
218
|
this.getCurrentBikeData()
|
|
209
219
|
.then(bikeData => {
|
|
210
|
-
this.updateData(this.
|
|
220
|
+
this.updateData(this.daumRunData, bikeData);
|
|
211
221
|
this.transformData();
|
|
212
222
|
this.updateBusy = false;
|
|
213
223
|
})
|
|
@@ -262,35 +272,32 @@ class DaumAdapterBase extends Device_1.default {
|
|
|
262
272
|
data.pedalRpm = bikeData.cadence;
|
|
263
273
|
data.speed = bikeData.speed;
|
|
264
274
|
data.heartrate = bikeData.heartrate;
|
|
265
|
-
data.
|
|
266
|
-
data.distanceInternal = bikeData.distance;
|
|
275
|
+
data.distanceInternal = bikeData.distanceInternal;
|
|
267
276
|
data.gear = bikeData.gear;
|
|
268
|
-
|
|
269
|
-
this.adapterTime = Date.now() - this.tsPrevData;
|
|
270
|
-
}
|
|
271
|
-
this.tsPrevData = Date.now();
|
|
272
|
-
data.time = Math.round(this.adapterTime || 0);
|
|
277
|
+
data.time = bikeData.time;
|
|
273
278
|
if (bikeData.slope)
|
|
274
279
|
data.slope = bikeData.slope;
|
|
275
|
-
this.
|
|
280
|
+
this.daumRunData = this.getCyclingMode().updateData(data);
|
|
276
281
|
}
|
|
277
282
|
transformData() {
|
|
278
|
-
if (this.
|
|
283
|
+
if (this.daumRunData === undefined)
|
|
279
284
|
return;
|
|
280
285
|
let distance = 0;
|
|
281
|
-
if (this.distanceInternal !== undefined && this.
|
|
282
|
-
distance = (0, utils_1.intVal)(this.
|
|
286
|
+
if (this.distanceInternal !== undefined && this.daumRunData.distanceInternal !== undefined) {
|
|
287
|
+
distance = (0, utils_1.intVal)(this.daumRunData.distanceInternal - this.distanceInternal);
|
|
283
288
|
}
|
|
284
|
-
if (this.
|
|
285
|
-
this.distanceInternal = this.
|
|
289
|
+
if (this.daumRunData.distanceInternal !== undefined)
|
|
290
|
+
this.distanceInternal = this.daumRunData.distanceInternal;
|
|
286
291
|
let data = {
|
|
287
|
-
speed: (0, utils_1.floatVal)(this.
|
|
288
|
-
slope: (0, utils_1.floatVal)(this.
|
|
289
|
-
power: (0, utils_1.intVal)(this.
|
|
290
|
-
cadence: (0, utils_1.intVal)(this.
|
|
291
|
-
heartrate: (0, utils_1.intVal)(this.
|
|
292
|
+
speed: (0, utils_1.floatVal)(this.daumRunData.speed),
|
|
293
|
+
slope: (0, utils_1.floatVal)(this.daumRunData.slope),
|
|
294
|
+
power: (0, utils_1.intVal)(this.daumRunData.power),
|
|
295
|
+
cadence: (0, utils_1.intVal)(this.daumRunData.pedalRpm),
|
|
296
|
+
heartrate: (0, utils_1.intVal)(this.daumRunData.heartrate),
|
|
292
297
|
distance,
|
|
293
|
-
timestamp: Date.now()
|
|
298
|
+
timestamp: Date.now(),
|
|
299
|
+
deviceTime: this.daumRunData.time,
|
|
300
|
+
deviceDistanceCounter: this.daumRunData.distanceInternal
|
|
294
301
|
};
|
|
295
302
|
if (this.ignoreHrm)
|
|
296
303
|
delete data.heartrate;
|
|
@@ -301,7 +308,7 @@ class DaumAdapterBase extends Device_1.default {
|
|
|
301
308
|
if (this.ignoreBike) {
|
|
302
309
|
data = { heartrate: data.heartrate };
|
|
303
310
|
}
|
|
304
|
-
this.
|
|
311
|
+
this.deviceData = data;
|
|
305
312
|
}
|
|
306
313
|
sendRequest(request) {
|
|
307
314
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -331,10 +338,10 @@ class DaumAdapterBase extends Device_1.default {
|
|
|
331
338
|
});
|
|
332
339
|
}
|
|
333
340
|
refreshRequests() {
|
|
334
|
-
if (!this.
|
|
341
|
+
if (!this.daumRunData.isPedalling || this.daumRunData.pedalRpm === 0)
|
|
335
342
|
return;
|
|
336
|
-
let bikeRequest = this.getCyclingMode().sendBikeUpdate({ refresh: true });
|
|
337
|
-
const prev = this.requests[this.requests.length - 1];
|
|
343
|
+
let bikeRequest = this.getCyclingMode().sendBikeUpdate({ refresh: true }) || {};
|
|
344
|
+
const prev = this.requests[this.requests.length - 1] || {};
|
|
338
345
|
if (bikeRequest.targetPower !== undefined && bikeRequest.targetPower !== prev.targetPower) {
|
|
339
346
|
this.logEvent({ message: 'add request', request: bikeRequest });
|
|
340
347
|
this.requests.push(bikeRequest);
|
|
@@ -342,7 +349,7 @@ class DaumAdapterBase extends Device_1.default {
|
|
|
342
349
|
}
|
|
343
350
|
processClientRequest(request) {
|
|
344
351
|
if (request.slope !== undefined) {
|
|
345
|
-
this.
|
|
352
|
+
this.daumRunData.slope = request.slope;
|
|
346
353
|
}
|
|
347
354
|
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
|
348
355
|
let bikeRequest = this.getCyclingMode().sendBikeUpdate(request);
|
|
@@ -146,7 +146,6 @@ class ERGCyclingMode extends CyclingMode_1.CyclingModeBase {
|
|
|
146
146
|
let speed;
|
|
147
147
|
let m = this.adapter.getWeight();
|
|
148
148
|
let distanceInternal = prevData.distanceInternal || 0;
|
|
149
|
-
let distance = Math.round(distanceInternal / 100);
|
|
150
149
|
let ts = Date.now();
|
|
151
150
|
let duration = this.prevUpdateTS === 0 ? 0 : ((ts - this.prevUpdateTS) / 1000);
|
|
152
151
|
if (rpm === 0 || bikeData.isPedalling === false) {
|
|
@@ -157,16 +156,14 @@ class ERGCyclingMode extends CyclingMode_1.CyclingModeBase {
|
|
|
157
156
|
speed = calculations_1.default.calculateSpeed(m, power, slope, { bikeType });
|
|
158
157
|
let v = speed / 3.6;
|
|
159
158
|
distanceInternal += Math.round(v * duration);
|
|
160
|
-
distance = Math.round(distanceInternal / 100);
|
|
161
159
|
}
|
|
162
160
|
data.speed = parseFloat(speed.toFixed(1));
|
|
163
161
|
data.power = Math.round(power);
|
|
164
|
-
data.distanceInternal =
|
|
165
|
-
data.distance = distance;
|
|
162
|
+
data.distanceInternal = distanceInternal;
|
|
166
163
|
data.slope = slope;
|
|
167
164
|
data.pedalRpm = rpm;
|
|
168
165
|
data.gear = gear;
|
|
169
|
-
if (data.time)
|
|
166
|
+
if (data.time !== undefined)
|
|
170
167
|
data.time += duration;
|
|
171
168
|
else
|
|
172
169
|
data.time = 0;
|
|
@@ -64,7 +64,6 @@ class PowerMeterCyclingMode extends CyclingMode_1.CyclingModeBase {
|
|
|
64
64
|
data.speed = parseFloat(speed.toFixed(1));
|
|
65
65
|
data.power = Math.round(power);
|
|
66
66
|
data.distanceInternal = Math.round(distanceInternal);
|
|
67
|
-
data.distance = Math.round(distanceInternal / 100);
|
|
68
67
|
data.slope = slope;
|
|
69
68
|
this.logger.logEvent({ message: "updateData result", data, bikeData, prevRequest: {}, prevSpeed: prevData.speed });
|
|
70
69
|
this.data = JSON.parse(JSON.stringify(data));
|
|
@@ -99,12 +99,17 @@ class DaumClassicAdapter extends DaumAdapter_1.default {
|
|
|
99
99
|
yield this.getBike().setPerson(user);
|
|
100
100
|
startState.setPerson = true;
|
|
101
101
|
}
|
|
102
|
+
if (!startState.setBikeType) {
|
|
103
|
+
const bikeType = this.getCyclingMode().getSetting('bikeType') || 'race';
|
|
104
|
+
yield this.getBike().setBikeType(bikeType.toLowerCase());
|
|
105
|
+
startState.setBikeType = true;
|
|
106
|
+
}
|
|
102
107
|
if (!startState.startProg) {
|
|
103
108
|
yield this.getBike().startProg();
|
|
104
109
|
startState.startProg = true;
|
|
105
110
|
}
|
|
106
111
|
if (!startState.setGear) {
|
|
107
|
-
yield this.bike.setGear(this.
|
|
112
|
+
yield this.bike.setGear(this.daumRunData.gear || (opts.gear || 10));
|
|
108
113
|
startState.setGear = true;
|
|
109
114
|
}
|
|
110
115
|
const startRequest = this.getCyclingMode().getBikeInitRequest();
|
|
@@ -84,7 +84,6 @@ class DaumClassicCyclingMode extends SmartTrainerCyclingMode_1.default {
|
|
|
84
84
|
data.power = Math.round(power);
|
|
85
85
|
data.slope = slope;
|
|
86
86
|
data.distanceInternal = distanceInternal;
|
|
87
|
-
data.distance = Math.round(distanceInternal / 100);
|
|
88
87
|
this.logger.logEvent({ message: "updateData result", data, bikeData, prevRequest: this.prevRequest || {}, prevSpeed: prevData.speed, event: this.event });
|
|
89
88
|
this.data = JSON.parse(JSON.stringify(data));
|
|
90
89
|
this.prevUpdateTS = ts;
|
|
@@ -123,7 +123,7 @@ function hexstr(arr, start, len) {
|
|
|
123
123
|
}
|
|
124
124
|
exports.hexstr = hexstr;
|
|
125
125
|
function Float32ToHex(float32) {
|
|
126
|
-
function getHex(i) { return ('00' + i.toString(16)).slice(-2); }
|
|
126
|
+
function getHex(i) { return ('00' + i.toString(16)).slice(-2).toUpperCase(); }
|
|
127
127
|
var view = new DataView(new ArrayBuffer(4));
|
|
128
128
|
view.setFloat32(0, float32);
|
|
129
129
|
return Array.apply(null, { length: 4 }).map((_, i) => getHex(view.getUint8(i))).join('');
|
|
@@ -72,7 +72,6 @@ class DaumClassicCyclingMode extends PowerMeterCyclingMode_1.default {
|
|
|
72
72
|
data.speed = parseFloat(speed.toFixed(1));
|
|
73
73
|
data.power = Math.round(power);
|
|
74
74
|
data.distanceInternal = Math.round(distanceInternal);
|
|
75
|
-
data.distance = Math.round(distanceInternal / 100);
|
|
76
75
|
data.slope = slope;
|
|
77
76
|
this.logger.logEvent({ message: "updateData result", data, bikeData, prevRequest: {}, prevSpeed: prevData.speed });
|
|
78
77
|
this.data = JSON.parse(JSON.stringify(data));
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Route } from '../../types/route';
|
|
2
1
|
import DaumAdapter from '../DaumAdapter';
|
|
3
2
|
export default class DaumPremiumDevice extends DaumAdapter {
|
|
4
3
|
static NAME: string;
|
|
@@ -8,7 +7,6 @@ export default class DaumPremiumDevice extends DaumAdapter {
|
|
|
8
7
|
getInterface(): any;
|
|
9
8
|
getSupportedCyclingModes(): Array<any>;
|
|
10
9
|
check(): Promise<unknown>;
|
|
11
|
-
initClassic(route: Route): Promise<boolean>;
|
|
12
10
|
start(props: any): Promise<unknown>;
|
|
13
11
|
getCurrentBikeData(): Promise<any>;
|
|
14
12
|
}
|
|
@@ -62,20 +62,6 @@ class DaumPremiumDevice extends DaumAdapter_1.default {
|
|
|
62
62
|
}
|
|
63
63
|
}));
|
|
64
64
|
}
|
|
65
|
-
initClassic(route) {
|
|
66
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
-
if (!route)
|
|
68
|
-
return true;
|
|
69
|
-
let res;
|
|
70
|
-
const bikeType = this.getCyclingMode().getSetting('bikeType');
|
|
71
|
-
res = yield this.bike.programUpload(bikeType, route);
|
|
72
|
-
if (!res)
|
|
73
|
-
return false;
|
|
74
|
-
res = yield this.bike.startProgram(route.programId);
|
|
75
|
-
if (!res)
|
|
76
|
-
return false;
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
65
|
start(props) {
|
|
80
66
|
return __awaiter(this, void 0, void 0, function* () {
|
|
81
67
|
this.logger.logEvent({ message: 'start()' });
|
|
@@ -99,20 +85,20 @@ class DaumPremiumDevice extends DaumAdapter_1.default {
|
|
|
99
85
|
if (!info.version) {
|
|
100
86
|
info.version = yield this.bike.getProtocolVersion();
|
|
101
87
|
}
|
|
102
|
-
if (
|
|
103
|
-
|
|
88
|
+
if (this.getCyclingMode().getModeProperty('eppSupport')) {
|
|
89
|
+
const bikeType = this.getCyclingMode().getSetting('bikeType');
|
|
90
|
+
if (!info.upload)
|
|
91
|
+
info.upload = yield this.bike.programUpload(bikeType, route, props.onStatusUpdate);
|
|
92
|
+
if (!info.started) {
|
|
93
|
+
const programId = route ? route.programId : 0;
|
|
94
|
+
info.started = yield this.bike.startProgram(programId);
|
|
95
|
+
}
|
|
104
96
|
}
|
|
105
|
-
|
|
106
|
-
info.init = true;
|
|
107
|
-
}
|
|
108
|
-
if (!info.person && this.getCyclingMode().getModeProperty('eppSupport')) {
|
|
97
|
+
if (!info.person && this.getCyclingMode().getModeProperty('setPersonSupport')) {
|
|
109
98
|
info.person = yield this.bike.setPerson(user);
|
|
110
99
|
}
|
|
111
|
-
else {
|
|
112
|
-
info.person = true;
|
|
113
|
-
}
|
|
114
100
|
if (!this.getCyclingMode().getModeProperty('eppSupport')) {
|
|
115
|
-
const gear = yield this.bike.setGear(this.
|
|
101
|
+
const gear = yield this.bike.setGear(this.daumRunData.gear || (opts.gear || 10));
|
|
116
102
|
return gear;
|
|
117
103
|
}
|
|
118
104
|
return;
|
|
@@ -121,7 +107,7 @@ class DaumPremiumDevice extends DaumAdapter_1.default {
|
|
|
121
107
|
console.error(err);
|
|
122
108
|
throw (new Error(`could not start device, reason:${err.message}`));
|
|
123
109
|
}
|
|
124
|
-
}), 5,
|
|
110
|
+
}), 5, 1500)
|
|
125
111
|
.then(data => {
|
|
126
112
|
this.startUpdatePull();
|
|
127
113
|
return data;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { ReservedCommands
|
|
2
|
+
import { ReservedCommands } from './utils';
|
|
3
3
|
import { Queue } from '../../utils';
|
|
4
4
|
import { EventLogger } from 'gd-eventlog';
|
|
5
5
|
import { User } from "../../types/user";
|
|
6
6
|
import { Route } from "../../types/route";
|
|
7
|
+
import { OnDeviceStartCallback } from "../../Device";
|
|
7
8
|
declare class Daum8i {
|
|
8
9
|
portName: string;
|
|
9
10
|
logger: EventLogger;
|
|
@@ -78,7 +79,7 @@ declare class Daum8i {
|
|
|
78
79
|
heartrate: number;
|
|
79
80
|
speed: number;
|
|
80
81
|
slope: number;
|
|
81
|
-
|
|
82
|
+
distanceInternal: number;
|
|
82
83
|
cadence: number;
|
|
83
84
|
power: number;
|
|
84
85
|
physEnergy: number;
|
|
@@ -95,10 +96,10 @@ declare class Daum8i {
|
|
|
95
96
|
getPower(power: any): Promise<number>;
|
|
96
97
|
setPerson(person: User): Promise<boolean>;
|
|
97
98
|
programUploadInit(): Promise<boolean>;
|
|
98
|
-
programUploadStart(bikeType:
|
|
99
|
+
programUploadStart(bikeType: string, route?: Route): Promise<Uint8Array>;
|
|
99
100
|
programUploadSendBlock(epp: Uint8Array, offset: number): Promise<boolean>;
|
|
100
101
|
programUploadDone(): Promise<boolean>;
|
|
101
|
-
programUpload(bikeType:
|
|
102
|
+
programUpload(bikeType: string, route: Route, onStatusUpdate?: OnDeviceStartCallback): Promise<boolean>;
|
|
102
103
|
startProgram(programId?: number): Promise<boolean>;
|
|
103
104
|
setGear(gear: any): Promise<number>;
|
|
104
105
|
getGear(): Promise<number>;
|
package/lib/daum/premium/bike.js
CHANGED
|
@@ -710,7 +710,8 @@ class Daum8i {
|
|
|
710
710
|
});
|
|
711
711
|
}
|
|
712
712
|
setPerson(person) {
|
|
713
|
-
|
|
713
|
+
const { sex, age, length, weight } = person;
|
|
714
|
+
this.logger.logEvent({ message: 'setPerson() request', sex, age, length, weight });
|
|
714
715
|
return this.sendReservedDaum8iCommand(utils_1.ReservedCommands.PERSON_SET, 'BF', (0, utils_1.getPersonData)(person))
|
|
715
716
|
.then((res) => {
|
|
716
717
|
const buffer = Buffer.from(res);
|
|
@@ -735,10 +736,12 @@ class Daum8i {
|
|
|
735
736
|
}
|
|
736
737
|
programUploadStart(bikeType, route) {
|
|
737
738
|
const payload = Buffer.alloc(40);
|
|
738
|
-
const epp = (0, utils_1.routeToEpp)(route);
|
|
739
|
+
const epp = route ? (0, utils_1.routeToEpp)(route) : undefined;
|
|
740
|
+
const eppLength = epp ? epp.length : 0;
|
|
741
|
+
const bikeTypeVal = (0, utils_1.getBikeType)(bikeType);
|
|
739
742
|
payload.writeInt32LE(0, 0);
|
|
740
|
-
payload.writeInt8(
|
|
741
|
-
payload.writeInt8(
|
|
743
|
+
payload.writeInt8(bikeTypeVal, 4);
|
|
744
|
+
payload.writeInt8(0, 5);
|
|
742
745
|
payload.writeInt16LE(0, 6);
|
|
743
746
|
payload.writeInt32LE(0, 8);
|
|
744
747
|
payload.writeInt32LE(0, 12);
|
|
@@ -749,8 +752,8 @@ class Daum8i {
|
|
|
749
752
|
payload.writeInt16LE(0, 28);
|
|
750
753
|
payload.writeInt16LE(0, 30);
|
|
751
754
|
payload.writeInt32LE(7, 32);
|
|
752
|
-
payload.writeInt32LE(
|
|
753
|
-
this.logger.logEvent({ message: 'programUploadStart() request' });
|
|
755
|
+
payload.writeInt32LE(eppLength, 36);
|
|
756
|
+
this.logger.logEvent({ message: 'programUploadStart() request', bikeType, length: eppLength });
|
|
754
757
|
return this.sendReservedDaum8iCommand(utils_1.ReservedCommands.PROGRAM_LIST_NEW_PROGRAM, 'BF', payload)
|
|
755
758
|
.then((res) => {
|
|
756
759
|
const buffer = Buffer.from(res);
|
|
@@ -799,20 +802,34 @@ class Daum8i {
|
|
|
799
802
|
;
|
|
800
803
|
});
|
|
801
804
|
}
|
|
802
|
-
programUpload(bikeType, route) {
|
|
805
|
+
programUpload(bikeType, route, onStatusUpdate) {
|
|
803
806
|
return __awaiter(this, void 0, void 0, function* () {
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
807
|
+
try {
|
|
808
|
+
yield this.programUploadInit();
|
|
809
|
+
const epp = yield this.programUploadStart(bikeType, route);
|
|
810
|
+
if (epp) {
|
|
811
|
+
let success = true;
|
|
812
|
+
let done = false;
|
|
813
|
+
let offset = 0;
|
|
814
|
+
if (onStatusUpdate)
|
|
815
|
+
onStatusUpdate(0, epp.length);
|
|
816
|
+
while (success && !done) {
|
|
817
|
+
success = yield this.programUploadSendBlock(epp, offset);
|
|
818
|
+
offset += MAX_DATA_BLOCK_SIZE;
|
|
819
|
+
done = offset >= epp.length;
|
|
820
|
+
if (onStatusUpdate)
|
|
821
|
+
onStatusUpdate(done ? epp.length : offset, epp.length);
|
|
822
|
+
}
|
|
823
|
+
if (done) {
|
|
824
|
+
return yield this.programUploadDone();
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
else {
|
|
828
|
+
return yield this.programUploadDone();
|
|
829
|
+
}
|
|
813
830
|
}
|
|
814
|
-
|
|
815
|
-
|
|
831
|
+
catch (err) {
|
|
832
|
+
console.log('~~~ err', err);
|
|
816
833
|
}
|
|
817
834
|
return false;
|
|
818
835
|
});
|
|
@@ -4,8 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getPersonData = exports.parseTrainingData = exports.routeToEpp = exports.getBikeType = exports.BikeType = exports.ReservedCommands = exports.Int32ToIntArray = exports.Int16ToIntArray = exports.Float32ToIntArray = exports.Float32ToHex = exports.getAsciiArrayFromStr = exports.asciiArrayToString = exports.charArrayToString = exports.ascii = exports.append = exports.getHex = exports.hexstr = exports.getMessageData = exports.buildMessage = exports.checkSum = exports.esc2bin = exports.bin2esc = void 0;
|
|
7
|
-
const user_1 = require("../../types/user");
|
|
8
|
-
const utils_1 = require("../classic/utils");
|
|
9
7
|
const win32filetime_1 = __importDefault(require("win32filetime"));
|
|
10
8
|
const sum = (arr) => arr.reduce((a, b) => a + b, 0);
|
|
11
9
|
function bin2esc(arr) {
|
|
@@ -15,29 +13,29 @@ function bin2esc(arr) {
|
|
|
15
13
|
const res = [];
|
|
16
14
|
arr.forEach(v => {
|
|
17
15
|
switch (v) {
|
|
18
|
-
case
|
|
19
|
-
res.push(
|
|
20
|
-
res.push(
|
|
16
|
+
case 0x12:
|
|
17
|
+
res.push(0x22);
|
|
18
|
+
res.push(0x12);
|
|
21
19
|
break;
|
|
22
|
-
case
|
|
23
|
-
res.push(
|
|
24
|
-
res.push(
|
|
20
|
+
case 0x22:
|
|
21
|
+
res.push(0x22);
|
|
22
|
+
res.push(0x22);
|
|
25
23
|
break;
|
|
26
|
-
case
|
|
27
|
-
res.push(
|
|
28
|
-
res.push(
|
|
24
|
+
case 0x01:
|
|
25
|
+
res.push(0x22);
|
|
26
|
+
res.push(0x11);
|
|
29
27
|
break;
|
|
30
|
-
case
|
|
31
|
-
res.push(
|
|
32
|
-
res.push(
|
|
28
|
+
case 0x17:
|
|
29
|
+
res.push(0x22);
|
|
30
|
+
res.push(0x27);
|
|
33
31
|
break;
|
|
34
|
-
case
|
|
35
|
-
res.push(
|
|
36
|
-
res.push(
|
|
32
|
+
case 0x06:
|
|
33
|
+
res.push(0x22);
|
|
34
|
+
res.push(0x16);
|
|
37
35
|
break;
|
|
38
|
-
case
|
|
39
|
-
res.push(
|
|
40
|
-
res.push(
|
|
36
|
+
case 0x15:
|
|
37
|
+
res.push(0x22);
|
|
38
|
+
res.push(0x25);
|
|
41
39
|
break;
|
|
42
40
|
default:
|
|
43
41
|
res.push(v);
|
|
@@ -56,26 +54,29 @@ function esc2bin(arr) {
|
|
|
56
54
|
if (escaped) {
|
|
57
55
|
escaped = false;
|
|
58
56
|
switch (v) {
|
|
59
|
-
case
|
|
60
|
-
res.push(
|
|
57
|
+
case 0x11:
|
|
58
|
+
res.push(0x1);
|
|
61
59
|
return;
|
|
62
|
-
case
|
|
63
|
-
res.push(
|
|
60
|
+
case 0x27:
|
|
61
|
+
res.push(0x17);
|
|
64
62
|
return;
|
|
65
|
-
case
|
|
66
|
-
res.push(
|
|
63
|
+
case 0x16:
|
|
64
|
+
res.push(0x6);
|
|
67
65
|
return;
|
|
68
|
-
case
|
|
69
|
-
res.push(
|
|
66
|
+
case 0x25:
|
|
67
|
+
res.push(0x15);
|
|
70
68
|
return;
|
|
71
|
-
case
|
|
72
|
-
res.push(
|
|
69
|
+
case 0x12:
|
|
70
|
+
res.push(0x12);
|
|
71
|
+
return;
|
|
72
|
+
case 0x22:
|
|
73
|
+
res.push(0x22);
|
|
73
74
|
return;
|
|
74
75
|
default: res.push(v);
|
|
75
76
|
}
|
|
76
77
|
return;
|
|
77
78
|
}
|
|
78
|
-
if (v ===
|
|
79
|
+
if (v === 0x22) {
|
|
79
80
|
escaped = true;
|
|
80
81
|
}
|
|
81
82
|
else {
|
|
@@ -258,9 +259,9 @@ function routeToEpp(route, date) {
|
|
|
258
259
|
let offset = 0;
|
|
259
260
|
const name = route.name || '';
|
|
260
261
|
const description = route.description || '';
|
|
261
|
-
const minElevation =
|
|
262
|
-
const maxElevation = Math.max(...route.points.map(p => p.elevation));
|
|
263
|
-
const sampleRate = route.points.length !== 0 ? route.totalDistance / route.points.length : 0;
|
|
262
|
+
const minElevation = route.minElevation ? route.minElevation : 0;
|
|
263
|
+
const maxElevation = route.maxElevation ? route.minElevation : Math.max(...route.points.map(p => p.elevation));
|
|
264
|
+
const sampleRate = route.points.length !== 0 ? Math.round(route.totalDistance / route.points.length) : 0;
|
|
264
265
|
buffer.writeUInt32LE(fileTime.low, offset);
|
|
265
266
|
offset += 4;
|
|
266
267
|
buffer.writeUInt32LE(fileTime.high, offset);
|
|
@@ -314,9 +315,9 @@ function parseTrainingData(payload) {
|
|
|
314
315
|
const data = {
|
|
315
316
|
time: parseInt(vals[0]),
|
|
316
317
|
heartrate: parseInt(vals[1]),
|
|
317
|
-
speed: parseFloat(vals[2]),
|
|
318
|
+
speed: parseFloat(vals[2]) * 3.6,
|
|
318
319
|
slope: parseFloat(vals[3]),
|
|
319
|
-
|
|
320
|
+
distanceInternal: parseInt(vals[4]),
|
|
320
321
|
cadence: parseFloat(vals[5]),
|
|
321
322
|
power: parseInt(vals[6]),
|
|
322
323
|
physEnergy: parseFloat(vals[7]),
|
|
@@ -358,17 +359,17 @@ function getPersonData(user) {
|
|
|
358
359
|
buffer.writeUInt8(0, offset);
|
|
359
360
|
offset += 1;
|
|
360
361
|
}
|
|
361
|
-
buffer.writeInt32LE(
|
|
362
|
+
buffer.writeInt32LE(1, offset);
|
|
362
363
|
offset += 4;
|
|
363
|
-
buffer.writeInt32LE(
|
|
364
|
+
buffer.writeInt32LE(1, offset);
|
|
364
365
|
offset += 4;
|
|
365
|
-
buffer.writeInt32LE(
|
|
366
|
+
buffer.writeInt32LE(175, offset);
|
|
366
367
|
offset += 4;
|
|
367
|
-
buffer.writeFloatLE(
|
|
368
|
+
buffer.writeFloatLE(70, offset);
|
|
368
369
|
offset += 4;
|
|
369
370
|
buffer.writeFloatLE(0, offset);
|
|
370
371
|
offset += 4;
|
|
371
|
-
buffer.writeUInt32LE(
|
|
372
|
+
buffer.writeUInt32LE(1, offset);
|
|
372
373
|
offset += 4;
|
|
373
374
|
return buffer;
|
|
374
375
|
}
|
package/lib/types/route.d.ts
CHANGED