incyclist-devices 2.3.9 → 2.3.11
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/interface.d.ts +6 -3
- package/lib/ble/base/interface.js +83 -48
- package/lib/ble/fm/adapter.d.ts +2 -1
- package/lib/ble/fm/adapter.js +27 -9
- package/lib/ble/fm/sensor.js +9 -2
- package/lib/ble/wahoo/sensor.d.ts +1 -0
- package/lib/ble/wahoo/sensor.js +18 -0
- package/package.json +1 -1
- package/lib/ble/adapter-factory.d.ts +0 -34
- package/lib/ble/adapter-factory.js +0 -110
- package/lib/ble/base/comms-utils.d.ts +0 -7
- package/lib/ble/base/comms-utils.js +0 -90
- package/lib/ble/base/comms.d.ts +0 -75
- package/lib/ble/base/comms.js +0 -599
- package/lib/ble/ble-interface.d.ts +0 -84
- package/lib/ble/ble-interface.js +0 -622
- package/lib/ble/ble-peripheral.d.ts +0 -39
- package/lib/ble/ble-peripheral.js +0 -252
- package/lib/ble/cp/comm.d.ts +0 -30
- package/lib/ble/cp/comm.js +0 -126
- package/lib/ble/elite/adapter.d.ts +0 -21
- package/lib/ble/elite/adapter.js +0 -118
- package/lib/ble/elite/comms.d.ts +0 -31
- package/lib/ble/elite/comms.js +0 -127
- package/lib/ble/elite/index.d.ts +0 -3
- package/lib/ble/elite/index.js +0 -10
- package/lib/ble/fm/comms.d.ts +0 -49
- package/lib/ble/fm/comms.js +0 -506
- package/lib/ble/hr/comm.d.ts +0 -19
- package/lib/ble/hr/comm.js +0 -65
- package/lib/ble/peripheral-cache.d.ts +0 -45
- package/lib/ble/peripheral-cache.js +0 -109
- package/lib/ble/tacx/comms.d.ts +0 -59
- package/lib/ble/tacx/comms.js +0 -634
- package/lib/ble/wahoo/comms.d.ts +0 -64
- package/lib/ble/wahoo/comms.js +0 -399
- package/lib/direct-connect/base/comms.d.ts +0 -3
- package/lib/direct-connect/base/comms.js +0 -7
- package/lib/direct-connect/base/sensor.d.ts +0 -3
- package/lib/direct-connect/base/sensor.js +0 -7
- package/lib/direct-connect/utils.d.ts +0 -5
- package/lib/direct-connect/utils.js +0 -73
- package/lib/factories/index.d.ts +0 -3
- package/lib/factories/index.js +0 -10
- package/lib/utils/operation.d.ts +0 -17
- package/lib/utils/operation.js +0 -20
|
@@ -27,6 +27,7 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
|
|
|
27
27
|
protected expectedServices: string[];
|
|
28
28
|
protected matching: string[];
|
|
29
29
|
protected connectTask: InteruptableTask<TaskState, boolean>;
|
|
30
|
+
protected disconnectTask: InteruptableTask<TaskState, boolean>;
|
|
30
31
|
protected scanTask: InteruptableTask<TaskState, void>;
|
|
31
32
|
protected discoverTask: InteruptableTask<TaskState, void>;
|
|
32
33
|
protected onDiscovered: (peripheral: BleRawPeripheral) => void;
|
|
@@ -35,8 +36,9 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
|
|
|
35
36
|
id: string;
|
|
36
37
|
peripheral: IBlePeripheral;
|
|
37
38
|
}[];
|
|
38
|
-
protected connectAttemptCnt: number;
|
|
39
39
|
protected emitted: BlePeripheralAnnouncement[];
|
|
40
|
+
protected confirmedBleState: BleInterfaceState;
|
|
41
|
+
protected currentBleState: BleInterfaceState;
|
|
40
42
|
static getInstance(props?: InterfaceProps): BleInterface;
|
|
41
43
|
protected constructor(props: InterfaceProps);
|
|
42
44
|
setProps(props: InterfaceProps): void;
|
|
@@ -52,6 +54,7 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
|
|
|
52
54
|
registerConnected(peripheral: IBlePeripheral, id: string): void;
|
|
53
55
|
unregisterConnected(id: string): void;
|
|
54
56
|
protected isConnecting(): boolean;
|
|
57
|
+
protected isDisconnecting(): boolean;
|
|
55
58
|
scan(props: BleScanProps): Promise<DeviceSettings[]>;
|
|
56
59
|
stopScan(): Promise<boolean>;
|
|
57
60
|
onScanDone(): DeviceSettings[];
|
|
@@ -94,9 +97,9 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
|
|
|
94
97
|
protected connectBle(): Promise<boolean>;
|
|
95
98
|
protected waitForBleConnected(): Promise<boolean>;
|
|
96
99
|
protected onError(err: Error): void;
|
|
97
|
-
protected onConnected(): void
|
|
100
|
+
protected onConnected(): Promise<void>;
|
|
98
101
|
protected onDisconnected(): Promise<void>;
|
|
99
|
-
protected onBleStateChange(state: BleInterfaceState): void
|
|
102
|
+
protected onBleStateChange(state: BleInterfaceState): Promise<void>;
|
|
100
103
|
protected getAdapterFactory(): BleAdapterFactory<TBleSensor>;
|
|
101
104
|
protected getConnectTimeout(): number;
|
|
102
105
|
protected getExpectedServices(): string[];
|
|
@@ -50,7 +50,6 @@ class BleInterface extends events_1.default {
|
|
|
50
50
|
this.expectedServices = ['180d', '1818', '1826', '6e40fec1'];
|
|
51
51
|
this.matching = [];
|
|
52
52
|
this.connectedPeripherals = [];
|
|
53
|
-
this.connectAttemptCnt = 0;
|
|
54
53
|
this.emitted = [];
|
|
55
54
|
this.instanceId = ++instanceCount;
|
|
56
55
|
this.props = props;
|
|
@@ -111,41 +110,59 @@ class BleInterface extends events_1.default {
|
|
|
111
110
|
log: this.logEvent.bind(this),
|
|
112
111
|
});
|
|
113
112
|
const success = yield this.connectTask.run().catch(() => false);
|
|
114
|
-
if (success) {
|
|
115
|
-
this.startPeripheralScan();
|
|
116
|
-
}
|
|
117
113
|
return success;
|
|
118
114
|
});
|
|
119
115
|
}
|
|
120
116
|
disconnect(connectionLost) {
|
|
121
117
|
return __awaiter(this, void 0, void 0, function* () {
|
|
122
|
-
|
|
123
|
-
if (!this.getBinding()) {
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
if (!this.isConnected() && !connectionLost)
|
|
118
|
+
if (!this.isConnected())
|
|
127
119
|
return true;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
120
|
+
const performDisconnect = () => __awaiter(this, void 0, void 0, function* () {
|
|
121
|
+
var _a;
|
|
122
|
+
if (!this.getBinding()) {
|
|
123
|
+
this.confirmedBleState = 'poweredOff';
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
this.getBinding().removeAllListeners('error');
|
|
127
|
+
if (!this.isConnected() && !connectionLost) {
|
|
128
|
+
this.confirmedBleState = 'poweredOff';
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
if (!connectionLost)
|
|
132
|
+
this.logEvent({ message: 'disconnect request' });
|
|
133
|
+
this.emit('disconnect-request');
|
|
134
|
+
yield this.stopPeripheralScan();
|
|
135
|
+
if (connectionLost) {
|
|
136
|
+
this.emitDisconnectAllPeripherals();
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
yield this.disconnectAllPeripherals();
|
|
140
|
+
}
|
|
141
|
+
if (this.isConnecting())
|
|
142
|
+
yield ((_a = this.connectTask) === null || _a === void 0 ? void 0 : _a.stop());
|
|
143
|
+
this.emit('disconnect-done');
|
|
144
|
+
this.getBinding().removeAllListeners('stateChange');
|
|
145
|
+
this.getBinding().on('stateChange', this.onBleStateChange.bind(this));
|
|
146
|
+
this.getBinding().on('error', this.onError.bind(this));
|
|
147
|
+
this.logEvent({ message: 'interface disconnected', interface: 'BLE' });
|
|
148
|
+
this.confirmedBleState = 'poweredOff';
|
|
149
|
+
return true;
|
|
150
|
+
});
|
|
151
|
+
if (this.isDisconnecting()) {
|
|
152
|
+
return this.disconnectTask.getPromise();
|
|
137
153
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
154
|
+
this.disconnectTask = new task_1.InteruptableTask(performDisconnect(), {
|
|
155
|
+
timeout: this.getConnectTimeout(),
|
|
156
|
+
name: 'BLE connect',
|
|
157
|
+
errorOnTimeout: false,
|
|
158
|
+
log: this.logEvent.bind(this),
|
|
159
|
+
});
|
|
160
|
+
const success = yield this.disconnectTask.run().catch(() => false);
|
|
161
|
+
return success;
|
|
144
162
|
});
|
|
145
163
|
}
|
|
146
164
|
isConnected() {
|
|
147
|
-
|
|
148
|
-
return this.connectAttemptCnt > 0 && ((_a = this.getBinding()) === null || _a === void 0 ? void 0 : _a.state) === 'poweredOn';
|
|
165
|
+
return this.confirmedBleState === 'poweredOn';
|
|
149
166
|
}
|
|
150
167
|
registerConnected(peripheral, id) {
|
|
151
168
|
const p = this.connectedPeripherals.find(p => p.id === id);
|
|
@@ -165,6 +182,10 @@ class BleInterface extends events_1.default {
|
|
|
165
182
|
var _a;
|
|
166
183
|
return ((_a = this.connectTask) === null || _a === void 0 ? void 0 : _a.isRunning()) === true;
|
|
167
184
|
}
|
|
185
|
+
isDisconnecting() {
|
|
186
|
+
var _a;
|
|
187
|
+
return ((_a = this.disconnectTask) === null || _a === void 0 ? void 0 : _a.isRunning()) === true;
|
|
188
|
+
}
|
|
168
189
|
scan(props) {
|
|
169
190
|
return __awaiter(this, void 0, void 0, function* () {
|
|
170
191
|
this.resumeLogging();
|
|
@@ -272,12 +293,12 @@ class BleInterface extends events_1.default {
|
|
|
272
293
|
}
|
|
273
294
|
startPeripheralScan() {
|
|
274
295
|
return __awaiter(this, arguments, void 0, function* (retry = false) {
|
|
275
|
-
this.expectedServices = this.getExpectedServices();
|
|
276
|
-
if (!retry)
|
|
277
|
-
this.logEvent({ message: 'starting peripheral discovery ...' });
|
|
278
296
|
if (!this.isConnected() || this.isDiscovering()) {
|
|
279
297
|
return;
|
|
280
298
|
}
|
|
299
|
+
this.expectedServices = this.getExpectedServices();
|
|
300
|
+
if (!retry)
|
|
301
|
+
this.logEvent({ message: 'starting peripheral discovery ...' });
|
|
281
302
|
this.discoverTask = new task_1.InteruptableTask(this.discoverPeripherals(), {
|
|
282
303
|
errorOnTimeout: false,
|
|
283
304
|
name: 'discover',
|
|
@@ -556,10 +577,9 @@ class BleInterface extends events_1.default {
|
|
|
556
577
|
}
|
|
557
578
|
connectBle() {
|
|
558
579
|
return __awaiter(this, void 0, void 0, function* () {
|
|
559
|
-
this.
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
this.logEvent({ message: 'BLE connected' });
|
|
580
|
+
this.currentBleState = this.getBinding().state;
|
|
581
|
+
if (this.currentBleState === 'poweredOn') {
|
|
582
|
+
this.onConnected();
|
|
563
583
|
return true;
|
|
564
584
|
}
|
|
565
585
|
const res = yield this.waitForBleConnected();
|
|
@@ -573,13 +593,13 @@ class BleInterface extends events_1.default {
|
|
|
573
593
|
return done(false);
|
|
574
594
|
});
|
|
575
595
|
this.getBinding().on('stateChange', (state) => {
|
|
596
|
+
if (state === this.confirmedBleState)
|
|
597
|
+
return;
|
|
598
|
+
this.logEvent({ message: 'BLE state change', state });
|
|
576
599
|
if (state === 'poweredOn') {
|
|
577
600
|
this.onConnected();
|
|
578
601
|
return done(true);
|
|
579
602
|
}
|
|
580
|
-
else {
|
|
581
|
-
this.logEvent({ message: 'BLE state change', state });
|
|
582
|
-
}
|
|
583
603
|
});
|
|
584
604
|
});
|
|
585
605
|
}
|
|
@@ -587,26 +607,41 @@ class BleInterface extends events_1.default {
|
|
|
587
607
|
this.logError(err, 'BLE connect');
|
|
588
608
|
}
|
|
589
609
|
onConnected() {
|
|
590
|
-
this
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
610
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
611
|
+
if (this.isConnected())
|
|
612
|
+
return;
|
|
613
|
+
this.confirmedBleState = 'poweredOn';
|
|
614
|
+
this.getBinding().removeAllListeners('error');
|
|
615
|
+
this.getBinding().removeAllListeners('stateChange');
|
|
616
|
+
this.getBinding().on('stateChange', this.onBleStateChange.bind(this));
|
|
617
|
+
this.getBinding().on('error', this.onError.bind(this));
|
|
618
|
+
this.logEvent({ message: 'BLE connected' });
|
|
619
|
+
this.startPeripheralScan();
|
|
620
|
+
});
|
|
595
621
|
}
|
|
596
622
|
onDisconnected() {
|
|
597
623
|
return __awaiter(this, void 0, void 0, function* () {
|
|
624
|
+
if (this.isDisconnecting() || !this.isConnected())
|
|
625
|
+
return;
|
|
598
626
|
this.logEvent({ message: 'BLE Disconnected' });
|
|
599
627
|
yield this.disconnect(true);
|
|
600
|
-
this.getBinding().on('stateChange', this.onBleStateChange.bind(this));
|
|
601
|
-
this.getBinding().on('error', this.onError.bind(this));
|
|
602
628
|
});
|
|
603
629
|
}
|
|
604
630
|
onBleStateChange(state) {
|
|
605
|
-
|
|
606
|
-
this.
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
631
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
632
|
+
if (state === this.currentBleState)
|
|
633
|
+
return;
|
|
634
|
+
this.currentBleState = state;
|
|
635
|
+
if (state === 'poweredOff') {
|
|
636
|
+
this.onDisconnected();
|
|
637
|
+
}
|
|
638
|
+
else {
|
|
639
|
+
if (this.isDisconnecting()) {
|
|
640
|
+
yield this.disconnectTask.getPromise();
|
|
641
|
+
}
|
|
642
|
+
this.onConnected();
|
|
643
|
+
}
|
|
644
|
+
});
|
|
610
645
|
}
|
|
611
646
|
getAdapterFactory() {
|
|
612
647
|
return factories_1.BleAdapterFactory.getInstance('ble');
|
package/lib/ble/fm/adapter.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import BleFitnessMachineDevice from './sensor';
|
|
2
2
|
import BleAdapter from '../base/adapter';
|
|
3
3
|
import ICyclingMode, { CyclingMode } from '../../modes/types';
|
|
4
|
-
import { IndoorBikeData } from './types';
|
|
4
|
+
import { IndoorBikeData, IndoorBikeFeatures } from './types';
|
|
5
5
|
import { BleDeviceProperties, BleDeviceSettings, BleStartProperties, IBlePeripheral } from '../types';
|
|
6
6
|
import { IAdapter, IncyclistAdapterData, IncyclistBikeData } from '../../types';
|
|
7
7
|
import { LegacyProfile } from '../../antv2/types';
|
|
@@ -24,6 +24,7 @@ export default class BleFmAdapter extends BleAdapter<IndoorBikeData, BleFitnessM
|
|
|
24
24
|
protected establishControl(): Promise<boolean>;
|
|
25
25
|
protected sendInitialRequest(): Promise<void>;
|
|
26
26
|
protected checkCapabilities(): Promise<void>;
|
|
27
|
+
protected updateCapabilitiesFromFeatures(features: IndoorBikeFeatures): void;
|
|
27
28
|
sendUpdate(request: any, enforced?: boolean): Promise<void>;
|
|
28
29
|
sendInitCommands(): Promise<boolean>;
|
|
29
30
|
}
|
package/lib/ble/fm/adapter.js
CHANGED
|
@@ -121,6 +121,8 @@ class BleFmAdapter extends adapter_1.default {
|
|
|
121
121
|
if (!this.isStarting())
|
|
122
122
|
return;
|
|
123
123
|
this.setConstants();
|
|
124
|
+
if (!this.hasCapability(types_1.IncyclistCapability.Control))
|
|
125
|
+
return;
|
|
124
126
|
yield this.establishControl();
|
|
125
127
|
yield this.sendInitialRequest();
|
|
126
128
|
});
|
|
@@ -182,7 +184,6 @@ class BleFmAdapter extends adapter_1.default {
|
|
|
182
184
|
}
|
|
183
185
|
checkCapabilities() {
|
|
184
186
|
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
-
var _a, _b, _c;
|
|
186
187
|
const before = this.capabilities.join(',');
|
|
187
188
|
const sensor = this.getSensor();
|
|
188
189
|
if (!sensor.features) {
|
|
@@ -193,14 +194,8 @@ class BleFmAdapter extends adapter_1.default {
|
|
|
193
194
|
this.logEvent({ message: 'error getting fitness machine features', device: this.getName(), interface: this.getInterface(), error: err });
|
|
194
195
|
}
|
|
195
196
|
}
|
|
196
|
-
if (
|
|
197
|
-
this.
|
|
198
|
-
}
|
|
199
|
-
if (((_b = sensor.features) === null || _b === void 0 ? void 0 : _b.cadence) && !this.hasCapability(types_1.IncyclistCapability.Cadence)) {
|
|
200
|
-
this.capabilities.push(types_1.IncyclistCapability.Cadence);
|
|
201
|
-
}
|
|
202
|
-
if (((_c = sensor.features) === null || _c === void 0 ? void 0 : _c.power) && !this.hasCapability(types_1.IncyclistCapability.Power)) {
|
|
203
|
-
this.capabilities.push(types_1.IncyclistCapability.Power);
|
|
197
|
+
if (sensor.features) {
|
|
198
|
+
this.updateCapabilitiesFromFeatures(sensor.features);
|
|
204
199
|
}
|
|
205
200
|
const after = this.capabilities.join(',');
|
|
206
201
|
if (before !== after) {
|
|
@@ -209,10 +204,33 @@ class BleFmAdapter extends adapter_1.default {
|
|
|
209
204
|
}
|
|
210
205
|
});
|
|
211
206
|
}
|
|
207
|
+
updateCapabilitiesFromFeatures(features) {
|
|
208
|
+
if (features.heartrate && !this.hasCapability(types_1.IncyclistCapability.HeartRate)) {
|
|
209
|
+
this.capabilities.push(types_1.IncyclistCapability.HeartRate);
|
|
210
|
+
}
|
|
211
|
+
if (features.cadence && !this.hasCapability(types_1.IncyclistCapability.Cadence)) {
|
|
212
|
+
this.capabilities.push(types_1.IncyclistCapability.Cadence);
|
|
213
|
+
}
|
|
214
|
+
if (features.cadence === false && this.hasCapability(types_1.IncyclistCapability.Cadence)) {
|
|
215
|
+
this.capabilities = this.capabilities.filter(cap => cap !== types_1.IncyclistCapability.Cadence);
|
|
216
|
+
}
|
|
217
|
+
if (features.power && !this.hasCapability(types_1.IncyclistCapability.Power)) {
|
|
218
|
+
this.capabilities.push(types_1.IncyclistCapability.Power);
|
|
219
|
+
}
|
|
220
|
+
if (features.power === false && this.hasCapability(types_1.IncyclistCapability.Power)) {
|
|
221
|
+
this.capabilities = this.capabilities.filter(cap => cap !== types_1.IncyclistCapability.Power);
|
|
222
|
+
}
|
|
223
|
+
if (features.setPower === false && features.setSlope === false) {
|
|
224
|
+
this.logEvent({ message: 'downgrade to Power Meter', name: this.getSettings().name, interface: this.getSettings().interface });
|
|
225
|
+
this.capabilities = this.capabilities.filter(cap => cap !== types_1.IncyclistCapability.Control);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
212
228
|
sendUpdate(request_1) {
|
|
213
229
|
return __awaiter(this, arguments, void 0, function* (request, enforced = false) {
|
|
214
230
|
if (!enforced && (this.paused || !this.device))
|
|
215
231
|
return;
|
|
232
|
+
if (!this.hasCapability(types_1.IncyclistCapability.Control))
|
|
233
|
+
return;
|
|
216
234
|
if (!enforced && (this.stopped && !this.isStarting()))
|
|
217
235
|
return;
|
|
218
236
|
try {
|
package/lib/ble/fm/sensor.js
CHANGED
|
@@ -79,8 +79,11 @@ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
|
|
|
79
79
|
getWindSpeed() { return this.windSpeed; }
|
|
80
80
|
requestControl() {
|
|
81
81
|
return __awaiter(this, void 0, void 0, function* () {
|
|
82
|
+
var _a, _b;
|
|
82
83
|
if (this.hasControl)
|
|
83
84
|
return true;
|
|
85
|
+
if (((_a = this.features) === null || _a === void 0 ? void 0 : _a.setPower) === false && ((_b = this.features) === null || _b === void 0 ? void 0 : _b.setSlope) === false)
|
|
86
|
+
return true;
|
|
84
87
|
this.logEvent({ message: 'requestControl' });
|
|
85
88
|
this.isCheckingControl = true;
|
|
86
89
|
const data = Buffer.alloc(1);
|
|
@@ -300,10 +303,11 @@ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
|
|
|
300
303
|
}
|
|
301
304
|
setTargetInclination(inclination) {
|
|
302
305
|
return __awaiter(this, void 0, void 0, function* () {
|
|
306
|
+
var _a;
|
|
303
307
|
if (this.data.targetInclination !== undefined && this.data.targetInclination === inclination)
|
|
304
308
|
return true;
|
|
305
|
-
if (
|
|
306
|
-
return;
|
|
309
|
+
if (((_a = this.features) === null || _a === void 0 ? void 0 : _a.setSlope) === false)
|
|
310
|
+
return true;
|
|
307
311
|
const hasControl = yield this.requestControl();
|
|
308
312
|
if (!hasControl) {
|
|
309
313
|
this.logEvent({ message: 'setTargetInclination failed', reason: 'control is disabled' });
|
|
@@ -318,6 +322,9 @@ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
|
|
|
318
322
|
}
|
|
319
323
|
setIndoorBikeSimulation(windSpeed, gradient, crr, cw) {
|
|
320
324
|
return __awaiter(this, void 0, void 0, function* () {
|
|
325
|
+
var _a;
|
|
326
|
+
if (((_a = this.features) === null || _a === void 0 ? void 0 : _a.setPower) === false)
|
|
327
|
+
return true;
|
|
321
328
|
const hasControl = yield this.requestControl();
|
|
322
329
|
if (!hasControl) {
|
|
323
330
|
this.logEvent({ message: 'setIndoorBikeSimulation failed', reason: 'control is disabled' });
|
|
@@ -36,6 +36,7 @@ export default class BleWahooDevice extends BleFitnessMachineDevice {
|
|
|
36
36
|
time: any;
|
|
37
37
|
};
|
|
38
38
|
protected parsePower(_data: Buffer): IndoorBikeData;
|
|
39
|
+
protected supportsHeartRate(): boolean;
|
|
39
40
|
protected writeWahooFtmsMessage(requestedOpCode: number, data: Buffer, props?: BleWriteProps): Promise<boolean>;
|
|
40
41
|
protected setPowerAdjusting(): void;
|
|
41
42
|
protected isPowerAdjusting(): boolean;
|
package/lib/ble/wahoo/sensor.js
CHANGED
|
@@ -29,6 +29,12 @@ class BleWahooDevice extends sensor_1.default {
|
|
|
29
29
|
this.weight = consts_1.DEFAULT_BIKE_WEIGHT + consts_1.DEFAULT_USER_WEIGHT;
|
|
30
30
|
this.data = {};
|
|
31
31
|
this.wahooCP = consts_3.WAHOO_ADVANCED_TRAINER_CP;
|
|
32
|
+
this._features = {
|
|
33
|
+
fitnessMachine: 0, targetSettings: 0,
|
|
34
|
+
power: true, cadence: true, heartrate: this.supportsHeartRate(),
|
|
35
|
+
setPower: true,
|
|
36
|
+
setSlope: true
|
|
37
|
+
};
|
|
32
38
|
}
|
|
33
39
|
isMatching(serviceUUIDs) {
|
|
34
40
|
const uuids = serviceUUIDs.map(uuid => (0, utils_1.beautifyUUID)(uuid));
|
|
@@ -192,6 +198,18 @@ class BleWahooDevice extends sensor_1.default {
|
|
|
192
198
|
const { instantaneousPower, cadence, time } = this.data;
|
|
193
199
|
return { instantaneousPower, cadence, time, raw: data.toString('hex') };
|
|
194
200
|
}
|
|
201
|
+
supportsHeartRate() {
|
|
202
|
+
var _a;
|
|
203
|
+
try {
|
|
204
|
+
if (!this.peripheral)
|
|
205
|
+
return false;
|
|
206
|
+
return ((_a = this.peripheral.services) === null || _a === void 0 ? void 0 : _a.find(s => (0, utils_1.beautifyUUID)(s.uuid) === (0, utils_1.beautifyUUID)('180d'))) !== undefined;
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
this.logEvent({ message: 'error', fn: 'supportsHeartRate', error: err.message, stack: err.stack });
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
195
213
|
writeWahooFtmsMessage(requestedOpCode, data, props) {
|
|
196
214
|
return __awaiter(this, void 0, void 0, function* () {
|
|
197
215
|
try {
|
package/package.json
CHANGED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import BleAdapter from "./base/adapter";
|
|
2
|
-
import { BleDeviceSettings, BleProtocol } from "./types";
|
|
3
|
-
import { DeviceProperties } from "../types";
|
|
4
|
-
import { BleComms } from "./base/comms";
|
|
5
|
-
import { BleDeviceData } from "./base/types";
|
|
6
|
-
export interface BleAdapterInfo {
|
|
7
|
-
protocol: BleProtocol;
|
|
8
|
-
Adapter: typeof BleAdapter<BleDeviceData, BleComms>;
|
|
9
|
-
Comm: typeof BleComms;
|
|
10
|
-
}
|
|
11
|
-
export default class BleAdapterFactory {
|
|
12
|
-
static _instance: BleAdapterFactory;
|
|
13
|
-
implementations: BleAdapterInfo[];
|
|
14
|
-
instances: Array<BleAdapter<BleDeviceData, BleComms>>;
|
|
15
|
-
static getInstance(): BleAdapterFactory;
|
|
16
|
-
constructor();
|
|
17
|
-
getAdapterInfo(protocol: BleProtocol): BleAdapterInfo;
|
|
18
|
-
getAll(): BleAdapterInfo[];
|
|
19
|
-
createInstance(settings: BleDeviceSettings, props?: DeviceProperties): BleAdapter<BleDeviceData, BleComms>;
|
|
20
|
-
removeInstance(query: {
|
|
21
|
-
settings?: BleDeviceSettings;
|
|
22
|
-
adapter?: BleAdapter<BleDeviceData, BleComms>;
|
|
23
|
-
}): void;
|
|
24
|
-
find(settings?: BleDeviceSettings): BleAdapter<BleDeviceData, BleComms>;
|
|
25
|
-
register(protocol: BleProtocol, Adapter: typeof BleAdapter<BleDeviceData, BleComms>, Comm: typeof BleComms): void;
|
|
26
|
-
getAllInstances(): Array<BleAdapter<BleDeviceData, BleComms>>;
|
|
27
|
-
getAllSupportedComms(): (typeof BleComms)[];
|
|
28
|
-
getAllSupportedAdapters(): Array<(typeof BleAdapter<BleDeviceData, BleComms>)>;
|
|
29
|
-
getAllSupportedServices(): string[];
|
|
30
|
-
getDeviceClasses(peripheral: any, props?: {
|
|
31
|
-
protocol?: BleProtocol;
|
|
32
|
-
services?: string[];
|
|
33
|
-
}): (typeof BleComms)[];
|
|
34
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const comms_utils_1 = require("./base/comms-utils");
|
|
4
|
-
const utils_1 = require("./utils");
|
|
5
|
-
class BleAdapterFactory {
|
|
6
|
-
static getInstance() {
|
|
7
|
-
if (!BleAdapterFactory._instance)
|
|
8
|
-
BleAdapterFactory._instance = new BleAdapterFactory();
|
|
9
|
-
return BleAdapterFactory._instance;
|
|
10
|
-
}
|
|
11
|
-
constructor() {
|
|
12
|
-
this.implementations = [];
|
|
13
|
-
this.instances = [];
|
|
14
|
-
}
|
|
15
|
-
getAdapterInfo(protocol) {
|
|
16
|
-
return this.implementations.find(a => a.protocol === protocol);
|
|
17
|
-
}
|
|
18
|
-
getAll() {
|
|
19
|
-
return this.implementations;
|
|
20
|
-
}
|
|
21
|
-
createInstance(settings, props) {
|
|
22
|
-
let { profile, protocol } = settings;
|
|
23
|
-
const adapterSettings = Object.assign({}, settings);
|
|
24
|
-
if (profile) {
|
|
25
|
-
try {
|
|
26
|
-
const mapping = (0, utils_1.mapLegacyProfile)(profile);
|
|
27
|
-
protocol = adapterSettings.protocol = mapping.protocol;
|
|
28
|
-
delete adapterSettings.profile;
|
|
29
|
-
}
|
|
30
|
-
catch (_a) {
|
|
31
|
-
delete settings.profile;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
const existing = this.find(adapterSettings);
|
|
35
|
-
if (existing) {
|
|
36
|
-
existing.setProperties(props);
|
|
37
|
-
return existing;
|
|
38
|
-
}
|
|
39
|
-
const info = this.getAdapterInfo(protocol);
|
|
40
|
-
if (!info || !info.Adapter)
|
|
41
|
-
return;
|
|
42
|
-
const adapter = new info.Adapter(adapterSettings, props);
|
|
43
|
-
this.instances.push(adapter);
|
|
44
|
-
return adapter;
|
|
45
|
-
}
|
|
46
|
-
removeInstance(query) {
|
|
47
|
-
let idx = -1;
|
|
48
|
-
if (query.settings) {
|
|
49
|
-
idx = this.instances.findIndex(a => a.isEqual(query.settings));
|
|
50
|
-
}
|
|
51
|
-
else if (query.adapter) {
|
|
52
|
-
idx = this.instances.findIndex(a => a.isEqual(query.adapter.getSettings()));
|
|
53
|
-
}
|
|
54
|
-
if (idx !== -1)
|
|
55
|
-
this.instances.splice(idx);
|
|
56
|
-
}
|
|
57
|
-
find(settings) {
|
|
58
|
-
return this.instances.find(a => a.isEqual(settings));
|
|
59
|
-
}
|
|
60
|
-
register(protocol, Adapter, Comm) {
|
|
61
|
-
const info = Object.assign({}, { protocol, Adapter, Comm });
|
|
62
|
-
const existing = this.implementations.findIndex(a => a.protocol === protocol);
|
|
63
|
-
if (existing !== -1)
|
|
64
|
-
this.implementations[existing] = info;
|
|
65
|
-
else
|
|
66
|
-
this.implementations.push(info);
|
|
67
|
-
}
|
|
68
|
-
getAllInstances() {
|
|
69
|
-
return this.instances;
|
|
70
|
-
}
|
|
71
|
-
getAllSupportedComms() {
|
|
72
|
-
const supported = BleAdapterFactory.getInstance().getAll();
|
|
73
|
-
return supported.map(info => info.Comm);
|
|
74
|
-
}
|
|
75
|
-
getAllSupportedAdapters() {
|
|
76
|
-
const supported = BleAdapterFactory.getInstance().getAll();
|
|
77
|
-
return supported.map(info => info.Adapter);
|
|
78
|
-
}
|
|
79
|
-
getAllSupportedServices() {
|
|
80
|
-
const supported = BleAdapterFactory.getInstance().getAll();
|
|
81
|
-
const res = [];
|
|
82
|
-
if (supported && supported.length > 0) {
|
|
83
|
-
supported.forEach(info => {
|
|
84
|
-
if (info && info.Comm && info.Comm.services) {
|
|
85
|
-
info.Comm.services.forEach(s => {
|
|
86
|
-
if (!res.includes(s))
|
|
87
|
-
res.push(s);
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
return res;
|
|
93
|
-
}
|
|
94
|
-
getDeviceClasses(peripheral, props = {}) {
|
|
95
|
-
let DeviceClasses;
|
|
96
|
-
const { protocol, services = peripheral.advertisement.serviceUuids } = props;
|
|
97
|
-
const classes = this.getAllSupportedComms();
|
|
98
|
-
DeviceClasses = (0, comms_utils_1.getDevicesFromServices)(classes, services);
|
|
99
|
-
if (protocol && DeviceClasses && DeviceClasses.length > 0) {
|
|
100
|
-
DeviceClasses = DeviceClasses.filter((C) => {
|
|
101
|
-
const device = new C({ peripheral });
|
|
102
|
-
if (device.getProtocol() !== protocol)
|
|
103
|
-
return false;
|
|
104
|
-
return true;
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
return DeviceClasses;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
exports.default = BleAdapterFactory;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { BleProtocol } from "../types";
|
|
2
|
-
import { BleComms } from "./comms";
|
|
3
|
-
export declare function getBestDeviceMatch(DeviceClasses: (typeof BleComms)[]): typeof BleComms;
|
|
4
|
-
export declare function getDevicesFromServices(deviceTypes: (typeof BleComms)[], services: string | string[]): (typeof BleComms)[];
|
|
5
|
-
export declare function getServicesFromDeviceTypes(deviceTypes: (typeof BleComms)[]): string[];
|
|
6
|
-
export declare function getServicesFromProtocols(protocols: BleProtocol[]): string[];
|
|
7
|
-
export declare function getServicesFromDevice(device: BleComms): string[];
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getBestDeviceMatch = getBestDeviceMatch;
|
|
7
|
-
exports.getDevicesFromServices = getDevicesFromServices;
|
|
8
|
-
exports.getServicesFromDeviceTypes = getServicesFromDeviceTypes;
|
|
9
|
-
exports.getServicesFromProtocols = getServicesFromProtocols;
|
|
10
|
-
exports.getServicesFromDevice = getServicesFromDevice;
|
|
11
|
-
const adapter_factory_1 = __importDefault(require("../adapter-factory"));
|
|
12
|
-
const utils_1 = require("../utils");
|
|
13
|
-
function getBestDeviceMatch(DeviceClasses) {
|
|
14
|
-
if (!DeviceClasses || DeviceClasses.length === 0)
|
|
15
|
-
return;
|
|
16
|
-
const details = DeviceClasses.map(c => ({ name: c.prototype.constructor.name, priority: c.detectionPriority || 0, class: c }));
|
|
17
|
-
details.sort((a, b) => b.priority - a.priority);
|
|
18
|
-
return details[0].class;
|
|
19
|
-
}
|
|
20
|
-
function getDevicesFromServices(deviceTypes, services) {
|
|
21
|
-
if (!deviceTypes || !Array.isArray(deviceTypes) || deviceTypes.length === 0) {
|
|
22
|
-
return [];
|
|
23
|
-
}
|
|
24
|
-
const get = (deviceTypes, fnCompare) => {
|
|
25
|
-
const types = deviceTypes.filter(DeviceType => {
|
|
26
|
-
const C = DeviceType;
|
|
27
|
-
let found = false;
|
|
28
|
-
if (C.services)
|
|
29
|
-
found = C.services.find((s) => fnCompare(s));
|
|
30
|
-
return found;
|
|
31
|
-
});
|
|
32
|
-
return types;
|
|
33
|
-
};
|
|
34
|
-
if (typeof services === 'string') {
|
|
35
|
-
return get(deviceTypes, (s) => (0, utils_1.matches)(s, services));
|
|
36
|
-
}
|
|
37
|
-
if (Array.isArray(services)) {
|
|
38
|
-
const sids = services.map(utils_1.uuid);
|
|
39
|
-
return get(deviceTypes, s => {
|
|
40
|
-
const res = sids.find((service) => (0, utils_1.matches)(s, service));
|
|
41
|
-
return res !== undefined;
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
return [];
|
|
45
|
-
}
|
|
46
|
-
function getServicesFromDeviceTypes(deviceTypes) {
|
|
47
|
-
let services = [];
|
|
48
|
-
try {
|
|
49
|
-
if (!deviceTypes || !Array.isArray(deviceTypes) || deviceTypes.length === 0) {
|
|
50
|
-
return [];
|
|
51
|
-
}
|
|
52
|
-
deviceTypes.forEach(DeviceType => {
|
|
53
|
-
if (DeviceType.services) {
|
|
54
|
-
const dtServices = DeviceType.services;
|
|
55
|
-
dtServices.forEach(s => {
|
|
56
|
-
if (!services.find(s2 => s2 === s))
|
|
57
|
-
services.push(s);
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
catch (err) {
|
|
63
|
-
console.log(err);
|
|
64
|
-
}
|
|
65
|
-
return services;
|
|
66
|
-
}
|
|
67
|
-
function getServicesFromProtocols(protocols) {
|
|
68
|
-
const services = [];
|
|
69
|
-
const comms = adapter_factory_1.default.getInstance().getAllSupportedComms();
|
|
70
|
-
comms
|
|
71
|
-
.filter((C) => protocols.find(p => p === C.protocol) !== undefined)
|
|
72
|
-
.forEach((C) => {
|
|
73
|
-
C.services.forEach(s => {
|
|
74
|
-
if (!services.find(s2 => s2 === s))
|
|
75
|
-
services.push(s);
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
return services;
|
|
79
|
-
}
|
|
80
|
-
function getServicesFromDevice(device) {
|
|
81
|
-
if (!device)
|
|
82
|
-
return [];
|
|
83
|
-
const services = [];
|
|
84
|
-
const dServices = device.getServiceUUids();
|
|
85
|
-
dServices.forEach(s => {
|
|
86
|
-
if (!services.find(s2 => s2 === s))
|
|
87
|
-
services.push(s);
|
|
88
|
-
});
|
|
89
|
-
return services;
|
|
90
|
-
}
|