incyclist-devices 1.4.93 → 1.4.94
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.js +1 -1
- package/lib/ant/antpwr/pwr-adapter.d.ts +1 -0
- package/lib/ant/antpwr/pwr-adapter.js +3 -0
- package/lib/ble/ble-device.d.ts +2 -1
- package/lib/ble/ble-device.js +29 -9
- package/lib/ble/ble-interface.d.ts +1 -0
- package/lib/ble/ble-interface.js +17 -4
- package/lib/ble/ble-peripheral.d.ts +1 -1
- package/lib/ble/ble-peripheral.js +23 -13
- package/lib/ble/ble.d.ts +3 -0
- package/lib/ble/fm.d.ts +6 -2
- package/lib/ble/fm.js +143 -90
- package/lib/ble/hrm.d.ts +1 -1
- package/lib/ble/hrm.js +4 -3
- package/lib/ble/pwr.d.ts +2 -1
- package/lib/ble/pwr.js +10 -5
- package/lib/ble/tacx.d.ts +1 -1
- package/lib/ble/tacx.js +4 -4
- package/lib/ble/wahoo-kickr.d.ts +1 -1
- package/lib/ble/wahoo-kickr.js +7 -2
- package/package.json +1 -1
package/lib/Device.js
CHANGED
|
@@ -9,7 +9,7 @@ class IncyclistDevice {
|
|
|
9
9
|
this.detected = false;
|
|
10
10
|
this.selected = false;
|
|
11
11
|
this.onDataFn = undefined;
|
|
12
|
-
this.settings = settings;
|
|
12
|
+
this.settings = settings || {};
|
|
13
13
|
}
|
|
14
14
|
isBike() { throw new Error('not implemented'); }
|
|
15
15
|
isPower() { throw new Error('not implemented'); }
|
|
@@ -36,6 +36,7 @@ export default class AntFEAdapter extends AntAdapter {
|
|
|
36
36
|
getDisplayName(): string;
|
|
37
37
|
getCyclingMode(): CyclingMode;
|
|
38
38
|
getDefaultCyclingMode(): CyclingMode;
|
|
39
|
+
getSupportedCyclingModes(): any[];
|
|
39
40
|
onAttached(): void;
|
|
40
41
|
getLogData(data: any, excludeList: any): any;
|
|
41
42
|
onDeviceData(deviceData: AntPwrData): void;
|
|
@@ -58,6 +58,9 @@ class AntFEAdapter extends AntAdapter_1.default {
|
|
|
58
58
|
getDefaultCyclingMode() {
|
|
59
59
|
return new power_meter_1.default(this);
|
|
60
60
|
}
|
|
61
|
+
getSupportedCyclingModes() {
|
|
62
|
+
return [power_meter_1.default];
|
|
63
|
+
}
|
|
61
64
|
onAttached() {
|
|
62
65
|
this.logger.logEvent({ message: 'Device connected' });
|
|
63
66
|
this.connected = true;
|
package/lib/ble/ble-device.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export declare abstract class BleDevice extends BleDeviceClass {
|
|
|
35
35
|
workerIv: NodeJS.Timeout;
|
|
36
36
|
prevMessages: MessageLog[];
|
|
37
37
|
constructor(props?: BleDeviceConstructProps);
|
|
38
|
+
getServices(): string[];
|
|
38
39
|
logEvent(event: any): void;
|
|
39
40
|
setLogger(logger: EventLogger): void;
|
|
40
41
|
setInterface(ble: BleInterfaceClass): void;
|
|
@@ -51,7 +52,7 @@ export declare abstract class BleDevice extends BleDeviceClass {
|
|
|
51
52
|
disconnect(): Promise<boolean>;
|
|
52
53
|
abstract getProfile(): string;
|
|
53
54
|
checkForDuplicate(characteristic: string, data: Buffer): boolean;
|
|
54
|
-
onData(characteristic: string,
|
|
55
|
+
onData(characteristic: string, _data: Buffer): boolean;
|
|
55
56
|
timeoutCheck(): void;
|
|
56
57
|
startWorker(): void;
|
|
57
58
|
stopWorker(): void;
|
package/lib/ble/ble-device.js
CHANGED
|
@@ -47,13 +47,14 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
47
47
|
this.logger = new gd_eventlog_1.EventLogger('BleDevice');
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
+
getServices() {
|
|
51
|
+
return this.services;
|
|
52
|
+
}
|
|
50
53
|
logEvent(event) {
|
|
51
54
|
if (this.logger) {
|
|
52
55
|
this.logger.logEvent(event);
|
|
53
56
|
}
|
|
54
|
-
|
|
55
|
-
console.log('~~~BLE:', event);
|
|
56
|
-
}
|
|
57
|
+
console.log('~~~BLE:', event);
|
|
57
58
|
}
|
|
58
59
|
setLogger(logger) {
|
|
59
60
|
this.logger = logger;
|
|
@@ -80,8 +81,12 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
80
81
|
this.state = "disconnected";
|
|
81
82
|
if (!this.connectState.isDisconnecting) {
|
|
82
83
|
this.peripheral.state = 'disconnected';
|
|
84
|
+
this.connectState.isConnecting = false;
|
|
83
85
|
this.connectState.isConnected = false;
|
|
84
|
-
this.
|
|
86
|
+
this.cleanupListeners();
|
|
87
|
+
this.subscribedCharacteristics = [];
|
|
88
|
+
this.ble.onDisconnect(this.peripheral);
|
|
89
|
+
this.connect({ reconnect: true });
|
|
85
90
|
}
|
|
86
91
|
this.emit('disconnected');
|
|
87
92
|
}
|
|
@@ -128,6 +133,7 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
128
133
|
this.connectState.isConnecting = true;
|
|
129
134
|
try {
|
|
130
135
|
const connector = this.ble.getConnector(peripheral);
|
|
136
|
+
connector.on('disconnect', () => { this.onDisconnect(); });
|
|
131
137
|
yield connector.connect();
|
|
132
138
|
yield connector.initialize();
|
|
133
139
|
yield this.subscribeAll(connector);
|
|
@@ -156,9 +162,10 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
156
162
|
}
|
|
157
163
|
connect(props) {
|
|
158
164
|
return __awaiter(this, void 0, void 0, function* () {
|
|
165
|
+
const { reconnect } = props || {};
|
|
159
166
|
try {
|
|
160
|
-
this.logEvent({ message: 'connect', address: this.peripheral ? this.peripheral.address : this.address, state: this.connectState });
|
|
161
|
-
if (this.connectState.isConnecting) {
|
|
167
|
+
this.logEvent({ message: reconnect ? 'reconnect' : 'connect', address: this.peripheral ? this.peripheral.address : this.address, state: this.connectState });
|
|
168
|
+
if (!reconnect && this.connectState.isConnecting) {
|
|
162
169
|
yield this.waitForConnectFinished(CONNECT_WAIT_TIMEOUT);
|
|
163
170
|
}
|
|
164
171
|
if (this.connectState.isConnected) {
|
|
@@ -238,6 +245,8 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
238
245
|
}
|
|
239
246
|
if (!this.connectState.isConnecting && !this.connectState.isConnected) {
|
|
240
247
|
this.connectState.isDisconnecting = false;
|
|
248
|
+
this.connectState.isConnecting = false;
|
|
249
|
+
this.connectState.isConnected = false;
|
|
241
250
|
this.logEvent({ message: 'disconnect result: success', device: { id, name, address } });
|
|
242
251
|
return true;
|
|
243
252
|
}
|
|
@@ -245,13 +254,17 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
245
254
|
this.cleanupListeners();
|
|
246
255
|
setTimeout(() => { this.connectState.isDisconnecting = false; }, 1000);
|
|
247
256
|
this.logEvent({ message: 'disconnect result: unclear - connect ongoing', device: { id, name, address } });
|
|
257
|
+
this.connectState.isConnecting = false;
|
|
258
|
+
this.connectState.isConnected = false;
|
|
248
259
|
return true;
|
|
249
260
|
}
|
|
250
261
|
if (this.connectState.isConnected) {
|
|
251
262
|
this.ble.removeConnectedDevice(this);
|
|
252
263
|
this.cleanupListeners();
|
|
253
|
-
setTimeout(() => { this.connectState.isDisconnecting = false; }, 1000);
|
|
254
264
|
this.logEvent({ message: 'disconnect result: success', device: { id, name, address } });
|
|
265
|
+
this.connectState.isDisconnecting = false;
|
|
266
|
+
this.connectState.isConnecting = false;
|
|
267
|
+
this.connectState.isConnected = false;
|
|
255
268
|
return true;
|
|
256
269
|
}
|
|
257
270
|
});
|
|
@@ -273,10 +286,11 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
273
286
|
}
|
|
274
287
|
return false;
|
|
275
288
|
}
|
|
276
|
-
onData(characteristic,
|
|
289
|
+
onData(characteristic, _data) {
|
|
290
|
+
const data = Buffer.from(_data);
|
|
277
291
|
const isDuplicate = this.checkForDuplicate(characteristic, data);
|
|
278
292
|
if (isDuplicate) {
|
|
279
|
-
return;
|
|
293
|
+
return false;
|
|
280
294
|
}
|
|
281
295
|
this.logEvent({ message: 'got data', characteristic, data: data.toString('hex'), writeQueue: this.writeQueue.length });
|
|
282
296
|
if (this.writeQueue.length > 0) {
|
|
@@ -286,8 +300,10 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
286
300
|
this.writeQueue.splice(writeIdx, 1);
|
|
287
301
|
if (writeItem.resolve)
|
|
288
302
|
writeItem.resolve(data);
|
|
303
|
+
return false;
|
|
289
304
|
}
|
|
290
305
|
}
|
|
306
|
+
return true;
|
|
291
307
|
}
|
|
292
308
|
timeoutCheck() {
|
|
293
309
|
const now = Date.now();
|
|
@@ -321,6 +337,8 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
321
337
|
write(characteristicUuid, data, props) {
|
|
322
338
|
return __awaiter(this, void 0, void 0, function* () {
|
|
323
339
|
try {
|
|
340
|
+
if (!this.isConnected())
|
|
341
|
+
throw new Error('not connected');
|
|
324
342
|
const { withoutResponse, timeout } = props || {};
|
|
325
343
|
const connector = this.ble.getConnector(this.peripheral);
|
|
326
344
|
const isAlreadySubscribed = connector.isSubscribed(characteristicUuid);
|
|
@@ -380,6 +398,8 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
380
398
|
}
|
|
381
399
|
read(characteristicUuid) {
|
|
382
400
|
return new Promise((resolve, reject) => {
|
|
401
|
+
if (!this.isConnected())
|
|
402
|
+
return reject(new Error('not connected'));
|
|
383
403
|
const characteristic = this.characteristics.find(c => c.uuid === characteristicUuid || (0, ble_1.uuid)(c.uuid) === characteristicUuid);
|
|
384
404
|
if (!characteristic) {
|
|
385
405
|
reject(new Error('Characteristic not found'));
|
|
@@ -67,6 +67,7 @@ export default class BleInterface extends BleInterfaceClass {
|
|
|
67
67
|
getServicesFromDevice(device: BleDeviceClass): string[];
|
|
68
68
|
waitForConnectFinished(timeout: any): Promise<unknown>;
|
|
69
69
|
addPeripheralToCache(peripheral: any, props?: {}): void;
|
|
70
|
+
onDisconnect(peripheral: any): void;
|
|
70
71
|
getConnector(peripheral: BlePeripheral): any;
|
|
71
72
|
findPeripheral(peripheral: BlePeripheral | {
|
|
72
73
|
id?: string;
|
package/lib/ble/ble-interface.js
CHANGED
|
@@ -290,6 +290,11 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
290
290
|
const connector = info && info.connector ? info.connector : new ble_peripheral_1.default(this, peripheral);
|
|
291
291
|
this.peripheralCache.push(Object.assign({ address: peripheral.address, ts: Date.now(), peripheral, connector }, props));
|
|
292
292
|
}
|
|
293
|
+
onDisconnect(peripheral) {
|
|
294
|
+
const idx = this.peripheralCache.findIndex(i => i.address === peripheral.address);
|
|
295
|
+
if (idx !== -1)
|
|
296
|
+
this.peripheralCache.splice(idx, 1);
|
|
297
|
+
}
|
|
293
298
|
getConnector(peripheral) {
|
|
294
299
|
const info = this.peripheralCache.find(i => i.address === peripheral.address);
|
|
295
300
|
if (!info) {
|
|
@@ -411,7 +416,8 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
411
416
|
if (devices && devices.length > 0) {
|
|
412
417
|
for (let i = 0; i < devices.length; i++) {
|
|
413
418
|
const idx = this.devices.push({ device: devices[i], isConnected: false }) - 1;
|
|
414
|
-
|
|
419
|
+
if (!devices[i].isConnected())
|
|
420
|
+
yield devices[i].connect();
|
|
415
421
|
this.devices[idx].isConnected = true;
|
|
416
422
|
}
|
|
417
423
|
}
|
|
@@ -558,14 +564,14 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
558
564
|
});
|
|
559
565
|
};
|
|
560
566
|
const onPeripheralFound = (peripheral, fromCache = false) => __awaiter(this, void 0, void 0, function* () {
|
|
567
|
+
if (!peripheral || !peripheral.advertisement || !peripheral.advertisement.localName || !peripheral.advertisement.serviceUuids || peripheral.advertisement.serviceUuids.length === 0)
|
|
568
|
+
return;
|
|
561
569
|
if (fromCache)
|
|
562
570
|
this.logEvent({ message: 'adding from Cache', peripheral: peripheral.address });
|
|
563
571
|
else {
|
|
564
572
|
const { id, name, address, advertisement = {} } = peripheral;
|
|
565
573
|
this.logEvent({ message: 'BLE scan: found device', peripheral: { id, name, address, services: advertisement.serviceUuids } });
|
|
566
574
|
}
|
|
567
|
-
if (!peripheral || !peripheral.advertisement || !peripheral.advertisement.serviceUuids || peripheral.advertisement.serviceUuids.length === 0)
|
|
568
|
-
return;
|
|
569
575
|
if (peripheral.address === undefined || peripheral.address === '')
|
|
570
576
|
peripheral.address = peripheral.id;
|
|
571
577
|
const isPeripheralProcessed = peripheralsProcessed.find(p => p === peripheral.address) !== undefined;
|
|
@@ -638,7 +644,14 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
638
644
|
this.peripheralCache.forEach(i => {
|
|
639
645
|
onPeripheralFound(i.peripheral, true);
|
|
640
646
|
});
|
|
641
|
-
|
|
647
|
+
let services = [];
|
|
648
|
+
if (scanForDevice) {
|
|
649
|
+
if (props.requested instanceof ble_1.BleDeviceClass) {
|
|
650
|
+
const device = props.requested;
|
|
651
|
+
services = (device.getServices()) || [];
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
bleBinding.startScanning(services, false, (err) => {
|
|
642
655
|
if (err) {
|
|
643
656
|
this.logEvent({ message: `${opStr} result: error`, requested: scanForDevice ? { name, address, profile } : undefined, error: err.message });
|
|
644
657
|
this.scanState.isScanning = false;
|
|
@@ -24,7 +24,7 @@ export default class BlePeripheralConnector {
|
|
|
24
24
|
initialize(enforce?: boolean): Promise<void>;
|
|
25
25
|
isSubscribed(characteristicUuid: string): boolean;
|
|
26
26
|
subscribeAll(callback: (characteristicUuid: string, data: any) => void): Promise<string[]>;
|
|
27
|
-
subscribe(characteristicUuid: string): Promise<boolean>;
|
|
27
|
+
subscribe(characteristicUuid: string, timeout?: number): Promise<boolean>;
|
|
28
28
|
onData(characteristicUuid: string, data: any): void;
|
|
29
29
|
on(characteristicUuid: string, callback: (characteristicUuid: string, data: any) => void): void;
|
|
30
30
|
off(characteristicUuid: string, callback: (characteristicUuid: string, data: any) => void): void;
|
|
@@ -22,7 +22,7 @@ class BlePeripheralConnector {
|
|
|
22
22
|
this.emitter = new events_1.default();
|
|
23
23
|
if (!this.peripheral || !this.ble)
|
|
24
24
|
throw new Error('Illegal Arguments');
|
|
25
|
-
this.state = { isConnected: false, isConnecting: false, isInitialized: false, isInitializing: false, isSubscribing: false };
|
|
25
|
+
this.state = { subscribed: [], isConnected: false, isConnecting: false, isInitialized: false, isInitializing: false, isSubscribing: false };
|
|
26
26
|
this.services = undefined;
|
|
27
27
|
this.characteristics = undefined;
|
|
28
28
|
this.logger = new gd_eventlog_1.EventLogger('BLE');
|
|
@@ -31,7 +31,9 @@ class BlePeripheralConnector {
|
|
|
31
31
|
if (this.logger) {
|
|
32
32
|
this.logger.logEvent(event);
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
if (process.env.BLE_DEBUG) {
|
|
35
|
+
console.log('~~~BLE:', event);
|
|
36
|
+
}
|
|
35
37
|
}
|
|
36
38
|
connect() {
|
|
37
39
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -40,9 +42,10 @@ class BlePeripheralConnector {
|
|
|
40
42
|
this.logEvent({ message: 'connect', peripheral: this.peripheral.address, state: this.state });
|
|
41
43
|
this.state.isConnecting = true;
|
|
42
44
|
try {
|
|
45
|
+
this.peripheral.on('connect', () => { console.log('~~~ peripheral connected', this.peripheral); });
|
|
46
|
+
this.peripheral.on('disconnect', () => { this.onDisconnect(); });
|
|
43
47
|
if (!this.state.isConnected || (this.peripheral && this.peripheral.state !== 'connected')) {
|
|
44
48
|
yield this.peripheral.connectAsync();
|
|
45
|
-
this.peripheral.once('disconnect', this.onDisconnect.bind(this));
|
|
46
49
|
}
|
|
47
50
|
this.state.isConnected = this.peripheral.state === 'connected';
|
|
48
51
|
}
|
|
@@ -58,9 +61,12 @@ class BlePeripheralConnector {
|
|
|
58
61
|
});
|
|
59
62
|
}
|
|
60
63
|
onDisconnect() {
|
|
64
|
+
this.peripheral.removeAllListeners('connect');
|
|
65
|
+
this.peripheral.removeAllListeners('disconnect');
|
|
61
66
|
this.logEvent({ message: 'onDisconnected', peripheral: this.peripheral.address, state: this.state });
|
|
62
67
|
this.state.isConnected = false;
|
|
63
|
-
this.
|
|
68
|
+
this.state.isConnecting = false;
|
|
69
|
+
this.emitter.emit('disconnect');
|
|
64
70
|
}
|
|
65
71
|
initialize(enforce = false) {
|
|
66
72
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -108,7 +114,7 @@ class BlePeripheralConnector {
|
|
|
108
114
|
this.logEvent({ message: 'subscribe', peripheral: this.peripheral.address, characteristic: c.uuid, uuid: (0, ble_1.uuid)(c.uuid) });
|
|
109
115
|
if (this.state.subscribed.find(uuid => uuid === c.uuid) === undefined) {
|
|
110
116
|
try {
|
|
111
|
-
yield this.subscribe(c.uuid);
|
|
117
|
+
yield this.subscribe(c.uuid, 3000);
|
|
112
118
|
subscribed.push(c.uuid);
|
|
113
119
|
}
|
|
114
120
|
catch (err) {
|
|
@@ -126,8 +132,8 @@ class BlePeripheralConnector {
|
|
|
126
132
|
return subscribed;
|
|
127
133
|
});
|
|
128
134
|
}
|
|
129
|
-
subscribe(characteristicUuid) {
|
|
130
|
-
this.logEvent({ message: 'subscribe', characteristic: characteristicUuid, characteristics: this.characteristics.map(c => ({ characteristic: c.uuid, uuid: (0, ble_1.uuid)(c.uuid) })) });
|
|
135
|
+
subscribe(characteristicUuid, timeout) {
|
|
136
|
+
this.logEvent({ message: 'subscribe attempt', characteristic: characteristicUuid, characteristics: this.characteristics.map(c => ({ characteristic: c.uuid, uuid: (0, ble_1.uuid)(c.uuid) })) });
|
|
131
137
|
return new Promise((resolve, reject) => {
|
|
132
138
|
try {
|
|
133
139
|
const characteristic = this.characteristics.find(c => (0, ble_1.uuid)(c.uuid) === (0, ble_1.uuid)(characteristicUuid) || (0, ble_1.uuid)(c.uuid) === (0, ble_1.uuid)(characteristicUuid));
|
|
@@ -135,17 +141,21 @@ class BlePeripheralConnector {
|
|
|
135
141
|
reject(new Error('Characteristic not found'));
|
|
136
142
|
return;
|
|
137
143
|
}
|
|
138
|
-
this.logEvent({ message: 'subscribe', peripheral: this.peripheral.address, characteristic: characteristic.uuid
|
|
144
|
+
this.logEvent({ message: 'subscribe', peripheral: this.peripheral.address, characteristic: characteristic.uuid });
|
|
139
145
|
characteristic.removeAllListeners('data');
|
|
140
146
|
characteristic.on('data', (data, _isNotification) => {
|
|
141
147
|
this.onData((0, ble_1.uuid)(characteristicUuid), data);
|
|
142
148
|
});
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
149
|
+
let to;
|
|
150
|
+
if (timeout) {
|
|
151
|
+
to = setTimeout(() => {
|
|
152
|
+
this.logEvent({ message: 'subscribe result', characteristic: characteristicUuid, error: 'timeout' });
|
|
153
|
+
reject(new Error('timeout'));
|
|
154
|
+
}, timeout);
|
|
155
|
+
}
|
|
147
156
|
characteristic.subscribe((err) => {
|
|
148
|
-
|
|
157
|
+
if (to)
|
|
158
|
+
clearTimeout(to);
|
|
149
159
|
this.logEvent({ message: 'subscribe result', characteristic: characteristicUuid, error: err });
|
|
150
160
|
if (err)
|
|
151
161
|
reject(err);
|
package/lib/ble/ble.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import EventEmitter from "events";
|
|
|
3
3
|
import BlePeripheralConnector from "./ble-peripheral";
|
|
4
4
|
export declare type ConnectProps = {
|
|
5
5
|
timeout?: number;
|
|
6
|
+
reconnect?: boolean;
|
|
6
7
|
};
|
|
7
8
|
export interface BleDeviceIdentifier {
|
|
8
9
|
id?: string;
|
|
@@ -42,6 +43,7 @@ export declare abstract class BleDeviceClass extends EventEmitter {
|
|
|
42
43
|
abstract connect(props?: ConnectProps): Promise<boolean>;
|
|
43
44
|
abstract disconnect(): Promise<boolean>;
|
|
44
45
|
abstract getDeviceInfo(): Promise<BleDeviceInfo>;
|
|
46
|
+
abstract getServices(): string[];
|
|
45
47
|
setCharacteristicUUIDs(uuids: string[]): void;
|
|
46
48
|
}
|
|
47
49
|
export interface BleWriteProps {
|
|
@@ -78,6 +80,7 @@ export declare abstract class BleInterfaceClass extends EventEmitter {
|
|
|
78
80
|
abstract scan(props: ScanProps): Promise<BleDeviceClass[]>;
|
|
79
81
|
abstract stopScan(): Promise<boolean>;
|
|
80
82
|
abstract disconnect(): Promise<boolean>;
|
|
83
|
+
abstract onDisconnect(peripheral: BlePeripheral): void;
|
|
81
84
|
abstract isScanning(): boolean;
|
|
82
85
|
abstract addConnectedDevice(device: BleDeviceClass): void;
|
|
83
86
|
abstract removeConnectedDevice(device: BleDeviceClass): void;
|
package/lib/ble/fm.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { DeviceProtocol } from '../DeviceProtocol';
|
|
|
8
8
|
import { EventLogger } from 'gd-eventlog';
|
|
9
9
|
import CyclingMode from '../CyclingMode';
|
|
10
10
|
import { IncyclistBikeData } from '../CyclingMode';
|
|
11
|
+
import BlePeripheralConnector from './ble-peripheral';
|
|
11
12
|
declare type PowerData = {
|
|
12
13
|
instantaneousPower?: number;
|
|
13
14
|
balance?: number;
|
|
@@ -25,7 +26,9 @@ export declare type IndoorBikeData = {
|
|
|
25
26
|
resistanceLevel?: number;
|
|
26
27
|
instantaneousPower?: number;
|
|
27
28
|
averagePower?: number;
|
|
28
|
-
|
|
29
|
+
totalEnergy?: number;
|
|
30
|
+
energyPerHour?: number;
|
|
31
|
+
energyPerMinute?: number;
|
|
29
32
|
heartrate?: number;
|
|
30
33
|
metabolicEquivalent?: number;
|
|
31
34
|
time?: number;
|
|
@@ -54,6 +57,7 @@ export default class BleFitnessMachineDevice extends BleDevice {
|
|
|
54
57
|
constructor(props?: any);
|
|
55
58
|
isMatching(characteristics: string[]): boolean;
|
|
56
59
|
subscribeWriteResponse(cuuid: string): Promise<void>;
|
|
60
|
+
subscribeAll(conn?: BlePeripheralConnector): Promise<void>;
|
|
57
61
|
init(): Promise<boolean>;
|
|
58
62
|
onDisconnect(): void;
|
|
59
63
|
getProfile(): string;
|
|
@@ -71,7 +75,7 @@ export default class BleFitnessMachineDevice extends BleDevice {
|
|
|
71
75
|
parseIndoorBikeData(_data: Uint8Array): IndoorBikeData;
|
|
72
76
|
parseFitnessMachineStatus(_data: Uint8Array): IndoorBikeData;
|
|
73
77
|
getFitnessMachineFeatures(): Promise<IndoorBikeFeatures>;
|
|
74
|
-
onData(characteristic: string, data: Buffer):
|
|
78
|
+
onData(characteristic: string, data: Buffer): boolean;
|
|
75
79
|
writeFtmsMessage(requestedOpCode: any, data: any, props?: BleWriteProps): Promise<number>;
|
|
76
80
|
requestControl(): Promise<boolean>;
|
|
77
81
|
setTargetPower(power: number): Promise<boolean>;
|
package/lib/ble/fm.js
CHANGED
|
@@ -93,6 +93,7 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
93
93
|
this.windSpeed = 0;
|
|
94
94
|
this.wheelSize = 2100;
|
|
95
95
|
this.data = {};
|
|
96
|
+
this.services = BleFitnessMachineDevice.services;
|
|
96
97
|
}
|
|
97
98
|
isMatching(characteristics) {
|
|
98
99
|
if (!characteristics)
|
|
@@ -125,13 +126,44 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
125
126
|
}
|
|
126
127
|
});
|
|
127
128
|
}
|
|
129
|
+
subscribeAll(conn) {
|
|
130
|
+
return new Promise(resolve => {
|
|
131
|
+
const characteristics = [consts_1.INDOOR_BIKE_DATA, consts_1.FTMS_STATUS, consts_1.FTMS_CP];
|
|
132
|
+
const timeout = Date.now() + 5500;
|
|
133
|
+
const iv = setInterval(() => {
|
|
134
|
+
const subscriptionStatus = characteristics.map(c => this.subscribedCharacteristics.find(s => s === c) !== undefined);
|
|
135
|
+
const done = subscriptionStatus.filter(s => s === true).length === characteristics.length;
|
|
136
|
+
if (done || Date.now() > timeout) {
|
|
137
|
+
clearInterval(iv);
|
|
138
|
+
resolve();
|
|
139
|
+
}
|
|
140
|
+
}, 100);
|
|
141
|
+
try {
|
|
142
|
+
const connector = conn || this.ble.getConnector(this.peripheral);
|
|
143
|
+
for (let i = 0; i < characteristics.length; i++) {
|
|
144
|
+
const c = characteristics[i];
|
|
145
|
+
const isAlreadySubscribed = connector.isSubscribed(c);
|
|
146
|
+
if (!isAlreadySubscribed) {
|
|
147
|
+
connector.removeAllListeners(c);
|
|
148
|
+
connector.on(c, (uuid, data) => {
|
|
149
|
+
this.onData(uuid, data);
|
|
150
|
+
});
|
|
151
|
+
connector.subscribe(c);
|
|
152
|
+
this.subscribedCharacteristics.push(c);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
this.logEvent({ message: 'Error', fn: 'subscribeAll()', error: err.message, stack: err.stack });
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
128
161
|
init() {
|
|
129
162
|
const _super = Object.create(null, {
|
|
130
163
|
initDevice: { get: () => super.initDevice }
|
|
131
164
|
});
|
|
132
165
|
return __awaiter(this, void 0, void 0, function* () {
|
|
133
166
|
try {
|
|
134
|
-
yield this.subscribeWriteResponse(consts_1.FTMS_CP);
|
|
135
167
|
yield _super.initDevice.call(this);
|
|
136
168
|
yield this.getFitnessMachineFeatures();
|
|
137
169
|
this.logEvent({ message: 'device info', deviceInfo: this.deviceInfo, features: this.features });
|
|
@@ -180,6 +212,7 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
180
212
|
}
|
|
181
213
|
}
|
|
182
214
|
catch (err) {
|
|
215
|
+
this.logEvent({ message: 'error', fn: 'parseHrm()', error: err.message | err, stack: err.stack });
|
|
183
216
|
}
|
|
184
217
|
return Object.assign(Object.assign({}, this.data), { raw: `2a37:${data.toString('hex')}` });
|
|
185
218
|
}
|
|
@@ -191,99 +224,113 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
191
224
|
getWindSpeed() { return this.windSpeed; }
|
|
192
225
|
parseIndoorBikeData(_data) {
|
|
193
226
|
const data = Buffer.from(_data);
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
227
|
+
try {
|
|
228
|
+
const flags = data.readUInt16LE(0);
|
|
229
|
+
let offset = 2;
|
|
230
|
+
if ((flags & IndoorBikeDataFlag.MoreData) === 0) {
|
|
231
|
+
this.data.speed = data.readUInt16LE(offset) / 100;
|
|
232
|
+
offset += 2;
|
|
233
|
+
}
|
|
234
|
+
if (flags & IndoorBikeDataFlag.AverageSpeedPresent) {
|
|
235
|
+
this.data.averageSpeed = data.readUInt16LE(offset) / 100;
|
|
236
|
+
offset += 2;
|
|
237
|
+
}
|
|
238
|
+
if (flags & IndoorBikeDataFlag.InstantaneousCadence) {
|
|
239
|
+
this.data.cadence = data.readUInt16LE(offset) / 2;
|
|
240
|
+
offset += 2;
|
|
241
|
+
}
|
|
242
|
+
if (flags & IndoorBikeDataFlag.AverageCadencePresent) {
|
|
243
|
+
this.data.averageCadence = data.readUInt16LE(offset) / 2;
|
|
244
|
+
offset += 2;
|
|
245
|
+
}
|
|
246
|
+
if (flags & IndoorBikeDataFlag.TotalDistancePresent) {
|
|
247
|
+
const dvLow = data.readUInt8(offset);
|
|
248
|
+
offset += 1;
|
|
249
|
+
const dvHigh = data.readUInt16LE(offset);
|
|
250
|
+
offset += 2;
|
|
251
|
+
this.data.totalDistance = (dvHigh << 8) + dvLow;
|
|
252
|
+
}
|
|
253
|
+
if (flags & IndoorBikeDataFlag.ResistanceLevelPresent) {
|
|
254
|
+
this.data.resistanceLevel = data.readInt8(offset);
|
|
255
|
+
offset += 1;
|
|
256
|
+
}
|
|
257
|
+
if (flags & IndoorBikeDataFlag.InstantaneousPowerPresent) {
|
|
258
|
+
this.data.instantaneousPower = data.readInt16LE(offset);
|
|
259
|
+
offset += 2;
|
|
260
|
+
}
|
|
261
|
+
if (flags & IndoorBikeDataFlag.AveragePowerPresent) {
|
|
262
|
+
this.data.averagePower = data.readInt16LE(offset);
|
|
263
|
+
offset += 2;
|
|
264
|
+
}
|
|
265
|
+
if (flags & IndoorBikeDataFlag.ExpendedEnergyPresent) {
|
|
266
|
+
this.data.totalEnergy = data.readUInt16LE(offset);
|
|
267
|
+
offset += 2;
|
|
268
|
+
this.data.energyPerHour = data.readUInt16LE(offset);
|
|
269
|
+
offset += 2;
|
|
270
|
+
this.data.energyPerMinute = data.readUInt8(offset);
|
|
271
|
+
offset += 1;
|
|
272
|
+
}
|
|
273
|
+
if (flags & IndoorBikeDataFlag.HeartRatePresent) {
|
|
274
|
+
this.data.heartrate = data.readUInt8(offset);
|
|
275
|
+
offset += 1;
|
|
276
|
+
}
|
|
277
|
+
if (flags & IndoorBikeDataFlag.MetabolicEquivalentPresent) {
|
|
278
|
+
this.data.metabolicEquivalent = data.readUInt8(offset) / 10;
|
|
279
|
+
offset += 2;
|
|
280
|
+
}
|
|
281
|
+
if (flags & IndoorBikeDataFlag.ElapsedTimePresent) {
|
|
282
|
+
this.data.time = data.readUInt16LE(offset);
|
|
283
|
+
offset += 2;
|
|
284
|
+
}
|
|
285
|
+
if (flags & IndoorBikeDataFlag.RemainingTimePresent) {
|
|
286
|
+
this.data.remainingTime = data.readUInt16LE(offset);
|
|
287
|
+
offset += 2;
|
|
288
|
+
}
|
|
246
289
|
}
|
|
247
|
-
|
|
248
|
-
this.
|
|
249
|
-
offset += 2;
|
|
290
|
+
catch (err) {
|
|
291
|
+
this.logEvent({ message: 'error', fn: 'parseIndoorBikeData()', error: err.message | err, stack: err.stack });
|
|
250
292
|
}
|
|
251
293
|
return Object.assign(Object.assign({}, this.data), { raw: `2ad2:${data.toString('hex')}` });
|
|
252
294
|
}
|
|
253
295
|
parseFitnessMachineStatus(_data) {
|
|
254
296
|
const data = Buffer.from(_data);
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
297
|
+
try {
|
|
298
|
+
const OpCode = data.readUInt8(0);
|
|
299
|
+
switch (OpCode) {
|
|
300
|
+
case 8:
|
|
301
|
+
this.data.targetPower = data.readInt16LE(1);
|
|
302
|
+
break;
|
|
303
|
+
case 6:
|
|
304
|
+
this.data.targetInclination = data.readInt16LE(1) / 10;
|
|
305
|
+
break;
|
|
306
|
+
case 4:
|
|
307
|
+
this.data.status = "STARTED";
|
|
308
|
+
break;
|
|
309
|
+
case 3:
|
|
310
|
+
case 2:
|
|
311
|
+
this.data.status = "STOPPED";
|
|
312
|
+
break;
|
|
313
|
+
case 20:
|
|
314
|
+
const spinDownStatus = data.readUInt8(1);
|
|
315
|
+
switch (spinDownStatus) {
|
|
316
|
+
case 1:
|
|
317
|
+
this.data.status = "SPIN DOWN REQUESTED";
|
|
318
|
+
break;
|
|
319
|
+
case 2:
|
|
320
|
+
this.data.status = "SPIN DOWN SUCCESS";
|
|
321
|
+
break;
|
|
322
|
+
case 3:
|
|
323
|
+
this.data.status = "SPIN DOWN ERROR";
|
|
324
|
+
break;
|
|
325
|
+
case 4:
|
|
326
|
+
this.data.status = "STOP PEDALING";
|
|
327
|
+
break;
|
|
328
|
+
default: break;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
catch (err) {
|
|
333
|
+
this.logEvent({ message: 'error', fn: 'parseFitnessMachineStatus()', error: err.message | err, stack: err.stack });
|
|
287
334
|
}
|
|
288
335
|
return Object.assign(Object.assign({}, this.data), { raw: `2ada:${data.toString('hex')}` });
|
|
289
336
|
}
|
|
@@ -298,6 +345,7 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
298
345
|
const fitnessMachine = buffer.readUInt32LE(0);
|
|
299
346
|
const targetSettings = buffer.readUInt32LE(4);
|
|
300
347
|
this.features = { fitnessMachine, targetSettings };
|
|
348
|
+
this.logEvent({ message: 'supported Features: ', fatures: this.features });
|
|
301
349
|
}
|
|
302
350
|
}
|
|
303
351
|
catch (err) {
|
|
@@ -306,7 +354,9 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
306
354
|
});
|
|
307
355
|
}
|
|
308
356
|
onData(characteristic, data) {
|
|
309
|
-
super.onData(characteristic, data);
|
|
357
|
+
const hasData = super.onData(characteristic, data);
|
|
358
|
+
if (!hasData)
|
|
359
|
+
return false;
|
|
310
360
|
const uuid = characteristic.toLocaleLowerCase();
|
|
311
361
|
let res = undefined;
|
|
312
362
|
switch (uuid) {
|
|
@@ -326,8 +376,11 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
326
376
|
default:
|
|
327
377
|
break;
|
|
328
378
|
}
|
|
329
|
-
if (res)
|
|
379
|
+
if (res) {
|
|
330
380
|
this.emit('data', res);
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
return true;
|
|
331
384
|
}
|
|
332
385
|
writeFtmsMessage(requestedOpCode, data, props) {
|
|
333
386
|
return __awaiter(this, void 0, void 0, function* () {
|
package/lib/ble/hrm.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export default class BleHrmDevice extends BleDevice {
|
|
|
20
20
|
getProfile(): string;
|
|
21
21
|
getServiceUUids(): string[];
|
|
22
22
|
parseHrm(_data: Uint8Array): HrmData;
|
|
23
|
-
onData(characteristic: string, data: Buffer):
|
|
23
|
+
onData(characteristic: string, data: Buffer): boolean;
|
|
24
24
|
}
|
|
25
25
|
export declare class HrmAdapter extends DeviceAdapter {
|
|
26
26
|
device: BleHrmDevice;
|
package/lib/ble/hrm.js
CHANGED
|
@@ -51,14 +51,15 @@ 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);
|
|
55
|
-
|
|
56
|
-
if (isDuplicate)
|
|
54
|
+
const hasData = super.onData(characteristic, data);
|
|
55
|
+
if (!hasData)
|
|
57
56
|
return;
|
|
58
57
|
if (characteristic.toLocaleLowerCase() === '2a37') {
|
|
59
58
|
const res = this.parseHrm(data);
|
|
60
59
|
this.emit('data', res);
|
|
60
|
+
return false;
|
|
61
61
|
}
|
|
62
|
+
return true;
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
exports.default = BleHrmDevice;
|
package/lib/ble/pwr.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export default class BleCyclingPowerDevice extends BleDevice {
|
|
|
42
42
|
time: any;
|
|
43
43
|
};
|
|
44
44
|
parsePower(_data: Uint8Array): PowerData;
|
|
45
|
-
onData(characteristic: string, data: Buffer):
|
|
45
|
+
onData(characteristic: string, data: Buffer): boolean;
|
|
46
46
|
reset(): void;
|
|
47
47
|
}
|
|
48
48
|
export declare class PwrAdapter extends DeviceAdapter {
|
|
@@ -71,6 +71,7 @@ export declare class PwrAdapter extends DeviceAdapter {
|
|
|
71
71
|
getDisplayName(): string;
|
|
72
72
|
getCyclingMode(): CyclingMode;
|
|
73
73
|
getDefaultCyclingMode(): CyclingMode;
|
|
74
|
+
getSupportedCyclingModes(): any[];
|
|
74
75
|
getPort(): string;
|
|
75
76
|
getWeight(): number;
|
|
76
77
|
setIgnoreBike(ignore: any): void;
|
package/lib/ble/pwr.js
CHANGED
|
@@ -34,6 +34,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
34
34
|
exports.PwrAdapter = void 0;
|
|
35
35
|
const ble_device_1 = require("./ble-device");
|
|
36
36
|
const ble_interface_1 = __importDefault(require("./ble-interface"));
|
|
37
|
+
const ble_1 = require("./ble");
|
|
37
38
|
const Device_1 = __importStar(require("../Device"));
|
|
38
39
|
const gd_eventlog_1 = require("gd-eventlog");
|
|
39
40
|
const consts_1 = require("./consts");
|
|
@@ -138,14 +139,15 @@ class BleCyclingPowerDevice extends ble_device_1.BleDevice {
|
|
|
138
139
|
return { instantaneousPower, balance, accTorque, rpm, time, raw: `2a63:${data.toString('hex')}` };
|
|
139
140
|
}
|
|
140
141
|
onData(characteristic, data) {
|
|
141
|
-
super.onData(characteristic, data);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (characteristic.toLocaleLowerCase() === consts_1.CSP_MEASUREMENT) {
|
|
142
|
+
const hasData = super.onData(characteristic, data);
|
|
143
|
+
if (!hasData)
|
|
144
|
+
return false;
|
|
145
|
+
if ((0, ble_1.matches)(characteristic, consts_1.CSP_MEASUREMENT)) {
|
|
146
146
|
const res = this.parsePower(data);
|
|
147
147
|
this.emit('data', res);
|
|
148
|
+
return false;
|
|
148
149
|
}
|
|
150
|
+
return true;
|
|
149
151
|
}
|
|
150
152
|
reset() {
|
|
151
153
|
this.instantaneousPower = undefined;
|
|
@@ -201,6 +203,9 @@ class PwrAdapter extends Device_1.default {
|
|
|
201
203
|
getDefaultCyclingMode() {
|
|
202
204
|
return new power_meter_1.default(this);
|
|
203
205
|
}
|
|
206
|
+
getSupportedCyclingModes() {
|
|
207
|
+
return [power_meter_1.default];
|
|
208
|
+
}
|
|
204
209
|
getPort() {
|
|
205
210
|
return 'ble';
|
|
206
211
|
}
|
package/lib/ble/tacx.d.ts
CHANGED
|
@@ -63,7 +63,7 @@ export default class TacxAdvancedFitnessMachineDevice extends BleFitnessMachineD
|
|
|
63
63
|
parseTrainerData(data: Buffer): BleFeBikeData;
|
|
64
64
|
parseProductInformation(data: Buffer): BleFeBikeData;
|
|
65
65
|
parseFECMessage(_data: Buffer): BleFeBikeData;
|
|
66
|
-
onData(characteristic: string, data: Buffer):
|
|
66
|
+
onData(characteristic: string, data: Buffer): boolean;
|
|
67
67
|
getChecksum(message: any[]): number;
|
|
68
68
|
buildMessage(payload?: number[], msgID?: number): Buffer;
|
|
69
69
|
sendMessage(message: Buffer): Promise<boolean>;
|
package/lib/ble/tacx.js
CHANGED
|
@@ -164,10 +164,10 @@ class TacxAdvancedFitnessMachineDevice extends fm_1.default {
|
|
|
164
164
|
return { rpm, time: this.timeOffset + c.time };
|
|
165
165
|
}
|
|
166
166
|
parseCSC(_data, logOnly = false) {
|
|
167
|
-
|
|
167
|
+
const data = Buffer.from(_data);
|
|
168
|
+
this.logEvent({ message: 'BLE CSC message', data: data.toString('hex') });
|
|
168
169
|
if (logOnly)
|
|
169
170
|
return this.data;
|
|
170
|
-
const data = Buffer.from(_data);
|
|
171
171
|
let offset = 0;
|
|
172
172
|
const flags = data.readUInt8(offset);
|
|
173
173
|
offset++;
|
|
@@ -187,10 +187,10 @@ class TacxAdvancedFitnessMachineDevice extends fm_1.default {
|
|
|
187
187
|
return this.data;
|
|
188
188
|
}
|
|
189
189
|
parsePower(_data, logOnly = false) {
|
|
190
|
-
|
|
190
|
+
const data = Buffer.from(_data);
|
|
191
|
+
this.logEvent({ message: 'BLE CSP message', data: data.toString('hex') });
|
|
191
192
|
if (logOnly)
|
|
192
193
|
return this.data;
|
|
193
|
-
const data = Buffer.from(_data);
|
|
194
194
|
try {
|
|
195
195
|
let offset = 4;
|
|
196
196
|
const flags = data.readUInt16LE(0);
|
package/lib/ble/wahoo-kickr.d.ts
CHANGED
|
@@ -70,7 +70,7 @@ export default class WahooAdvancedFitnessMachineDevice extends BleFitnessMachine
|
|
|
70
70
|
time: any;
|
|
71
71
|
};
|
|
72
72
|
parsePower(_data: Buffer): IndoorBikeData;
|
|
73
|
-
onData(characteristic: string, data: Buffer):
|
|
73
|
+
onData(characteristic: string, data: Buffer): boolean;
|
|
74
74
|
writeWahooFtmsMessage(requestedOpCode: number, data: Buffer, props?: BleWriteProps): Promise<boolean>;
|
|
75
75
|
requestControl(): Promise<boolean>;
|
|
76
76
|
setPowerAdjusting(): void;
|
package/lib/ble/wahoo-kickr.js
CHANGED
|
@@ -170,7 +170,9 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
|
|
|
170
170
|
return { instantaneousPower, cadence, time, raw: data.toString('hex') };
|
|
171
171
|
}
|
|
172
172
|
onData(characteristic, data) {
|
|
173
|
-
super.onData(characteristic, data);
|
|
173
|
+
const hasData = super.onData(characteristic, data);
|
|
174
|
+
if (!hasData)
|
|
175
|
+
return false;
|
|
174
176
|
const uuid = characteristic.toLowerCase();
|
|
175
177
|
let res = undefined;
|
|
176
178
|
switch (uuid) {
|
|
@@ -190,8 +192,11 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
|
|
|
190
192
|
this.logEvent({ message: 'data', uuid, data: data.toString('hex') });
|
|
191
193
|
break;
|
|
192
194
|
}
|
|
193
|
-
if (res)
|
|
195
|
+
if (res) {
|
|
194
196
|
this.emit('data', res);
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
return true;
|
|
195
200
|
}
|
|
196
201
|
writeWahooFtmsMessage(requestedOpCode, data, props) {
|
|
197
202
|
return __awaiter(this, void 0, void 0, function* () {
|