incyclist-devices 1.4.48 → 1.4.51
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/DeviceSupport.d.ts +2 -1
- package/lib/DeviceSupport.js +3 -1
- package/lib/ble/ble-device.d.ts +11 -2
- package/lib/ble/ble-device.js +28 -5
- package/lib/ble/ble-erg-mode.d.ts +1 -8
- package/lib/ble/ble-erg-mode.js +20 -33
- package/lib/ble/ble-st-mode.d.ts +1 -10
- package/lib/ble/ble-st-mode.js +33 -76
- package/lib/ble/fm.d.ts +25 -2
- package/lib/ble/fm.js +234 -19
- package/lib/ble/hrm.js +1 -0
- package/lib/ble/pwr.js +1 -0
- package/lib/ble/wahoo-kickr.d.ts +73 -0
- package/lib/ble/wahoo-kickr.js +372 -0
- package/lib/modes/power-base.js +0 -1
- package/lib/modes/power-meter.js +1 -1
- package/package.json +1 -1
package/lib/ble/fm.js
CHANGED
|
@@ -18,7 +18,15 @@ const ble_interface_1 = __importDefault(require("./ble-interface"));
|
|
|
18
18
|
const Device_1 = __importDefault(require("../Device"));
|
|
19
19
|
const gd_eventlog_1 = require("gd-eventlog");
|
|
20
20
|
const power_meter_1 = __importDefault(require("../modes/power-meter"));
|
|
21
|
+
const ble_st_mode_1 = __importDefault(require("./ble-st-mode"));
|
|
22
|
+
const ble_erg_mode_1 = __importDefault(require("./ble-erg-mode"));
|
|
21
23
|
const FTMS_CP = '2ad9';
|
|
24
|
+
const cwABike = {
|
|
25
|
+
race: 0.35,
|
|
26
|
+
triathlon: 0.29,
|
|
27
|
+
mountain: 0.57
|
|
28
|
+
};
|
|
29
|
+
const cRR = 0.0036;
|
|
22
30
|
const bit = (nr) => (1 << nr);
|
|
23
31
|
const IndoorBikeDataFlag = {
|
|
24
32
|
MoreData: bit(0),
|
|
@@ -79,6 +87,10 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
79
87
|
this.features = undefined;
|
|
80
88
|
this.hasControl = false;
|
|
81
89
|
this.isCPSubscribed = false;
|
|
90
|
+
this.crr = 0.0033;
|
|
91
|
+
this.cw = 0.6;
|
|
92
|
+
this.windSpeed = 0;
|
|
93
|
+
this.wheelSize = 2100;
|
|
82
94
|
this.data = {};
|
|
83
95
|
}
|
|
84
96
|
init() {
|
|
@@ -138,6 +150,12 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
138
150
|
}
|
|
139
151
|
return Object.assign(Object.assign({}, this.data), { raw: data.toString('hex') });
|
|
140
152
|
}
|
|
153
|
+
setCrr(crr) { this.crr = crr; }
|
|
154
|
+
getCrr() { return this.crr; }
|
|
155
|
+
setCw(cw) { this.cw = cw; }
|
|
156
|
+
getCw() { return this.cw; }
|
|
157
|
+
setWindSpeed(windSpeed) { this.windSpeed = windSpeed; }
|
|
158
|
+
getWindSpeed() { return this.windSpeed; }
|
|
141
159
|
parseIndoorBikeData(_data) {
|
|
142
160
|
const data = Buffer.from(_data);
|
|
143
161
|
const flags = data.readUInt16LE(0);
|
|
@@ -163,7 +181,7 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
163
181
|
offset += 1;
|
|
164
182
|
const dvHigh = data.readUInt16LE(offset);
|
|
165
183
|
offset += 2;
|
|
166
|
-
this.data.totalDistance = dvHigh << 8 + dvLow;
|
|
184
|
+
this.data.totalDistance = (dvHigh << 8) + dvLow;
|
|
167
185
|
}
|
|
168
186
|
if (flags & IndoorBikeDataFlag.ResistanceLevelPresent) {
|
|
169
187
|
this.data.resistanceLevel = data.readInt16LE(offset);
|
|
@@ -199,6 +217,43 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
199
217
|
}
|
|
200
218
|
return Object.assign(Object.assign({}, this.data), { raw: data.toString('hex') });
|
|
201
219
|
}
|
|
220
|
+
parseFitnessMachineStatus(_data) {
|
|
221
|
+
const data = Buffer.from(_data);
|
|
222
|
+
const OpCode = data.readUInt8(0);
|
|
223
|
+
switch (OpCode) {
|
|
224
|
+
case 8:
|
|
225
|
+
this.data.targetPower = data.readInt16LE(1);
|
|
226
|
+
break;
|
|
227
|
+
case 6:
|
|
228
|
+
this.data.targetInclination = data.readInt16LE(1) / 10;
|
|
229
|
+
break;
|
|
230
|
+
case 4:
|
|
231
|
+
this.data.status = "STARTED";
|
|
232
|
+
break;
|
|
233
|
+
case 3:
|
|
234
|
+
case 2:
|
|
235
|
+
this.data.status = "STOPPED";
|
|
236
|
+
break;
|
|
237
|
+
case 20:
|
|
238
|
+
const spinDownStatus = data.readUInt8(1);
|
|
239
|
+
switch (spinDownStatus) {
|
|
240
|
+
case 1:
|
|
241
|
+
this.data.status = "SPIN DOWN REQUESTED";
|
|
242
|
+
break;
|
|
243
|
+
case 2:
|
|
244
|
+
this.data.status = "SPIN DOWN SUCCESS";
|
|
245
|
+
break;
|
|
246
|
+
case 3:
|
|
247
|
+
this.data.status = "SPIN DOWN ERROR";
|
|
248
|
+
break;
|
|
249
|
+
case 4:
|
|
250
|
+
this.data.status = "STOP PEDALING";
|
|
251
|
+
break;
|
|
252
|
+
default: break;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return Object.assign(Object.assign({}, this.data), { raw: data.toString('hex') });
|
|
256
|
+
}
|
|
202
257
|
getFitnessMachineFeatures() {
|
|
203
258
|
return __awaiter(this, void 0, void 0, function* () {
|
|
204
259
|
if (this.features)
|
|
@@ -218,36 +273,148 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
218
273
|
});
|
|
219
274
|
}
|
|
220
275
|
onData(characteristic, data) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
276
|
+
super.onData(characteristic, data);
|
|
277
|
+
const uuid = characteristic.toLocaleLowerCase();
|
|
278
|
+
let res = undefined;
|
|
279
|
+
switch (uuid) {
|
|
280
|
+
case '2ad2':
|
|
281
|
+
res = this.parseIndoorBikeData(data);
|
|
282
|
+
break;
|
|
283
|
+
case '2a37':
|
|
284
|
+
res = this.parseHrm(data);
|
|
285
|
+
break;
|
|
286
|
+
case '2ada':
|
|
287
|
+
res = this.parseFitnessMachineStatus(data);
|
|
288
|
+
break;
|
|
289
|
+
default:
|
|
290
|
+
break;
|
|
224
291
|
}
|
|
225
|
-
if (
|
|
226
|
-
const res = this.parseHrm(data);
|
|
292
|
+
if (res)
|
|
227
293
|
this.emit('data', res);
|
|
228
|
-
|
|
294
|
+
}
|
|
295
|
+
writeFtmsMessage(requestedOpCode, data) {
|
|
296
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
297
|
+
try {
|
|
298
|
+
const res = yield this.write(FTMS_CP, data);
|
|
299
|
+
const responseData = Buffer.from(res);
|
|
300
|
+
const opCode = responseData.readUInt8(0);
|
|
301
|
+
const request = responseData.readUInt8(1);
|
|
302
|
+
const result = responseData.readUInt8(2);
|
|
303
|
+
if (opCode !== 128 || request !== requestedOpCode)
|
|
304
|
+
throw new Error('Illegal response ');
|
|
305
|
+
return result;
|
|
306
|
+
}
|
|
307
|
+
catch (err) {
|
|
308
|
+
this.logEvent({ message: 'writeFtmsMessage failed', opCode: requestedOpCode, reason: err.message });
|
|
309
|
+
return 4;
|
|
310
|
+
}
|
|
311
|
+
});
|
|
229
312
|
}
|
|
230
313
|
requestControl() {
|
|
231
314
|
return __awaiter(this, void 0, void 0, function* () {
|
|
232
315
|
if (this.hasControl)
|
|
233
316
|
return true;
|
|
317
|
+
this.logEvent({ message: 'requestControl' });
|
|
234
318
|
const data = Buffer.alloc(1);
|
|
235
319
|
data.writeUInt8(0, 0);
|
|
236
|
-
const
|
|
237
|
-
if (
|
|
320
|
+
const res = yield this.writeFtmsMessage(0, data);
|
|
321
|
+
if (res === 1) {
|
|
238
322
|
this.hasControl = true;
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
this.logEvent({ message: 'requestControl failed' });
|
|
326
|
+
}
|
|
239
327
|
return this.hasControl;
|
|
240
328
|
});
|
|
241
329
|
}
|
|
242
330
|
setTargetPower(power) {
|
|
243
331
|
return __awaiter(this, void 0, void 0, function* () {
|
|
332
|
+
this.logEvent({ message: 'setTargetPower', power, skip: (this.data.targetPower !== undefined && this.data.targetPower === power) });
|
|
333
|
+
if (this.data.targetPower !== undefined && this.data.targetPower === power)
|
|
334
|
+
return true;
|
|
244
335
|
const hasControl = yield this.requestControl();
|
|
245
|
-
if (!hasControl)
|
|
246
|
-
throw new Error('setTargetPower not possible - control is disabled');
|
|
247
336
|
const data = Buffer.alloc(3);
|
|
248
337
|
data.writeUInt8(5, 0);
|
|
249
338
|
data.writeInt16LE(Math.round(power), 1);
|
|
250
|
-
const res = yield this.
|
|
339
|
+
const res = yield this.writeFtmsMessage(5, data);
|
|
340
|
+
return (res === 1);
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
setSlope(slope) {
|
|
344
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
345
|
+
this.logEvent({ message: 'setSlope', slope });
|
|
346
|
+
const { windSpeed, crr, cw } = this;
|
|
347
|
+
return yield this.setIndoorBikeSimulation(windSpeed, slope, crr, cw);
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
setTargetInclination(inclination) {
|
|
351
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
352
|
+
if (this.data.targetInclination !== undefined && this.data.targetInclination === inclination)
|
|
353
|
+
return true;
|
|
354
|
+
const hasControl = yield this.requestControl();
|
|
355
|
+
if (!hasControl) {
|
|
356
|
+
this.logEvent({ message: 'setTargetInclination failed', reason: 'control is disabled' });
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
const data = Buffer.alloc(3);
|
|
360
|
+
data.writeUInt8(3, 0);
|
|
361
|
+
data.writeInt16LE(Math.round(inclination * 10), 1);
|
|
362
|
+
const res = yield this.writeFtmsMessage(3, data);
|
|
363
|
+
return (res === 1);
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
setIndoorBikeSimulation(windSpeed, gradient, crr, cw) {
|
|
367
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
368
|
+
const hasControl = yield this.requestControl();
|
|
369
|
+
const data = Buffer.alloc(7);
|
|
370
|
+
data.writeUInt8(17, 0);
|
|
371
|
+
data.writeInt16LE(Math.round(windSpeed * 1000), 1);
|
|
372
|
+
data.writeInt16LE(Math.round(gradient * 100), 3);
|
|
373
|
+
data.writeUInt8(Math.round(crr * 10000), 5);
|
|
374
|
+
data.writeUInt8(Math.round(cw * 100), 6);
|
|
375
|
+
const res = yield this.writeFtmsMessage(17, data);
|
|
376
|
+
return (res === 1);
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
startRequest() {
|
|
380
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
381
|
+
const hasControl = yield this.requestControl();
|
|
382
|
+
if (!hasControl) {
|
|
383
|
+
this.logEvent({ message: 'startRequest failed', reason: 'control is disabled' });
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
const data = Buffer.alloc(1);
|
|
387
|
+
data.writeUInt8(7, 0);
|
|
388
|
+
const res = yield this.writeFtmsMessage(7, data);
|
|
389
|
+
return (res === 1);
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
stopRequest() {
|
|
393
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
394
|
+
const hasControl = yield this.requestControl();
|
|
395
|
+
if (!hasControl) {
|
|
396
|
+
this.logEvent({ message: 'stopRequest failed', reason: 'control is disabled' });
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
399
|
+
const data = Buffer.alloc(2);
|
|
400
|
+
data.writeUInt8(8, 0);
|
|
401
|
+
data.writeUInt8(1, 1);
|
|
402
|
+
const res = yield this.writeFtmsMessage(8, data);
|
|
403
|
+
return (res === 1);
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
PauseRequest() {
|
|
407
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
408
|
+
const hasControl = yield this.requestControl();
|
|
409
|
+
if (!hasControl) {
|
|
410
|
+
this.logEvent({ message: 'PauseRequest failed', reason: 'control is disabled' });
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
413
|
+
const data = Buffer.alloc(2);
|
|
414
|
+
data.writeUInt8(8, 0);
|
|
415
|
+
data.writeUInt8(2, 1);
|
|
416
|
+
const res = yield this.writeFtmsMessage(8, data);
|
|
417
|
+
return (res === 1);
|
|
251
418
|
});
|
|
252
419
|
}
|
|
253
420
|
reset() {
|
|
@@ -266,8 +433,10 @@ class FmAdapter extends Device_1.default {
|
|
|
266
433
|
this.distanceInternal = 0;
|
|
267
434
|
this.device = device;
|
|
268
435
|
this.ble = protocol.ble;
|
|
269
|
-
this.
|
|
436
|
+
this.cyclingMode = this.getDefaultCyclingMode();
|
|
270
437
|
this.logger = new gd_eventlog_1.EventLogger('BLE-FM');
|
|
438
|
+
if (this.device)
|
|
439
|
+
this.device.setLogger(this.logger);
|
|
271
440
|
}
|
|
272
441
|
isBike() { return this.device.isBike(); }
|
|
273
442
|
isHrm() { return this.device.isHrm(); }
|
|
@@ -287,13 +456,33 @@ class FmAdapter extends Device_1.default {
|
|
|
287
456
|
getDisplayName() {
|
|
288
457
|
return this.getName();
|
|
289
458
|
}
|
|
459
|
+
getSupportedCyclingModes() {
|
|
460
|
+
return [ble_st_mode_1.default, ble_erg_mode_1.default, power_meter_1.default];
|
|
461
|
+
}
|
|
462
|
+
setCyclingMode(mode, settings) {
|
|
463
|
+
let selectedMode;
|
|
464
|
+
if (typeof mode === 'string') {
|
|
465
|
+
const supported = this.getSupportedCyclingModes();
|
|
466
|
+
const CyclingModeClass = supported.find(M => { const m = new M(this); return m.getName() === mode; });
|
|
467
|
+
if (CyclingModeClass) {
|
|
468
|
+
this.cyclingMode = new CyclingModeClass(this, settings);
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
selectedMode = this.getDefaultCyclingMode();
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
selectedMode = mode;
|
|
475
|
+
}
|
|
476
|
+
this.cyclingMode = selectedMode;
|
|
477
|
+
this.cyclingMode.setSettings(settings);
|
|
478
|
+
}
|
|
290
479
|
getCyclingMode() {
|
|
291
|
-
if (!this.
|
|
292
|
-
this.
|
|
293
|
-
return this.
|
|
480
|
+
if (!this.cyclingMode)
|
|
481
|
+
this.cyclingMode = this.getDefaultCyclingMode();
|
|
482
|
+
return this.cyclingMode;
|
|
294
483
|
}
|
|
295
484
|
getDefaultCyclingMode() {
|
|
296
|
-
return new
|
|
485
|
+
return new ble_st_mode_1.default(this);
|
|
297
486
|
}
|
|
298
487
|
getPort() {
|
|
299
488
|
return 'ble';
|
|
@@ -361,8 +550,27 @@ class FmAdapter extends Device_1.default {
|
|
|
361
550
|
yield this.ble.stopScan();
|
|
362
551
|
try {
|
|
363
552
|
const bleDevice = yield this.ble.connectDevice(this.device);
|
|
553
|
+
bleDevice.setLogger(this.logger);
|
|
364
554
|
if (bleDevice) {
|
|
365
555
|
this.device = bleDevice;
|
|
556
|
+
const mode = this.getCyclingMode();
|
|
557
|
+
if (mode && mode.getSetting('bikeType')) {
|
|
558
|
+
const bikeType = mode.getSetting('bikeType').toLowerCase();
|
|
559
|
+
this.device.setCrr(cRR);
|
|
560
|
+
switch (bikeType) {
|
|
561
|
+
case 'race':
|
|
562
|
+
this.device.setCw(cwABike.race);
|
|
563
|
+
break;
|
|
564
|
+
case 'triathlon':
|
|
565
|
+
this.device.setCw(cwABike.triathlon);
|
|
566
|
+
break;
|
|
567
|
+
case 'mountain':
|
|
568
|
+
this.device.setCw(cwABike.mountain);
|
|
569
|
+
break;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
const startRequest = this.getCyclingMode().getBikeInitRequest();
|
|
573
|
+
yield this.sendUpdate(startRequest);
|
|
366
574
|
bleDevice.on('data', (data) => {
|
|
367
575
|
this.onDeviceData(data);
|
|
368
576
|
});
|
|
@@ -385,9 +593,16 @@ class FmAdapter extends Device_1.default {
|
|
|
385
593
|
}
|
|
386
594
|
sendUpdate(request) {
|
|
387
595
|
return __awaiter(this, void 0, void 0, function* () {
|
|
388
|
-
if (this.paused)
|
|
596
|
+
if (this.paused || !this.device)
|
|
389
597
|
return;
|
|
390
|
-
this.getCyclingMode().sendBikeUpdate(request);
|
|
598
|
+
const update = this.getCyclingMode().sendBikeUpdate(request);
|
|
599
|
+
this.logger.logEvent({ message: 'send bike update requested', profile: this.getProfile(), update, request });
|
|
600
|
+
if (update.slope !== undefined) {
|
|
601
|
+
yield this.device.setSlope(update.slope);
|
|
602
|
+
}
|
|
603
|
+
if (update.targetPower !== undefined) {
|
|
604
|
+
yield this.device.setTargetPower(update.targetPower);
|
|
605
|
+
}
|
|
391
606
|
});
|
|
392
607
|
}
|
|
393
608
|
pause() { this.paused = true; return Promise.resolve(true); }
|
package/lib/ble/hrm.js
CHANGED
|
@@ -51,6 +51,7 @@ class BleHrmDevice extends ble_device_1.BleDevice {
|
|
|
51
51
|
return { heartrate, rr, raw: data.toString('hex') };
|
|
52
52
|
}
|
|
53
53
|
onData(characteristic, data) {
|
|
54
|
+
super.onData(characteristic, data);
|
|
54
55
|
if (characteristic.toLocaleLowerCase() === '2a37') {
|
|
55
56
|
const res = this.parseHrm(data);
|
|
56
57
|
this.emit('data', res);
|
package/lib/ble/pwr.js
CHANGED
|
@@ -109,6 +109,7 @@ class BleCyclingPowerDevice extends ble_device_1.BleDevice {
|
|
|
109
109
|
return { instantaneousPower, balance, accTorque, rpm, time, raw: data.toString('hex') };
|
|
110
110
|
}
|
|
111
111
|
onData(characteristic, data) {
|
|
112
|
+
super.onData(characteristic, data);
|
|
112
113
|
if (characteristic.toLocaleLowerCase() === '2a63') {
|
|
113
114
|
const res = this.parsePower(data);
|
|
114
115
|
this.emit('data', res);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import BleProtocol from './incyclist-protocol';
|
|
3
|
+
import { BleDeviceClass } from './ble';
|
|
4
|
+
import DeviceAdapter from '../Device';
|
|
5
|
+
import BleFitnessMachineDevice, { FmAdapter } from './fm';
|
|
6
|
+
declare type IndoorBikeData = {
|
|
7
|
+
speed?: number;
|
|
8
|
+
averageSpeed?: number;
|
|
9
|
+
cadence?: number;
|
|
10
|
+
averageCadence?: number;
|
|
11
|
+
totalDistance?: number;
|
|
12
|
+
resistanceLevel?: number;
|
|
13
|
+
instantaneousPower?: number;
|
|
14
|
+
averagePower?: number;
|
|
15
|
+
expendedEnergy?: number;
|
|
16
|
+
heartrate?: number;
|
|
17
|
+
metabolicEquivalent?: number;
|
|
18
|
+
time?: number;
|
|
19
|
+
remainingTime?: number;
|
|
20
|
+
raw?: string;
|
|
21
|
+
targetPower?: number;
|
|
22
|
+
targetInclination?: number;
|
|
23
|
+
status?: string;
|
|
24
|
+
};
|
|
25
|
+
declare type CrankData = {
|
|
26
|
+
revolutions?: number;
|
|
27
|
+
time?: number;
|
|
28
|
+
cntUpdateMissing?: number;
|
|
29
|
+
};
|
|
30
|
+
export default class WahooAdvancedFitnessMachineDevice extends BleFitnessMachineDevice {
|
|
31
|
+
static services: string[];
|
|
32
|
+
static characteristics: string[];
|
|
33
|
+
prevCrankData: CrankData;
|
|
34
|
+
currentCrankData: CrankData;
|
|
35
|
+
timeOffset: number;
|
|
36
|
+
tsPrevWrite: any;
|
|
37
|
+
constructor(props?: any);
|
|
38
|
+
init(): Promise<boolean>;
|
|
39
|
+
getProfile(): string;
|
|
40
|
+
getServiceUUids(): string[];
|
|
41
|
+
isBike(): boolean;
|
|
42
|
+
isPower(): boolean;
|
|
43
|
+
isHrm(): boolean;
|
|
44
|
+
parseCrankData(crankData: any): {
|
|
45
|
+
rpm: number;
|
|
46
|
+
time: any;
|
|
47
|
+
};
|
|
48
|
+
parsePower(_data: Buffer): IndoorBikeData;
|
|
49
|
+
onData(characteristic: string, data: Buffer): void;
|
|
50
|
+
writeWahooFtmsMessage(requestedOpCode: number, data: Buffer): Promise<boolean>;
|
|
51
|
+
requestControl(): Promise<boolean>;
|
|
52
|
+
setPowerAdjusting(): void;
|
|
53
|
+
isPowerAdjusting(): boolean;
|
|
54
|
+
setErgMode(power: number): Promise<boolean>;
|
|
55
|
+
setSimMode(weight: number, crr: number, cw: number): Promise<boolean>;
|
|
56
|
+
setSimCRR(crr: number): Promise<boolean>;
|
|
57
|
+
setSimWindResistance(cw: number): Promise<boolean>;
|
|
58
|
+
setSimGrade(slope: number): Promise<boolean>;
|
|
59
|
+
setSimWindSpeed(v: number): Promise<boolean>;
|
|
60
|
+
setTargetPower(power: number): Promise<boolean>;
|
|
61
|
+
setSlope(slope: any): Promise<boolean>;
|
|
62
|
+
reset(): void;
|
|
63
|
+
}
|
|
64
|
+
export declare class WahooAdvancedFmAdapter extends FmAdapter {
|
|
65
|
+
device: WahooAdvancedFitnessMachineDevice;
|
|
66
|
+
constructor(device: BleDeviceClass, protocol: BleProtocol);
|
|
67
|
+
isSame(device: DeviceAdapter): boolean;
|
|
68
|
+
getProfile(): string;
|
|
69
|
+
start(props?: any): Promise<any>;
|
|
70
|
+
pause(): Promise<boolean>;
|
|
71
|
+
resume(): Promise<boolean>;
|
|
72
|
+
}
|
|
73
|
+
export {};
|