incyclist-devices 3.0.32 → 3.0.33
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/cjs/ble/fm/sensor.js +32 -25
- package/lib/esm/ble/fm/sensor.js +32 -25
- package/lib/types/ble/fm/sensor.d.ts +2 -2
- package/package.json +1 -1
package/lib/cjs/ble/fm/sensor.js
CHANGED
|
@@ -498,7 +498,7 @@ class BleFitnessMachineDevice extends sensor_js_1.TBleSensor {
|
|
|
498
498
|
return serviceData;
|
|
499
499
|
}
|
|
500
500
|
else {
|
|
501
|
-
this.logEvent({ message: 'could not parse service data', reason: 'not enough data', raw: data?.toString('hex') });
|
|
501
|
+
this.logEvent({ message: 'could not parse service data', reason: data == null ? 'not available' : 'not enough data', raw: data?.toString('hex') });
|
|
502
502
|
}
|
|
503
503
|
}
|
|
504
504
|
catch (err) {
|
|
@@ -511,37 +511,40 @@ class BleFitnessMachineDevice extends sensor_js_1.TBleSensor {
|
|
|
511
511
|
if (this.getName().startsWith('MRK-')) {
|
|
512
512
|
return { fitnessMachine: 0, targetSettings: 0, setPower: true, power: true, heartrate: true };
|
|
513
513
|
}
|
|
514
|
+
let data;
|
|
515
|
+
try {
|
|
516
|
+
this.logEvent({ message: 'reading FitnessMachineFeatures', device: this.getName() });
|
|
517
|
+
data = await this.read('2acc');
|
|
518
|
+
}
|
|
519
|
+
catch (err) {
|
|
520
|
+
this.logEvent({ message: 'could not read FitnessMachineFeatures', error: err.message, stack: err.stack, device: this.getName() });
|
|
521
|
+
return undefined;
|
|
522
|
+
}
|
|
523
|
+
const buffer = data ? Buffer.from(data) : undefined;
|
|
514
524
|
try {
|
|
515
|
-
const data = await this.read('2acc');
|
|
516
|
-
const buffer = data ? Buffer.from(data) : undefined;
|
|
517
525
|
const services = this.peripheral?.services || [];
|
|
518
526
|
let power = services.some(s => (0, utils_js_1.matches)(s.uuid, '1818'));
|
|
519
527
|
let heartrate = services.some(s => (0, utils_js_1.matches)(s.uuid, '180d'));
|
|
520
528
|
const dataLength = buffer?.length ?? 0;
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
return this._features;
|
|
538
|
-
}
|
|
539
|
-
else {
|
|
540
|
-
return { fitnessMachine: 0, targetSettings: 0, power, heartrate };
|
|
541
|
-
}
|
|
529
|
+
const fitnessMachine = dataLength >= 4 ? buffer.readUInt32LE(0) : 0;
|
|
530
|
+
const targetSettings = dataLength >= 8 ? buffer.readUInt32LE(4) : 0;
|
|
531
|
+
const fmInfo = this.buildFitnessMachineInfo(fitnessMachine) ?? [];
|
|
532
|
+
const tsInfo = this.buildTargetSettingsInfo(targetSettings) ?? [];
|
|
533
|
+
power = power || (fitnessMachine & consts_js_2.FitnessMachineFeatureFlag.PowerMeasurementSupported) !== 0;
|
|
534
|
+
heartrate = heartrate || (fitnessMachine & consts_js_2.FitnessMachineFeatureFlag.HeartRateMeasurementSupported) !== 0;
|
|
535
|
+
const cadence = (fitnessMachine & consts_js_2.FitnessMachineFeatureFlag.CadenceSupported) !== 0;
|
|
536
|
+
const setSlope = (targetSettings & consts_js_2.TargetSettingFeatureFlag.IndoorBikeSimulationParametersSupported) !== 0
|
|
537
|
+
|| (targetSettings & consts_js_2.TargetSettingFeatureFlag.InclinationTargetSettingSupported) !== 0;
|
|
538
|
+
const setPower = (targetSettings & consts_js_2.TargetSettingFeatureFlag.PowerTargetSettingSupported) !== 0;
|
|
539
|
+
const setResistance = (targetSettings & consts_js_2.TargetSettingFeatureFlag.ResistanceTargetSettingSupported) !== 0;
|
|
540
|
+
this._features = { fitnessMachine, targetSettings, power, heartrate, cadence, setPower, setSlope, setResistance };
|
|
541
|
+
this.logEvent({ message: 'supported features', device: this.getName(), fmFeatures: fmInfo.join('|'), tsFeatures: tsInfo.join('|'), features: this._features, raw: buffer?.toString('hex') });
|
|
542
|
+
this._features.fmInfo = fmInfo;
|
|
543
|
+
this._features.tsInfo = tsInfo;
|
|
544
|
+
return this._features;
|
|
542
545
|
}
|
|
543
546
|
catch (err) {
|
|
544
|
-
this.logEvent({ message: 'could not
|
|
547
|
+
this.logEvent({ message: 'could not parse FitnessMachineFeatures', error: err.message, stack: err.stack, device: this.getName(), raw: buffer?.toString('hex') });
|
|
545
548
|
return undefined;
|
|
546
549
|
}
|
|
547
550
|
}
|
|
@@ -549,6 +552,8 @@ class BleFitnessMachineDevice extends sensor_js_1.TBleSensor {
|
|
|
549
552
|
return this.getSupportedServiceUUids()?.some(s => (0, utils_js_1.matches)(s, consts_js_2.ZWIFT_PLAY_UUID));
|
|
550
553
|
}
|
|
551
554
|
buildFitnessMachineInfo(fitnessMachine) {
|
|
555
|
+
if (fitnessMachine == null)
|
|
556
|
+
return;
|
|
552
557
|
if (this.getName().startsWith('MRK-')) {
|
|
553
558
|
return ['avgSpeed', 'cadence', 'power', 'pace'];
|
|
554
559
|
}
|
|
@@ -583,6 +588,8 @@ class BleFitnessMachineDevice extends sensor_js_1.TBleSensor {
|
|
|
583
588
|
return info;
|
|
584
589
|
}
|
|
585
590
|
buildTargetSettingsInfo(targetSettings) {
|
|
591
|
+
if (targetSettings == null)
|
|
592
|
+
return;
|
|
586
593
|
const info = [];
|
|
587
594
|
const check = (flag, name) => {
|
|
588
595
|
if (targetSettings & flag)
|
package/lib/esm/ble/fm/sensor.js
CHANGED
|
@@ -496,7 +496,7 @@ export default class BleFitnessMachineDevice extends TBleSensor {
|
|
|
496
496
|
return serviceData;
|
|
497
497
|
}
|
|
498
498
|
else {
|
|
499
|
-
this.logEvent({ message: 'could not parse service data', reason: 'not enough data', raw: data?.toString('hex') });
|
|
499
|
+
this.logEvent({ message: 'could not parse service data', reason: data == null ? 'not available' : 'not enough data', raw: data?.toString('hex') });
|
|
500
500
|
}
|
|
501
501
|
}
|
|
502
502
|
catch (err) {
|
|
@@ -509,37 +509,40 @@ export default class BleFitnessMachineDevice extends TBleSensor {
|
|
|
509
509
|
if (this.getName().startsWith('MRK-')) {
|
|
510
510
|
return { fitnessMachine: 0, targetSettings: 0, setPower: true, power: true, heartrate: true };
|
|
511
511
|
}
|
|
512
|
+
let data;
|
|
513
|
+
try {
|
|
514
|
+
this.logEvent({ message: 'reading FitnessMachineFeatures', device: this.getName() });
|
|
515
|
+
data = await this.read('2acc');
|
|
516
|
+
}
|
|
517
|
+
catch (err) {
|
|
518
|
+
this.logEvent({ message: 'could not read FitnessMachineFeatures', error: err.message, stack: err.stack, device: this.getName() });
|
|
519
|
+
return undefined;
|
|
520
|
+
}
|
|
521
|
+
const buffer = data ? Buffer.from(data) : undefined;
|
|
512
522
|
try {
|
|
513
|
-
const data = await this.read('2acc');
|
|
514
|
-
const buffer = data ? Buffer.from(data) : undefined;
|
|
515
523
|
const services = this.peripheral?.services || [];
|
|
516
524
|
let power = services.some(s => matches(s.uuid, '1818'));
|
|
517
525
|
let heartrate = services.some(s => matches(s.uuid, '180d'));
|
|
518
526
|
const dataLength = buffer?.length ?? 0;
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
return this._features;
|
|
536
|
-
}
|
|
537
|
-
else {
|
|
538
|
-
return { fitnessMachine: 0, targetSettings: 0, power, heartrate };
|
|
539
|
-
}
|
|
527
|
+
const fitnessMachine = dataLength >= 4 ? buffer.readUInt32LE(0) : 0;
|
|
528
|
+
const targetSettings = dataLength >= 8 ? buffer.readUInt32LE(4) : 0;
|
|
529
|
+
const fmInfo = this.buildFitnessMachineInfo(fitnessMachine) ?? [];
|
|
530
|
+
const tsInfo = this.buildTargetSettingsInfo(targetSettings) ?? [];
|
|
531
|
+
power = power || (fitnessMachine & FitnessMachineFeatureFlag.PowerMeasurementSupported) !== 0;
|
|
532
|
+
heartrate = heartrate || (fitnessMachine & FitnessMachineFeatureFlag.HeartRateMeasurementSupported) !== 0;
|
|
533
|
+
const cadence = (fitnessMachine & FitnessMachineFeatureFlag.CadenceSupported) !== 0;
|
|
534
|
+
const setSlope = (targetSettings & TargetSettingFeatureFlag.IndoorBikeSimulationParametersSupported) !== 0
|
|
535
|
+
|| (targetSettings & TargetSettingFeatureFlag.InclinationTargetSettingSupported) !== 0;
|
|
536
|
+
const setPower = (targetSettings & TargetSettingFeatureFlag.PowerTargetSettingSupported) !== 0;
|
|
537
|
+
const setResistance = (targetSettings & TargetSettingFeatureFlag.ResistanceTargetSettingSupported) !== 0;
|
|
538
|
+
this._features = { fitnessMachine, targetSettings, power, heartrate, cadence, setPower, setSlope, setResistance };
|
|
539
|
+
this.logEvent({ message: 'supported features', device: this.getName(), fmFeatures: fmInfo.join('|'), tsFeatures: tsInfo.join('|'), features: this._features, raw: buffer?.toString('hex') });
|
|
540
|
+
this._features.fmInfo = fmInfo;
|
|
541
|
+
this._features.tsInfo = tsInfo;
|
|
542
|
+
return this._features;
|
|
540
543
|
}
|
|
541
544
|
catch (err) {
|
|
542
|
-
this.logEvent({ message: 'could not
|
|
545
|
+
this.logEvent({ message: 'could not parse FitnessMachineFeatures', error: err.message, stack: err.stack, device: this.getName(), raw: buffer?.toString('hex') });
|
|
543
546
|
return undefined;
|
|
544
547
|
}
|
|
545
548
|
}
|
|
@@ -547,6 +550,8 @@ export default class BleFitnessMachineDevice extends TBleSensor {
|
|
|
547
550
|
return this.getSupportedServiceUUids()?.some(s => matches(s, ZWIFT_PLAY_UUID));
|
|
548
551
|
}
|
|
549
552
|
buildFitnessMachineInfo(fitnessMachine) {
|
|
553
|
+
if (fitnessMachine == null)
|
|
554
|
+
return;
|
|
550
555
|
if (this.getName().startsWith('MRK-')) {
|
|
551
556
|
return ['avgSpeed', 'cadence', 'power', 'pace'];
|
|
552
557
|
}
|
|
@@ -581,6 +586,8 @@ export default class BleFitnessMachineDevice extends TBleSensor {
|
|
|
581
586
|
return info;
|
|
582
587
|
}
|
|
583
588
|
buildTargetSettingsInfo(targetSettings) {
|
|
589
|
+
if (targetSettings == null)
|
|
590
|
+
return;
|
|
584
591
|
const info = [];
|
|
585
592
|
const check = (flag, name) => {
|
|
586
593
|
if (targetSettings & flag)
|
|
@@ -47,8 +47,8 @@ export default class BleFitnessMachineDevice extends TBleSensor {
|
|
|
47
47
|
protected parseServiceData(): FtmsServiceData | undefined;
|
|
48
48
|
getFitnessMachineFeatures(): Promise<IndoorBikeFeatures | undefined>;
|
|
49
49
|
supportsVirtualShifting(): boolean;
|
|
50
|
-
protected buildFitnessMachineInfo(fitnessMachine
|
|
51
|
-
protected buildTargetSettingsInfo(targetSettings
|
|
50
|
+
protected buildFitnessMachineInfo(fitnessMachine?: number): string[] | undefined;
|
|
51
|
+
protected buildTargetSettingsInfo(targetSettings?: number): string[] | undefined;
|
|
52
52
|
protected writeFtmsMessage(requestedOpCode: number, data: Buffer, props?: BleWriteProps): Promise<number>;
|
|
53
53
|
setTargetInclination(inclination: number): Promise<boolean>;
|
|
54
54
|
setIndoorBikeSimulation(windSpeed: number, gradient: number, crr: number, cw: number): Promise<boolean>;
|