incyclist-devices 1.4.45 → 1.4.46
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/Device.d.ts +2 -0
- package/lib/Device.js +1 -0
- package/lib/ant/AntAdapter.d.ts +1 -0
- package/lib/ant/AntAdapter.js +6 -0
- package/lib/ble/ble-device.d.ts +9 -7
- package/lib/ble/ble-device.js +83 -121
- package/lib/ble/ble-erg-mode.d.ts +24 -0
- package/lib/ble/ble-erg-mode.js +148 -0
- package/lib/ble/ble-interface.d.ts +13 -0
- package/lib/ble/ble-interface.js +49 -25
- package/lib/ble/ble-peripheral.d.ts +34 -0
- package/lib/ble/ble-peripheral.js +170 -0
- package/lib/ble/ble-st-mode.d.ts +24 -0
- package/lib/ble/ble-st-mode.js +148 -0
- package/lib/ble/ble.d.ts +9 -0
- package/lib/ble/fm.d.ts +6 -1
- package/lib/ble/fm.js +46 -6
- package/lib/ble/hrm.d.ts +1 -1
- package/lib/ble/hrm.js +6 -4
- package/lib/ble/incyclist-protocol.js +9 -1
- package/lib/ble/pwr.d.ts +1 -1
- package/lib/ble/pwr.js +6 -4
- package/lib/daum/DaumAdapter.d.ts +1 -0
- package/lib/daum/DaumAdapter.js +6 -0
- package/lib/kettler/ergo-racer/adapter.d.ts +1 -0
- package/lib/kettler/ergo-racer/adapter.js +6 -0
- package/lib/simulator/Simulator.d.ts +1 -0
- package/lib/simulator/Simulator.js +5 -0
- package/package.json +1 -1
package/lib/ble/fm.js
CHANGED
|
@@ -18,6 +18,7 @@ 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 FTMS_CP = '2ad9';
|
|
21
22
|
const bit = (nr) => (1 << nr);
|
|
22
23
|
const IndoorBikeDataFlag = {
|
|
23
24
|
MoreData: bit(0),
|
|
@@ -76,6 +77,8 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
76
77
|
constructor(props) {
|
|
77
78
|
super(props);
|
|
78
79
|
this.features = undefined;
|
|
80
|
+
this.hasControl = false;
|
|
81
|
+
this.isCPSubscribed = false;
|
|
79
82
|
this.data = {};
|
|
80
83
|
}
|
|
81
84
|
init() {
|
|
@@ -84,14 +87,20 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
84
87
|
});
|
|
85
88
|
return __awaiter(this, void 0, void 0, function* () {
|
|
86
89
|
try {
|
|
90
|
+
this.logEvent({ message: 'get device info' });
|
|
87
91
|
yield _super.init.call(this);
|
|
88
92
|
yield this.getFitnessMachineFeatures();
|
|
93
|
+
this.logEvent({ message: 'device info', deviceInfo: this.deviceInfo, features: this.features });
|
|
89
94
|
}
|
|
90
95
|
catch (err) {
|
|
91
96
|
return Promise.resolve(false);
|
|
92
97
|
}
|
|
93
98
|
});
|
|
94
99
|
}
|
|
100
|
+
onDisconnect() {
|
|
101
|
+
super.onDisconnect();
|
|
102
|
+
this.hasControl = false;
|
|
103
|
+
}
|
|
95
104
|
getProfile() {
|
|
96
105
|
return 'Smart Trainer';
|
|
97
106
|
}
|
|
@@ -112,7 +121,7 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
112
121
|
return true;
|
|
113
122
|
}
|
|
114
123
|
isHrm() {
|
|
115
|
-
return this.hasService('180d');
|
|
124
|
+
return this.hasService('180d') || (this.features && (this.features.fitnessMachine & FitnessMachineFeatureFlag.HeartRateMeasurementSupported) !== 0);
|
|
116
125
|
}
|
|
117
126
|
parseHrm(_data) {
|
|
118
127
|
const data = Buffer.from(_data);
|
|
@@ -193,8 +202,12 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
193
202
|
return this.features;
|
|
194
203
|
try {
|
|
195
204
|
const data = yield this.read('2acc');
|
|
196
|
-
|
|
197
|
-
|
|
205
|
+
const buffer = data ? Buffer.from(data) : undefined;
|
|
206
|
+
if (buffer) {
|
|
207
|
+
const fitnessMachine = buffer.readUInt32LE(0);
|
|
208
|
+
const targetSettings = buffer.readUInt32LE(4);
|
|
209
|
+
this.features = { fitnessMachine, targetSettings };
|
|
210
|
+
}
|
|
198
211
|
}
|
|
199
212
|
catch (err) {
|
|
200
213
|
this.logEvent({ message: 'could not read FitnessMachineFeatures', error: err.message, stack: err.stack });
|
|
@@ -211,9 +224,28 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
211
224
|
this.emit('data', res);
|
|
212
225
|
}
|
|
213
226
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
227
|
+
requestControl() {
|
|
228
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
229
|
+
if (this.hasControl)
|
|
230
|
+
return true;
|
|
231
|
+
const data = Buffer.alloc(1);
|
|
232
|
+
data.writeUInt8(0, 0);
|
|
233
|
+
const success = yield this.write(FTMS_CP, data);
|
|
234
|
+
if (success)
|
|
235
|
+
this.hasControl = true;
|
|
236
|
+
return this.hasControl;
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
setTargetPower(power) {
|
|
240
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
241
|
+
const hasControl = yield this.requestControl();
|
|
242
|
+
if (!hasControl)
|
|
243
|
+
throw new Error('setTargetPower not possible - control is disabled');
|
|
244
|
+
const data = Buffer.alloc(3);
|
|
245
|
+
data.writeUInt8(5, 0);
|
|
246
|
+
data.writeInt16LE(Math.round(power), 1);
|
|
247
|
+
const res = yield this.write(FTMS_CP, data);
|
|
248
|
+
});
|
|
217
249
|
}
|
|
218
250
|
reset() {
|
|
219
251
|
this.data = {};
|
|
@@ -237,6 +269,12 @@ class FmAdapter extends Device_1.default {
|
|
|
237
269
|
isBike() { return this.device.isBike(); }
|
|
238
270
|
isHrm() { return this.device.isHrm(); }
|
|
239
271
|
isPower() { return this.device.isPower(); }
|
|
272
|
+
isSame(device) {
|
|
273
|
+
if (!(device instanceof FmAdapter))
|
|
274
|
+
return false;
|
|
275
|
+
const adapter = device;
|
|
276
|
+
return (adapter.getName() === this.getName() && adapter.getProfile() === this.getProfile());
|
|
277
|
+
}
|
|
240
278
|
getProfile() {
|
|
241
279
|
return 'Smart Trainer';
|
|
242
280
|
}
|
|
@@ -316,6 +354,8 @@ class FmAdapter extends Device_1.default {
|
|
|
316
354
|
start(props) {
|
|
317
355
|
return __awaiter(this, void 0, void 0, function* () {
|
|
318
356
|
this.logger.logEvent({ message: 'start requested', profile: this.getProfile(), props });
|
|
357
|
+
if (this.ble.isScanning())
|
|
358
|
+
yield this.ble.stopScan();
|
|
319
359
|
try {
|
|
320
360
|
const bleDevice = yield this.ble.connectDevice(this.device);
|
|
321
361
|
if (bleDevice) {
|
package/lib/ble/hrm.d.ts
CHANGED
|
@@ -21,7 +21,6 @@ export default class BleHrmDevice extends BleDevice {
|
|
|
21
21
|
getServiceUUids(): string[];
|
|
22
22
|
parseHrm(_data: Uint8Array): HrmData;
|
|
23
23
|
onData(characteristic: string, data: Buffer): void;
|
|
24
|
-
write(characteristic: any, data: any): Promise<boolean>;
|
|
25
24
|
}
|
|
26
25
|
export declare class HrmAdapter extends DeviceAdapter {
|
|
27
26
|
device: BleHrmDevice;
|
|
@@ -34,6 +33,7 @@ export declare class HrmAdapter extends DeviceAdapter {
|
|
|
34
33
|
isBike(): boolean;
|
|
35
34
|
isHrm(): boolean;
|
|
36
35
|
isPower(): boolean;
|
|
36
|
+
isSame(device: DeviceAdapter): boolean;
|
|
37
37
|
getProfile(): string;
|
|
38
38
|
getName(): string;
|
|
39
39
|
getDisplayName(): string;
|
package/lib/ble/hrm.js
CHANGED
|
@@ -56,10 +56,6 @@ class BleHrmDevice extends ble_device_1.BleDevice {
|
|
|
56
56
|
this.emit('data', res);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
write(characteristic, data) {
|
|
60
|
-
console.log('write', characteristic, data);
|
|
61
|
-
return Promise.resolve(true);
|
|
62
|
-
}
|
|
63
59
|
}
|
|
64
60
|
exports.default = BleHrmDevice;
|
|
65
61
|
BleHrmDevice.services = ['180d'];
|
|
@@ -77,6 +73,12 @@ class HrmAdapter extends Device_1.default {
|
|
|
77
73
|
isBike() { return false; }
|
|
78
74
|
isHrm() { return true; }
|
|
79
75
|
isPower() { return false; }
|
|
76
|
+
isSame(device) {
|
|
77
|
+
if (!(device instanceof HrmAdapter))
|
|
78
|
+
return false;
|
|
79
|
+
const adapter = device;
|
|
80
|
+
return (adapter.getName() === this.getName() && adapter.getProfile() === this.getProfile());
|
|
81
|
+
}
|
|
80
82
|
getProfile() {
|
|
81
83
|
return 'Heartrate Monitor';
|
|
82
84
|
}
|
|
@@ -78,7 +78,15 @@ class BleProtocol extends DeviceProtocol_1.default {
|
|
|
78
78
|
case 'fm':
|
|
79
79
|
case 'smart trainer':
|
|
80
80
|
case 'fitness machine':
|
|
81
|
-
|
|
81
|
+
let device;
|
|
82
|
+
if (fromDevice)
|
|
83
|
+
device = bleDevice;
|
|
84
|
+
else {
|
|
85
|
+
device = this.ble.findDeviceInCache(Object.assign(Object.assign({}, props()), { profile: 'Smart Trainer' }));
|
|
86
|
+
if (!device)
|
|
87
|
+
device = new fm_1.default(props());
|
|
88
|
+
}
|
|
89
|
+
return new fm_1.FmAdapter(device, this);
|
|
82
90
|
case 'cp':
|
|
83
91
|
case 'power meter':
|
|
84
92
|
return new pwr_1.PwrAdapter(fromDevice ? bleDevice : new pwr_1.default(props()), this);
|
package/lib/ble/pwr.d.ts
CHANGED
|
@@ -42,7 +42,6 @@ export default class BleCyclingPowerDevice extends BleDevice {
|
|
|
42
42
|
};
|
|
43
43
|
parsePower(_data: Uint8Array): PowerData;
|
|
44
44
|
onData(characteristic: string, data: Buffer): void;
|
|
45
|
-
write(characteristic: any, data: any): Promise<boolean>;
|
|
46
45
|
reset(): void;
|
|
47
46
|
}
|
|
48
47
|
export declare class PwrAdapter extends DeviceAdapter {
|
|
@@ -59,6 +58,7 @@ export declare class PwrAdapter extends DeviceAdapter {
|
|
|
59
58
|
isBike(): boolean;
|
|
60
59
|
isHrm(): boolean;
|
|
61
60
|
isPower(): boolean;
|
|
61
|
+
isSame(device: DeviceAdapter): boolean;
|
|
62
62
|
getProfile(): string;
|
|
63
63
|
getName(): string;
|
|
64
64
|
getDisplayName(): string;
|
package/lib/ble/pwr.js
CHANGED
|
@@ -114,10 +114,6 @@ class BleCyclingPowerDevice extends ble_device_1.BleDevice {
|
|
|
114
114
|
this.emit('data', res);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
|
-
write(characteristic, data) {
|
|
118
|
-
console.log('write', characteristic, data);
|
|
119
|
-
return Promise.resolve(true);
|
|
120
|
-
}
|
|
121
117
|
reset() {
|
|
122
118
|
this.instantaneousPower = undefined;
|
|
123
119
|
this.balance = undefined;
|
|
@@ -147,6 +143,12 @@ class PwrAdapter extends Device_1.default {
|
|
|
147
143
|
isBike() { return true; }
|
|
148
144
|
isHrm() { return false; }
|
|
149
145
|
isPower() { return true; }
|
|
146
|
+
isSame(device) {
|
|
147
|
+
if (!(device instanceof PwrAdapter))
|
|
148
|
+
return false;
|
|
149
|
+
const adapter = device;
|
|
150
|
+
return (adapter.getName() === this.getName() && adapter.getProfile() === this.getProfile());
|
|
151
|
+
}
|
|
150
152
|
getProfile() {
|
|
151
153
|
return 'Power Meter';
|
|
152
154
|
}
|
|
@@ -39,6 +39,7 @@ export default class DaumAdapterBase extends IncyclistDevice implements DeviceAd
|
|
|
39
39
|
isBike(): boolean;
|
|
40
40
|
isPower(): boolean;
|
|
41
41
|
isHrm(): boolean;
|
|
42
|
+
isSame(device: DeviceAdapter): boolean;
|
|
42
43
|
setIgnoreHrm(ignore: any): void;
|
|
43
44
|
setIgnoreBike(ignore: any): void;
|
|
44
45
|
isStopped(): boolean;
|
package/lib/daum/DaumAdapter.js
CHANGED
|
@@ -131,6 +131,12 @@ class DaumAdapterBase extends Device_1.default {
|
|
|
131
131
|
isHrm() {
|
|
132
132
|
return true;
|
|
133
133
|
}
|
|
134
|
+
isSame(device) {
|
|
135
|
+
if (!(device instanceof DaumAdapterBase))
|
|
136
|
+
return false;
|
|
137
|
+
const adapter = device;
|
|
138
|
+
return (adapter.getName() === this.getName() && adapter.getPort() === this.getPort());
|
|
139
|
+
}
|
|
134
140
|
setIgnoreHrm(ignore) {
|
|
135
141
|
this.ignoreHrm = ignore;
|
|
136
142
|
}
|
|
@@ -56,6 +56,12 @@ class KettlerRacerAdapter extends Device_1.default {
|
|
|
56
56
|
isBike() { return true; }
|
|
57
57
|
isPower() { return true; }
|
|
58
58
|
isHrm() { return true; }
|
|
59
|
+
isSame(device) {
|
|
60
|
+
if (!(device instanceof KettlerRacerAdapter))
|
|
61
|
+
return false;
|
|
62
|
+
const adapter = device;
|
|
63
|
+
return (adapter.getName() === this.getName() && adapter.getPort() === this.getPort());
|
|
64
|
+
}
|
|
59
65
|
setID(id) {
|
|
60
66
|
this.id = id;
|
|
61
67
|
}
|
|
@@ -68,6 +68,11 @@ class Simulator extends Device_1.default {
|
|
|
68
68
|
isBike() { return true; }
|
|
69
69
|
isHrm() { return false; }
|
|
70
70
|
isPower() { return true; }
|
|
71
|
+
isSame(device) {
|
|
72
|
+
if (!(device instanceof Simulator))
|
|
73
|
+
return false;
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
71
76
|
getID() { return Simulator.NAME; }
|
|
72
77
|
getName() { return Simulator.NAME; }
|
|
73
78
|
getPort() { return 'local'; }
|