incyclist-devices 2.3.35 → 2.3.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/ble/base/adapter.d.ts +1 -0
- package/lib/ble/base/adapter.js +5 -1
- package/lib/ble/fm/adapter.js +6 -2
- package/lib/ble/zwift/play/sensor.d.ts +3 -2
- package/lib/ble/zwift/play/sensor.js +25 -11
- package/lib/direct-connect/base/peripheral.js +1 -0
- package/lib/modes/antble-smarttrainer.js +56 -20
- package/lib/modes/power-base.js +5 -1
- package/package.json +1 -1
|
@@ -13,6 +13,7 @@ export default class BleAdapter<TDeviceData extends BleDeviceData, TDevice exten
|
|
|
13
13
|
protected lastDataTS: number;
|
|
14
14
|
protected device: TDevice;
|
|
15
15
|
protected onDeviceDataHandler: any;
|
|
16
|
+
protected onDeviceDisconnectHandler: any;
|
|
16
17
|
protected startTask: InteruptableTask<TaskState, boolean>;
|
|
17
18
|
constructor(settings: BleDeviceSettings, props?: DeviceProperties);
|
|
18
19
|
getUniqueName(): string;
|
package/lib/ble/base/adapter.js
CHANGED
|
@@ -21,6 +21,7 @@ class BleAdapter extends adpater_1.default {
|
|
|
21
21
|
constructor(settings, props) {
|
|
22
22
|
super(settings, props);
|
|
23
23
|
this.onDeviceDataHandler = this.onDeviceData.bind(this);
|
|
24
|
+
this.onDeviceDisconnectHandler = this.emit.bind(this);
|
|
24
25
|
this.deviceData = {};
|
|
25
26
|
this.data = {};
|
|
26
27
|
this.dataMsgCount = 0;
|
|
@@ -346,7 +347,7 @@ class BleAdapter extends adpater_1.default {
|
|
|
346
347
|
yield sensor.subscribe();
|
|
347
348
|
if (connected) {
|
|
348
349
|
sensor.on('data', this.onDeviceDataHandler);
|
|
349
|
-
sensor.on('disconnected', this.
|
|
350
|
+
sensor.on('disconnected', this.onDeviceDisconnectHandler);
|
|
350
351
|
sensor.on('error', console.log);
|
|
351
352
|
connected = yield sensor.pair();
|
|
352
353
|
}
|
|
@@ -386,6 +387,9 @@ class BleAdapter extends adpater_1.default {
|
|
|
386
387
|
return true;
|
|
387
388
|
}
|
|
388
389
|
const sensor = this.getSensor();
|
|
390
|
+
sensor.off('data', this.onDeviceDataHandler);
|
|
391
|
+
sensor.off('disconnected', this.onDeviceDisconnectHandler);
|
|
392
|
+
sensor.off('error', console.log);
|
|
389
393
|
sensor.reset();
|
|
390
394
|
this.resetData();
|
|
391
395
|
this.stopped = true;
|
package/lib/ble/fm/adapter.js
CHANGED
|
@@ -269,6 +269,7 @@ class BleFmAdapter extends adapter_1.default {
|
|
|
269
269
|
const device = this.getSensor();
|
|
270
270
|
if (this.hasCapability(types_1.IncyclistCapability.Control)) {
|
|
271
271
|
const send = () => __awaiter(this, void 0, void 0, function* () {
|
|
272
|
+
var _a;
|
|
272
273
|
const res = {};
|
|
273
274
|
if (update.slope !== undefined) {
|
|
274
275
|
yield device.setSlope(update.slope);
|
|
@@ -283,9 +284,12 @@ class BleFmAdapter extends adapter_1.default {
|
|
|
283
284
|
if (!this.zwiftPlay) {
|
|
284
285
|
this.initVirtualShifting();
|
|
285
286
|
}
|
|
286
|
-
if (this.zwiftPlay) {
|
|
287
|
+
if (this.zwiftPlay && !isNaN(update.gearRatio)) {
|
|
288
|
+
let slope = (_a = update.slope) !== null && _a !== void 0 ? _a : 0;
|
|
289
|
+
if (slope === 0)
|
|
290
|
+
slope = 0.01;
|
|
291
|
+
yield this.zwiftPlay.setSimulationData({ inclineX100: slope * 100 });
|
|
287
292
|
const gearRatio = yield this.zwiftPlay.setGearRatio(update.gearRatio);
|
|
288
|
-
yield this.zwiftPlay.setSimulationData({ inclineX100: update.slope * 100 });
|
|
289
293
|
res.gearRatio = gearRatio;
|
|
290
294
|
}
|
|
291
295
|
}
|
|
@@ -27,8 +27,9 @@ export declare class BleZwiftPlaySensor extends TBleSensor {
|
|
|
27
27
|
protected isFM: boolean;
|
|
28
28
|
protected tsLastRidingData: number;
|
|
29
29
|
protected isHubServiceActive: boolean;
|
|
30
|
-
protected
|
|
31
|
-
protected
|
|
30
|
+
protected isHubServicePaired: boolean;
|
|
31
|
+
protected isHubServiceSubscribed: boolean;
|
|
32
|
+
protected initHubServicePromise: Promise<boolean>;
|
|
32
33
|
constructor(peripheral: IBlePeripheral | TBleSensor, props?: any);
|
|
33
34
|
reconnectSensor(): Promise<void>;
|
|
34
35
|
stopSensor(): Promise<boolean>;
|
|
@@ -74,11 +74,14 @@ class BleZwiftPlaySensor extends sensor_1.TBleSensor {
|
|
|
74
74
|
if (!this.isHubServiceActive) {
|
|
75
75
|
yield this.initHubService(false);
|
|
76
76
|
}
|
|
77
|
-
const crrx100000 = Math.round((_a = data === null || data === void 0 ? void 0 : data.crrx100000) !== null && _a !== void 0 ? _a :
|
|
78
|
-
const cWax10000 = Math.round((_b = data === null || data === void 0 ? void 0 : data.cWax10000) !== null && _b !== void 0 ? _b :
|
|
77
|
+
const crrx100000 = Math.round((_a = data === null || data === void 0 ? void 0 : data.crrx100000) !== null && _a !== void 0 ? _a : 400);
|
|
78
|
+
const cWax10000 = Math.round((_b = data === null || data === void 0 ? void 0 : data.cWax10000) !== null && _b !== void 0 ? _b : 5100);
|
|
79
79
|
const windx100 = Math.round((_c = data === null || data === void 0 ? void 0 : data.windx100) !== null && _c !== void 0 ? _c : 0);
|
|
80
|
-
|
|
80
|
+
let inclineX100 = Math.round((_d = data === null || data === void 0 ? void 0 : data.inclineX100) !== null && _d !== void 0 ? _d : 1);
|
|
81
|
+
if (inclineX100 === 0 || Number.isNaN(inclineX100))
|
|
82
|
+
inclineX100 = 1;
|
|
81
83
|
const simulation = { inclineX100, crrx100000, cWax10000, windx100 };
|
|
84
|
+
console.log('# set simulation data', simulation);
|
|
82
85
|
yield this.sendHubCommand({ simulation });
|
|
83
86
|
yield this.requestDataUpdate(512);
|
|
84
87
|
});
|
|
@@ -142,17 +145,21 @@ class BleZwiftPlaySensor extends sensor_1.TBleSensor {
|
|
|
142
145
|
}
|
|
143
146
|
initHubService() {
|
|
144
147
|
return __awaiter(this, arguments, void 0, function* (setSimulation = true) {
|
|
145
|
-
|
|
148
|
+
if (!this.isHubServiceActive && this.initHubServicePromise !== undefined) {
|
|
149
|
+
yield this.initHubServicePromise;
|
|
150
|
+
}
|
|
146
151
|
if (this.isHubServiceActive)
|
|
147
152
|
return true;
|
|
148
|
-
|
|
153
|
+
this.logEvent({ message: 'init hub service', paired: this.paired, subscribed: this.isHubServiceSubscribed });
|
|
154
|
+
console.log('# init Hub Service');
|
|
155
|
+
if (!this.isHubServicePaired) {
|
|
149
156
|
yield this.pair();
|
|
150
157
|
}
|
|
151
|
-
if (!this.
|
|
158
|
+
if (!this.isHubServiceSubscribed) {
|
|
152
159
|
yield this.subscribe();
|
|
153
|
-
this.
|
|
160
|
+
this.isHubServiceSubscribed = true;
|
|
154
161
|
}
|
|
155
|
-
|
|
162
|
+
this.initHubServicePromise = new Promise((done) => {
|
|
156
163
|
let timeout = setTimeout(() => {
|
|
157
164
|
done(false);
|
|
158
165
|
}, 2000);
|
|
@@ -163,7 +170,9 @@ class BleZwiftPlaySensor extends sensor_1.TBleSensor {
|
|
|
163
170
|
}
|
|
164
171
|
this.isHubServiceActive = true;
|
|
165
172
|
console.log('# init hub service completed');
|
|
173
|
+
this.logEvent({ message: 'init hub service done', paired: this.paired, subscribed: this.isHubServiceSubscribed });
|
|
166
174
|
if (setSimulation) {
|
|
175
|
+
this.logEvent({ message: 'hub: send initial simulation data' });
|
|
167
176
|
this.setSimulationData().then(() => {
|
|
168
177
|
done(true);
|
|
169
178
|
})
|
|
@@ -186,6 +195,7 @@ class BleZwiftPlaySensor extends sensor_1.TBleSensor {
|
|
|
186
195
|
this.logEvent({ message: 'could not init hub service', reason: err.message });
|
|
187
196
|
});
|
|
188
197
|
});
|
|
198
|
+
return this.initHubServicePromise;
|
|
189
199
|
});
|
|
190
200
|
}
|
|
191
201
|
sendHubRequest(request) {
|
|
@@ -344,7 +354,7 @@ class BleZwiftPlaySensor extends sensor_1.TBleSensor {
|
|
|
344
354
|
pair() {
|
|
345
355
|
return __awaiter(this, void 0, void 0, function* () {
|
|
346
356
|
var _a, _b;
|
|
347
|
-
if (this.
|
|
357
|
+
if (this.isHubServicePaired)
|
|
348
358
|
return true;
|
|
349
359
|
let manufacturerData;
|
|
350
360
|
try {
|
|
@@ -380,12 +390,12 @@ class BleZwiftPlaySensor extends sensor_1.TBleSensor {
|
|
|
380
390
|
message = Buffer.concat([Buffer.from('RideOn'), Buffer.from([0x01, 0x02]), this.publicKey]);
|
|
381
391
|
}
|
|
382
392
|
yield this.write((0, utils_1.fullUUID)('00000003-19ca-4651-86e5-fa29dcdd09d1'), message, { withoutResponse: true });
|
|
383
|
-
this.
|
|
393
|
+
this.isHubServicePaired = true;
|
|
384
394
|
return true;
|
|
385
395
|
}
|
|
386
396
|
catch (err) {
|
|
387
397
|
this.logEvent({ message: 'error', fn: 'pair', error: err.message, stack: err.stack });
|
|
388
|
-
this.
|
|
398
|
+
this.isHubServicePaired = false;
|
|
389
399
|
return false;
|
|
390
400
|
}
|
|
391
401
|
});
|
|
@@ -406,6 +416,10 @@ class BleZwiftPlaySensor extends sensor_1.TBleSensor {
|
|
|
406
416
|
this.paired = false;
|
|
407
417
|
this.encrypted = false;
|
|
408
418
|
this.deviceKey = null;
|
|
419
|
+
this.isHubServicePaired = false;
|
|
420
|
+
this.isHubServiceSubscribed = false;
|
|
421
|
+
this.isHubServiceActive = false;
|
|
422
|
+
delete this.initHubServicePromise;
|
|
409
423
|
}
|
|
410
424
|
getManufacturerData() {
|
|
411
425
|
const data = this.peripheral.getManufacturerData();
|
|
@@ -154,6 +154,7 @@ class DirectConnectPeripheral {
|
|
|
154
154
|
if (this.subscribed.includes(uuid)) {
|
|
155
155
|
return true;
|
|
156
156
|
}
|
|
157
|
+
console.log('# subscribe ', characteristicUUID);
|
|
157
158
|
const seqNo = this.getNextSeqNo();
|
|
158
159
|
const message = new messages_1.EnableCharacteristicNotificationsMessage();
|
|
159
160
|
const request = message.createRequest(seqNo, { characteristicUUID: (0, utils_1.parseUUID)(characteristicUUID), enable: true });
|
|
@@ -83,7 +83,7 @@ class SmartTrainerCyclingMode extends power_base_1.default {
|
|
|
83
83
|
virtshift.default = 'SmartTrainer';
|
|
84
84
|
}
|
|
85
85
|
if (!startGear) {
|
|
86
|
-
startGear = { key: 'startGear', name: 'Initial Gear', description: 'Initial Gear', type: types_1.CyclingModeProperyType.Integer, default:
|
|
86
|
+
startGear = { key: 'startGear', name: 'Initial Gear', description: 'Initial Gear', type: types_1.CyclingModeProperyType.Integer, default: 12, min: 1, max: 24, condition: (s) => (s === null || s === void 0 ? void 0 : s.virtshift) === 'Incyclist' || (s === null || s === void 0 ? void 0 : s.virtshift) === 'SmartTrainer' };
|
|
87
87
|
config.properties.push(startGear);
|
|
88
88
|
}
|
|
89
89
|
return config;
|
|
@@ -102,7 +102,10 @@ class SmartTrainerCyclingMode extends power_base_1.default {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
checkSlopeWithAdapterShifting(request, newRequest = {}) {
|
|
105
|
-
|
|
105
|
+
var _a;
|
|
106
|
+
this.checkSlopeNoShiftig(request, newRequest);
|
|
107
|
+
const gear = (_a = this.gear) !== null && _a !== void 0 ? _a : this.getSetting('startGear');
|
|
108
|
+
newRequest.gearRatio = this.gearRatios[gear - 1];
|
|
106
109
|
}
|
|
107
110
|
getSlopeDelta() {
|
|
108
111
|
return this.gearDelta * 0.5;
|
|
@@ -122,7 +125,7 @@ class SmartTrainerCyclingMode extends power_base_1.default {
|
|
|
122
125
|
}
|
|
123
126
|
}
|
|
124
127
|
checkSlopeWithSimulatedShifting(request, newRequest = {}) {
|
|
125
|
-
var _a, _b, _c, _d;
|
|
128
|
+
var _a, _b, _c, _d, _e;
|
|
126
129
|
if (this.gear === undefined) {
|
|
127
130
|
this.checkSlopeNoShiftig(request, newRequest);
|
|
128
131
|
return;
|
|
@@ -138,15 +141,34 @@ class SmartTrainerCyclingMode extends power_base_1.default {
|
|
|
138
141
|
if (slopeAdj !== undefined)
|
|
139
142
|
this.simSlope = this.simSlope * slopeAdj / 100;
|
|
140
143
|
}
|
|
141
|
-
catch (
|
|
144
|
+
catch (_f) {
|
|
142
145
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
const virtualSpeed = (0, calculations_1.calculateVirtualSpeed)(this.data.pedalRpm, this.gearRatios[this.gear - 1]);
|
|
147
|
+
const m = (_c = (_b = this.adapter) === null || _b === void 0 ? void 0 : _b.getWeight()) !== null && _c !== void 0 ? _c : 85;
|
|
148
|
+
const vCurrent = this.data.speed * 1000 / 3600;
|
|
149
|
+
const eKinCurrent = m * vCurrent * vCurrent / 2;
|
|
150
|
+
const newPower = calculations_1.default.calculatePower(m, virtualSpeed, (_d = this.simSlope) !== null && _d !== void 0 ? _d : 0);
|
|
151
|
+
const prevPower = this.data.power;
|
|
152
|
+
if (this.data.speed < 10 && this.data.isPedalling && (this.data.slope < 1 || this.data.speed === 0)) {
|
|
153
|
+
this.simPower = Math.max(newPower, prevPower);
|
|
154
|
+
this.logger.logEvent({ message: 'set simulater power', power: this.simPower, gear: this.gear, simSlope: this.simSlope, routeSlope: this.data.slope, prevPower, newPower });
|
|
149
155
|
}
|
|
156
|
+
else if (this.data.slope === prev && newPower < prevPower) {
|
|
157
|
+
this.simPower = prevPower;
|
|
158
|
+
this.logger.logEvent({ message: 'set simulater power', power: this.simPower, gear: this.gear, simSlope: this.simSlope, routeSlope: this.data.slope, prevPower, newPower });
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
const powerDiff = newPower - prevPower;
|
|
162
|
+
const vTarget = virtualSpeed * 1000 / 3600;
|
|
163
|
+
const eKinTarget = m * vTarget * vTarget / 2;
|
|
164
|
+
const eKinPrev = eKinCurrent;
|
|
165
|
+
const delta = eKinTarget - eKinPrev;
|
|
166
|
+
const eKinAfter1sec = eKinPrev - powerDiff * 1;
|
|
167
|
+
const vAfter1sec = Math.sqrt(2 * eKinAfter1sec / m) * 3600 / 1000;
|
|
168
|
+
this.simPower = calculations_1.default.calculatePower(m, vAfter1sec / 3.6, (_e = this.simSlope) !== null && _e !== void 0 ? _e : 0);
|
|
169
|
+
this.logger.logEvent({ message: 'set simulater power', power: this.simPower, gear: this.gear, simSlope: this.simSlope, routeSlope: this.data.slope, eKinPrev, eKinTarget, delta, prevPower, newPower });
|
|
170
|
+
}
|
|
171
|
+
this.verifySimPower();
|
|
150
172
|
}
|
|
151
173
|
newRequest.targetPower = this.simPower;
|
|
152
174
|
}
|
|
@@ -195,13 +217,17 @@ class SmartTrainerCyclingMode extends power_base_1.default {
|
|
|
195
217
|
this.gear = this.gearRatios.length;
|
|
196
218
|
}
|
|
197
219
|
delete request.gearDelta;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
220
|
+
if (this.data.pedalRpm > 0) {
|
|
221
|
+
const virtualSpeed = (0, calculations_1.calculateVirtualSpeed)(this.data.pedalRpm, this.gearRatios[this.gear - 1]);
|
|
222
|
+
const m = (_b = (_a = this.adapter) === null || _a === void 0 ? void 0 : _a.getWeight()) !== null && _b !== void 0 ? _b : 85;
|
|
223
|
+
this.simPower = calculations_1.default.calculatePower(m, virtualSpeed, (_d = (_c = this.simSlope) !== null && _c !== void 0 ? _c : this.data.slope) !== null && _d !== void 0 ? _d : 0);
|
|
224
|
+
this.verifySimPower();
|
|
225
|
+
this.logger.logEvent({ message: 'set simulater power', power: this.simPower, gear: this.gear, simSlope: this.simSlope, routeSlope: this.data.slope });
|
|
226
|
+
this.adapter.sendUpdate({ targetPower: this.simPower }).then(() => { });
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
delete this.simPower;
|
|
230
|
+
}
|
|
205
231
|
}
|
|
206
232
|
break;
|
|
207
233
|
case 'Adapter':
|
|
@@ -258,6 +284,9 @@ class SmartTrainerCyclingMode extends power_base_1.default {
|
|
|
258
284
|
if (this.data.pedalRpm > 0 && this.simPower < MIN_POWER) {
|
|
259
285
|
this.simPower = MIN_POWER;
|
|
260
286
|
}
|
|
287
|
+
if (!this.data.isPedalling) {
|
|
288
|
+
delete this.simPower;
|
|
289
|
+
}
|
|
261
290
|
}
|
|
262
291
|
checkEmptyRequest(newRequest) {
|
|
263
292
|
if (Object.keys(newRequest).length === 0) {
|
|
@@ -339,14 +368,21 @@ class SmartTrainerCyclingMode extends power_base_1.default {
|
|
|
339
368
|
return newRequest;
|
|
340
369
|
}
|
|
341
370
|
getGearString() {
|
|
371
|
+
var _a, _b, _c, _d;
|
|
342
372
|
const mode = this.getVirtualShiftMode();
|
|
343
373
|
if (mode === "Disabled")
|
|
344
374
|
return undefined;
|
|
345
|
-
if (mode === 'Simulated'
|
|
346
|
-
|
|
375
|
+
if (mode === 'Simulated') {
|
|
376
|
+
this.gear = (_b = (_a = this.gear) !== null && _a !== void 0 ? _a : this.getSetting('startGear')) !== null && _b !== void 0 ? _b : 0;
|
|
377
|
+
return this.gear.toString();
|
|
378
|
+
}
|
|
347
379
|
if (mode === "SlopeDelta")
|
|
348
380
|
return this.gearDelta > 0 ? `+${this.gearDelta}` : `${this.gearDelta}`;
|
|
349
|
-
|
|
381
|
+
if (mode === 'Adapter') {
|
|
382
|
+
this.gear = (_c = this.gear) !== null && _c !== void 0 ? _c : this.getSetting('startGear');
|
|
383
|
+
return this.gear.toString();
|
|
384
|
+
}
|
|
385
|
+
return (_d = this.gear) === null || _d === void 0 ? void 0 : _d.toString();
|
|
350
386
|
}
|
|
351
387
|
}
|
|
352
388
|
SmartTrainerCyclingMode.config = {
|
package/lib/modes/power-base.js
CHANGED
|
@@ -179,6 +179,7 @@ class PowerBasedCyclingModeBase extends base_1.CyclingModeBase {
|
|
|
179
179
|
}
|
|
180
180
|
copyBikeData(data, bikeData) {
|
|
181
181
|
var _a;
|
|
182
|
+
const prevCadence = data.pedalRpm;
|
|
182
183
|
const keys = Object.keys(bikeData);
|
|
183
184
|
keys.forEach(key => {
|
|
184
185
|
if (bikeData[key] === null)
|
|
@@ -195,7 +196,10 @@ class PowerBasedCyclingModeBase extends base_1.CyclingModeBase {
|
|
|
195
196
|
if (data.slope === undefined)
|
|
196
197
|
data.slope = 0;
|
|
197
198
|
if (bikeData.isPedalling === undefined)
|
|
198
|
-
data.isPedalling = data.pedalRpm > 0;
|
|
199
|
+
(data.isPedalling = data.pedalRpm > 0 || data.power > 0);
|
|
200
|
+
if (bikeData.pedalRpm === 0 && bikeData.power > 0 && prevCadence !== undefined) {
|
|
201
|
+
data.pedalRpm = prevCadence;
|
|
202
|
+
}
|
|
199
203
|
if (((_a = this.prevRequest) === null || _a === void 0 ? void 0 : _a.slope) !== undefined) {
|
|
200
204
|
data.slope = this.prevRequest.slope;
|
|
201
205
|
}
|