incyclist-devices 1.4.94 → 1.4.96
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/ant/antfe/AntFEAdapter.js +2 -3
- package/lib/ant/antfe/ant-fe-adv-st-mode.d.ts +9 -0
- package/lib/ant/antfe/ant-fe-adv-st-mode.js +51 -0
- package/lib/ant/antfe/ant-fe-erg-mode.d.ts +1 -0
- package/lib/ant/antfe/ant-fe-erg-mode.js +1 -0
- package/lib/ant/antfe/ant-fe-st-mode copy.d.ts +7 -0
- package/lib/ant/antfe/ant-fe-st-mode copy.js +54 -0
- package/lib/ant/antfe/ant-fe-st-mode.d.ts +0 -2
- package/lib/ant/antfe/ant-fe-st-mode.js +1 -40
- package/lib/ble/ble-erg-mode.d.ts +1 -0
- package/lib/ble/ble-erg-mode.js +2 -7
- package/lib/ble/ble-interface.js +56 -70
- package/lib/ble/fm.d.ts +1 -0
- package/lib/ble/fm.js +15 -4
- package/lib/ble/hrm.d.ts +1 -0
- package/lib/ble/hrm.js +1 -0
- package/lib/ble/pwr.d.ts +1 -0
- package/lib/ble/pwr.js +1 -0
- package/lib/ble/tacx.d.ts +1 -0
- package/lib/ble/tacx.js +1 -1
- package/lib/ble/wahoo-kickr.d.ts +1 -0
- package/lib/ble/wahoo-kickr.js +1 -0
- package/lib/daum/ERGCyclingMode.d.ts +1 -0
- package/lib/daum/ERGCyclingMode.js +1 -0
- package/lib/kettler/ergo-racer/ERGCyclingMode.d.ts +1 -0
- package/lib/kettler/ergo-racer/ERGCyclingMode.js +1 -0
- package/lib/modes/simulator.d.ts +1 -0
- package/lib/modes/simulator.js +1 -0
- package/package.json +1 -1
|
@@ -18,8 +18,7 @@ const utils_1 = require("../utils");
|
|
|
18
18
|
const utils_2 = require("../../utils");
|
|
19
19
|
const ant_fe_st_mode_1 = __importDefault(require("./ant-fe-st-mode"));
|
|
20
20
|
const ant_fe_erg_mode_1 = __importDefault(require("./ant-fe-erg-mode"));
|
|
21
|
-
const
|
|
22
|
-
const intVal = (d) => d ? parseInt(d) : d;
|
|
21
|
+
const ant_fe_adv_st_mode_1 = __importDefault(require("./ant-fe-adv-st-mode"));
|
|
23
22
|
const hex = (v) => Math.abs(v).toString(16).toUpperCase();
|
|
24
23
|
const TIMEOUT_ACK = 5000;
|
|
25
24
|
const TIMEOUT_START = 10000;
|
|
@@ -58,7 +57,7 @@ class AntFEAdapter extends AntAdapter_1.default {
|
|
|
58
57
|
return `${(0, utils_1.getBrand)(ManId)} FE ${DeviceID}${hrmStr}`;
|
|
59
58
|
}
|
|
60
59
|
getSupportedCyclingModes() {
|
|
61
|
-
return [ant_fe_st_mode_1.default, ant_fe_erg_mode_1.default];
|
|
60
|
+
return [ant_fe_st_mode_1.default, ant_fe_erg_mode_1.default, ant_fe_adv_st_mode_1.default];
|
|
62
61
|
}
|
|
63
62
|
setCyclingMode(mode, settings) {
|
|
64
63
|
let selectedMode;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import FtmsCyclingMode from "../../ble/ble-st-mode";
|
|
2
|
+
import { UpdateRequest } from "../../CyclingMode";
|
|
3
|
+
import { DeviceAdapter } from "../../Device";
|
|
4
|
+
export default class AntAdvSimCyclingMode extends FtmsCyclingMode {
|
|
5
|
+
constructor(adapter: DeviceAdapter, props?: any);
|
|
6
|
+
getName(): string;
|
|
7
|
+
getDescription(): string;
|
|
8
|
+
sendBikeUpdate(request: UpdateRequest): UpdateRequest;
|
|
9
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
const ble_st_mode_1 = __importDefault(require("../../ble/ble-st-mode"));
|
|
7
|
+
const MAX_DEVIATION = 10;
|
|
8
|
+
class AntAdvSimCyclingMode extends ble_st_mode_1.default {
|
|
9
|
+
constructor(adapter, props) {
|
|
10
|
+
super(adapter, props);
|
|
11
|
+
this.initLogger('AntAdvSimMode');
|
|
12
|
+
}
|
|
13
|
+
getName() {
|
|
14
|
+
return 'Advanced Smart Trainer';
|
|
15
|
+
}
|
|
16
|
+
getDescription() {
|
|
17
|
+
return 'Sends Slope to device. Respects Limits (from workout or settings). Calculates speed based on power and slope. ';
|
|
18
|
+
}
|
|
19
|
+
sendBikeUpdate(request) {
|
|
20
|
+
const getData = () => {
|
|
21
|
+
if (!this.data)
|
|
22
|
+
return {};
|
|
23
|
+
const { gear, pedalRpm, slope, power, speed } = this.data;
|
|
24
|
+
return { gear, pedalRpm, slope, power, speed };
|
|
25
|
+
};
|
|
26
|
+
this.logger.logEvent({ message: "processing update request", request, prev: this.prevRequest, data: getData() });
|
|
27
|
+
let newRequest = {};
|
|
28
|
+
if (request.slope === undefined && request.targetPower === undefined && request.refresh && this.prevRequest) {
|
|
29
|
+
return this.prevRequest;
|
|
30
|
+
}
|
|
31
|
+
if (request.slope !== undefined) {
|
|
32
|
+
newRequest.slope = parseFloat(request.slope.toFixed(1));
|
|
33
|
+
this.data.slope = newRequest.slope;
|
|
34
|
+
}
|
|
35
|
+
if (this.data && this.data.power) {
|
|
36
|
+
const { minPower, maxPower } = request;
|
|
37
|
+
let { targetPower } = request;
|
|
38
|
+
if (minPower !== undefined && maxPower !== undefined && minPower === maxPower)
|
|
39
|
+
targetPower = maxPower;
|
|
40
|
+
if (targetPower !== undefined && Math.abs(this.data.power - targetPower) > MAX_DEVIATION)
|
|
41
|
+
newRequest.targetPower = targetPower;
|
|
42
|
+
else if (minPower !== undefined && this.data.power < minPower)
|
|
43
|
+
newRequest.targetPower = minPower;
|
|
44
|
+
else if (request.maxPower !== undefined && this.data.power > request.maxPower)
|
|
45
|
+
newRequest.targetPower = maxPower;
|
|
46
|
+
}
|
|
47
|
+
this.prevRequest = JSON.parse(JSON.stringify(newRequest));
|
|
48
|
+
return newRequest;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.default = AntAdvSimCyclingMode;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import FtmsCyclingMode from "../../ble/ble-st-mode";
|
|
2
|
+
import { UpdateRequest } from "../../CyclingMode";
|
|
3
|
+
import { DeviceAdapter } from "../../Device";
|
|
4
|
+
export default class AntStCyclingMode extends FtmsCyclingMode {
|
|
5
|
+
constructor(adapter: DeviceAdapter, props?: any);
|
|
6
|
+
sendBikeUpdate(request: UpdateRequest): UpdateRequest;
|
|
7
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
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
|
+
const ble_st_mode_1 = __importDefault(require("../../ble/ble-st-mode"));
|
|
7
|
+
class AntStCyclingMode extends ble_st_mode_1.default {
|
|
8
|
+
constructor(adapter, props) {
|
|
9
|
+
super(adapter, props);
|
|
10
|
+
this.initLogger('AntSTMode');
|
|
11
|
+
}
|
|
12
|
+
sendBikeUpdate(request) {
|
|
13
|
+
console.log('~~~ SIMMode:sendBikeUpdate reuqest', request);
|
|
14
|
+
const getData = () => {
|
|
15
|
+
if (!this.data)
|
|
16
|
+
return {};
|
|
17
|
+
const { gear, pedalRpm, slope, power, speed } = this.data;
|
|
18
|
+
return { gear, pedalRpm, slope, power, speed };
|
|
19
|
+
};
|
|
20
|
+
const event = {};
|
|
21
|
+
if (this.data === undefined)
|
|
22
|
+
event.noData = true;
|
|
23
|
+
if (request.slope !== undefined && (event.noData || Math.abs(request.slope - this.data.slope) >= 0.1))
|
|
24
|
+
event.slopeUpdate = true;
|
|
25
|
+
if (this.prevRequest === undefined)
|
|
26
|
+
event.initialCall = true;
|
|
27
|
+
this.logger.logEvent({ message: "processing update request", request, prev: this.prevRequest, data: getData(), event });
|
|
28
|
+
let newRequest = {};
|
|
29
|
+
if (request.slope === undefined && request.targetPower === undefined && request.refresh && this.prevRequest) {
|
|
30
|
+
return this.prevRequest;
|
|
31
|
+
}
|
|
32
|
+
if (request.slope !== undefined) {
|
|
33
|
+
newRequest.slope = parseFloat(request.slope.toFixed(1));
|
|
34
|
+
this.data.slope = newRequest.slope;
|
|
35
|
+
}
|
|
36
|
+
if (request.targetPower !== undefined) {
|
|
37
|
+
newRequest.targetPower = request.targetPower;
|
|
38
|
+
}
|
|
39
|
+
if (request.minPower && request.maxPower && request.minPower === request.maxPower) {
|
|
40
|
+
newRequest.targetPower = request.minPower;
|
|
41
|
+
}
|
|
42
|
+
const prevData = this.data;
|
|
43
|
+
if (newRequest.targetPower === undefined && prevData && prevData.power) {
|
|
44
|
+
if (request.minPower !== undefined && prevData.power < request.minPower)
|
|
45
|
+
newRequest.targetPower = request.minPower;
|
|
46
|
+
if (request.maxPower !== undefined && prevData.power > request.maxPower)
|
|
47
|
+
newRequest.targetPower = request.maxPower;
|
|
48
|
+
}
|
|
49
|
+
this.prevRequest = JSON.parse(JSON.stringify(newRequest));
|
|
50
|
+
console.log('~~~ SimMode:sendBikeUpdate result', newRequest);
|
|
51
|
+
return newRequest;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.default = AntStCyclingMode;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import FtmsCyclingMode from "../../ble/ble-st-mode";
|
|
2
|
-
import { UpdateRequest } from "../../CyclingMode";
|
|
3
2
|
import { DeviceAdapter } from "../../Device";
|
|
4
3
|
export default class AntStCyclingMode extends FtmsCyclingMode {
|
|
5
4
|
constructor(adapter: DeviceAdapter, props?: any);
|
|
6
|
-
sendBikeUpdate(request: UpdateRequest): UpdateRequest;
|
|
7
5
|
}
|
|
@@ -7,46 +7,7 @@ const ble_st_mode_1 = __importDefault(require("../../ble/ble-st-mode"));
|
|
|
7
7
|
class AntStCyclingMode extends ble_st_mode_1.default {
|
|
8
8
|
constructor(adapter, props) {
|
|
9
9
|
super(adapter, props);
|
|
10
|
-
this.initLogger('
|
|
11
|
-
}
|
|
12
|
-
sendBikeUpdate(request) {
|
|
13
|
-
const getData = () => {
|
|
14
|
-
if (!this.data)
|
|
15
|
-
return {};
|
|
16
|
-
const { gear, pedalRpm, slope, power, speed } = this.data;
|
|
17
|
-
return { gear, pedalRpm, slope, power, speed };
|
|
18
|
-
};
|
|
19
|
-
const event = {};
|
|
20
|
-
if (this.data === undefined)
|
|
21
|
-
event.noData = true;
|
|
22
|
-
if (request.slope !== undefined && (event.noData || Math.abs(request.slope - this.data.slope) >= 0.1))
|
|
23
|
-
event.slopeUpdate = true;
|
|
24
|
-
if (this.prevRequest === undefined)
|
|
25
|
-
event.initialCall = true;
|
|
26
|
-
this.logger.logEvent({ message: "processing update request", request, prev: this.prevRequest, data: getData(), event });
|
|
27
|
-
let newRequest = {};
|
|
28
|
-
if (request.slope === undefined && request.targetPower === undefined && request.refresh && this.prevRequest) {
|
|
29
|
-
return this.prevRequest;
|
|
30
|
-
}
|
|
31
|
-
if (request.slope !== undefined) {
|
|
32
|
-
newRequest.slope = parseFloat(request.slope.toFixed(1));
|
|
33
|
-
this.data.slope = newRequest.slope;
|
|
34
|
-
}
|
|
35
|
-
if (request.targetPower !== undefined) {
|
|
36
|
-
newRequest.targetPower = request.targetPower;
|
|
37
|
-
}
|
|
38
|
-
if (request.minPower && request.maxPower && request.minPower === request.maxPower) {
|
|
39
|
-
newRequest.targetPower = request.minPower;
|
|
40
|
-
}
|
|
41
|
-
const prevData = this.data;
|
|
42
|
-
if (newRequest.targetPower === undefined && prevData && prevData.power) {
|
|
43
|
-
if (request.minPower !== undefined && prevData.power < request.minPower)
|
|
44
|
-
newRequest.targetPower = request.minPower;
|
|
45
|
-
if (request.maxPower !== undefined && prevData.power > request.maxPower)
|
|
46
|
-
newRequest.targetPower = request.maxPower;
|
|
47
|
-
}
|
|
48
|
-
this.prevRequest = JSON.parse(JSON.stringify(newRequest));
|
|
49
|
-
return newRequest;
|
|
10
|
+
this.initLogger('AntSimMode');
|
|
50
11
|
}
|
|
51
12
|
}
|
|
52
13
|
exports.default = AntStCyclingMode;
|
|
@@ -2,6 +2,7 @@ import CyclingMode, { CyclingModeProperty, IncyclistBikeData, UpdateRequest } fr
|
|
|
2
2
|
import { DeviceAdapter } from "../Device";
|
|
3
3
|
import PowerBasedCyclingModeBase from "../modes/power-base";
|
|
4
4
|
export default class BleERGCyclingMode extends PowerBasedCyclingModeBase implements CyclingMode {
|
|
5
|
+
static isERG: boolean;
|
|
5
6
|
prevRequest: UpdateRequest;
|
|
6
7
|
hasBikeUpdate: boolean;
|
|
7
8
|
chain: number[];
|
package/lib/ble/ble-erg-mode.js
CHANGED
|
@@ -50,21 +50,15 @@ class BleERGCyclingMode extends power_base_1.default {
|
|
|
50
50
|
this.prevRequest = {};
|
|
51
51
|
return request.reset ? { reset: true } : {};
|
|
52
52
|
}
|
|
53
|
+
delete request.slope;
|
|
53
54
|
const prevData = this.data || {};
|
|
54
55
|
if (request.targetPower !== undefined) {
|
|
55
|
-
delete request.slope;
|
|
56
56
|
delete request.refresh;
|
|
57
57
|
}
|
|
58
58
|
if (request.refresh) {
|
|
59
59
|
delete request.refresh;
|
|
60
60
|
newRequest.targetPower = this.prevRequest.targetPower;
|
|
61
61
|
}
|
|
62
|
-
if (request.slope !== undefined) {
|
|
63
|
-
if (!this.data)
|
|
64
|
-
this.data = {};
|
|
65
|
-
this.data.slope = request.slope;
|
|
66
|
-
delete request.slope;
|
|
67
|
-
}
|
|
68
62
|
if (request.maxPower !== undefined && request.minPower !== undefined && request.maxPower === request.minPower) {
|
|
69
63
|
request.targetPower = request.maxPower;
|
|
70
64
|
newRequest.targetPower = request.targetPower;
|
|
@@ -130,3 +124,4 @@ class BleERGCyclingMode extends power_base_1.default {
|
|
|
130
124
|
}
|
|
131
125
|
}
|
|
132
126
|
exports.default = BleERGCyclingMode;
|
|
127
|
+
BleERGCyclingMode.isERG = true;
|
package/lib/ble/ble-interface.js
CHANGED
|
@@ -71,9 +71,6 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
71
71
|
}
|
|
72
72
|
connect(props = {}) {
|
|
73
73
|
const timeout = props.timeout || 2000;
|
|
74
|
-
const runBackgroundScan = () => {
|
|
75
|
-
return;
|
|
76
|
-
};
|
|
77
74
|
return new Promise((resolve, reject) => {
|
|
78
75
|
if (this.connectState.isConnected) {
|
|
79
76
|
return resolve(true);
|
|
@@ -122,7 +119,6 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
122
119
|
this.connectState.isConnecting = false;
|
|
123
120
|
this.logEvent({ message: 'connect result: success' });
|
|
124
121
|
resolve(true);
|
|
125
|
-
runBackgroundScan();
|
|
126
122
|
return;
|
|
127
123
|
}
|
|
128
124
|
else {
|
|
@@ -142,7 +138,6 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
142
138
|
this.connectState.isConnected = true;
|
|
143
139
|
this.connectState.isConnecting = false;
|
|
144
140
|
this.logEvent({ message: 'connect result: success' });
|
|
145
|
-
runBackgroundScan();
|
|
146
141
|
return resolve(true);
|
|
147
142
|
}
|
|
148
143
|
else {
|
|
@@ -489,7 +484,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
489
484
|
}
|
|
490
485
|
scan(props) {
|
|
491
486
|
return __awaiter(this, void 0, void 0, function* () {
|
|
492
|
-
const { timeout = DEFAULT_SCAN_TIMEOUT, deviceTypes = [], requested
|
|
487
|
+
const { timeout = DEFAULT_SCAN_TIMEOUT, deviceTypes = [], requested } = props;
|
|
493
488
|
let profile;
|
|
494
489
|
if (requested)
|
|
495
490
|
profile = requested instanceof ble_1.BleDeviceClass ?
|
|
@@ -497,7 +492,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
497
492
|
requested.profile;
|
|
498
493
|
const { id, address, name } = requested || {};
|
|
499
494
|
const scanForDevice = (requested !== null && requested !== undefined);
|
|
500
|
-
const services = (
|
|
495
|
+
const services = (!deviceTypes || deviceTypes.length === 0) ? this.getAllSupportedServices() : this.getServicesFromDeviceTypes(deviceTypes);
|
|
501
496
|
const bleBinding = this.getBinding();
|
|
502
497
|
if (!bleBinding)
|
|
503
498
|
return Promise.reject(new Error('no binding defined'));
|
|
@@ -506,18 +501,14 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
506
501
|
}
|
|
507
502
|
const peripheralsProcessed = [];
|
|
508
503
|
const devicesProcessed = [];
|
|
509
|
-
this.logEvent({ message: 'scan()', props: { timeout
|
|
504
|
+
this.logEvent({ message: 'scan()', props: { timeout }, scanState: this.scanState,
|
|
510
505
|
peripheralCache: this.peripheralCache.map(i => ({ address: i.address, ts: i.ts, name: i.peripheral ? i.peripheral.advertisement.localName : '' })),
|
|
511
506
|
deviceCache: this.devices.map(i => ({ address: i.device.address, profile: i.device.getProfile(), isConnected: i.isConnected }))
|
|
512
507
|
});
|
|
513
|
-
if (!props.isBackgroundScan && this.scanState.isBackgroundScan) {
|
|
514
|
-
yield this.stopScan();
|
|
515
|
-
this.scanState.isBackgroundScan = false;
|
|
516
|
-
}
|
|
517
508
|
let opStr;
|
|
518
509
|
if (scanForDevice) {
|
|
519
510
|
opStr = 'search device';
|
|
520
|
-
this.logEvent({ message: 'search device request', device: { id, address, name }, deviceTypes });
|
|
511
|
+
this.logEvent({ message: 'search device request', services, device: { id, address, name }, deviceTypes });
|
|
521
512
|
}
|
|
522
513
|
else {
|
|
523
514
|
opStr = 'scan';
|
|
@@ -536,8 +527,6 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
536
527
|
}
|
|
537
528
|
return new Promise((resolve, reject) => {
|
|
538
529
|
this.scanState.isScanning = true;
|
|
539
|
-
if (props.isBackgroundScan)
|
|
540
|
-
this.scanState.isBackgroundScan = true;
|
|
541
530
|
if (scanForDevice) {
|
|
542
531
|
if (this.devices && this.devices.length > 0) {
|
|
543
532
|
const knownDevices = this.devices.map(i => ({ name: i.device.name, address: i.device.address, isConnected: i.isConnected, connectState: i.device.getConnectState() }));
|
|
@@ -566,8 +555,9 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
566
555
|
const onPeripheralFound = (peripheral, fromCache = false) => __awaiter(this, void 0, void 0, function* () {
|
|
567
556
|
if (!peripheral || !peripheral.advertisement || !peripheral.advertisement.localName || !peripheral.advertisement.serviceUuids || peripheral.advertisement.serviceUuids.length === 0)
|
|
568
557
|
return;
|
|
569
|
-
if (fromCache)
|
|
558
|
+
if (fromCache) {
|
|
570
559
|
this.logEvent({ message: 'adding from Cache', peripheral: peripheral.address });
|
|
560
|
+
}
|
|
571
561
|
else {
|
|
572
562
|
const { id, name, address, advertisement = {} } = peripheral;
|
|
573
563
|
this.logEvent({ message: 'BLE scan: found device', peripheral: { id, name, address, services: advertisement.serviceUuids } });
|
|
@@ -584,66 +574,62 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
584
574
|
const services = connectedServices ? connectedServices.map(cs => cs.uuid) : undefined;
|
|
585
575
|
const connectedPeripheral = connector.getPeripheral();
|
|
586
576
|
const { id, name, address, advertisement = {} } = connectedPeripheral;
|
|
587
|
-
const DeviceClasses = this.getDeviceClasses(connectedPeripheral, { profile, services });
|
|
577
|
+
const DeviceClasses = this.getDeviceClasses(connectedPeripheral, { profile, services }) || [];
|
|
588
578
|
this.logEvent({ message: 'BLE scan: device connected', peripheral: { id, name, address, services: advertisement.serviceUuids }, services, classes: DeviceClasses.map(c => c.prototype.constructor.name) });
|
|
589
579
|
let cntFound = 0;
|
|
590
|
-
DeviceClasses.
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
cntFound++;
|
|
612
|
-
}
|
|
613
|
-
else
|
|
580
|
+
const DeviceClass = DeviceClasses.sort((a, b) => (a.detectionPriority || 0 - b.detectionPriority || 0))[0];
|
|
581
|
+
if (!DeviceClass)
|
|
582
|
+
return;
|
|
583
|
+
if (scanForDevice && cntFound > 0)
|
|
584
|
+
return;
|
|
585
|
+
const d = this.createDevice(DeviceClass, peripheral, characteristics);
|
|
586
|
+
if (!d) {
|
|
587
|
+
this.logEvent({ message: `${opStr}: could not create device `, DeviceClass });
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
try {
|
|
591
|
+
this.logEvent({ message: `${opStr}: connecting `, device: d.name, profile: d.getProfile(), address: d.address });
|
|
592
|
+
yield d.connect();
|
|
593
|
+
}
|
|
594
|
+
catch (err) {
|
|
595
|
+
this.logEvent({ message: 'error', fn: 'onPeripheralFound()', error: err.message || err, stack: err.stack });
|
|
596
|
+
}
|
|
597
|
+
if (scanForDevice) {
|
|
598
|
+
if ((id && id !== '' && d.id === id) ||
|
|
599
|
+
(address && address !== '' && d.address === address) ||
|
|
600
|
+
(name && name !== '' && d.name === name))
|
|
614
601
|
cntFound++;
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
this.
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
602
|
+
}
|
|
603
|
+
else
|
|
604
|
+
cntFound++;
|
|
605
|
+
const existing = devicesProcessed.find(device => device.id === d.id && device.getProfile() === d.getProfile());
|
|
606
|
+
if (!scanForDevice && cntFound > 0 && !existing) {
|
|
607
|
+
this.logEvent({ message: `${opStr}: device found`, device: d.name, profile: d.getProfile(), address: d.address, services: d.services.join(',') });
|
|
608
|
+
this.addDeviceToCache(d, peripheral.state === 'connected');
|
|
609
|
+
devicesProcessed.push(d);
|
|
610
|
+
this.emit('device', d);
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
if (scanForDevice && cntFound > 0) {
|
|
614
|
+
this.logEvent({ message: `${opStr}: device found`, device: d.name, profile: d.getProfile(), address: d.address, services: d.services.join(',') });
|
|
615
|
+
this.addDeviceToCache(d, peripheral.state === 'connected');
|
|
616
|
+
devicesProcessed.push(d);
|
|
617
|
+
this.emit('device', d);
|
|
618
|
+
process.nextTick(() => {
|
|
619
|
+
if (this.scanState.timeout) {
|
|
620
|
+
clearTimeout(this.scanState.timeout);
|
|
621
|
+
this.scanState.timeout = null;
|
|
622
|
+
}
|
|
623
|
+
this.logEvent({ message: `${opStr}: stop scanning`, requested: scanForDevice ? { name, address, profile } : undefined, });
|
|
624
|
+
bleBinding.stopScanning(() => {
|
|
625
|
+
this.getBinding().removeAllListeners('discover');
|
|
626
|
+
this.scanState.isScanning = false;
|
|
627
|
+
resolve([d]);
|
|
639
628
|
});
|
|
640
|
-
}
|
|
641
|
-
}
|
|
629
|
+
});
|
|
630
|
+
}
|
|
642
631
|
});
|
|
643
632
|
this.logEvent({ message: `${opStr}: start scanning`, requested: scanForDevice ? { name, address, profile } : undefined, timeout });
|
|
644
|
-
this.peripheralCache.forEach(i => {
|
|
645
|
-
onPeripheralFound(i.peripheral, true);
|
|
646
|
-
});
|
|
647
633
|
let services = [];
|
|
648
634
|
if (scanForDevice) {
|
|
649
635
|
if (props.requested instanceof ble_1.BleDeviceClass) {
|
package/lib/ble/fm.d.ts
CHANGED
|
@@ -45,6 +45,7 @@ declare type IndoorBikeFeatures = {
|
|
|
45
45
|
export default class BleFitnessMachineDevice extends BleDevice {
|
|
46
46
|
static services: string[];
|
|
47
47
|
static characteristics: string[];
|
|
48
|
+
static detectionPriority: number;
|
|
48
49
|
data: IndoorBikeData;
|
|
49
50
|
features: IndoorBikeFeatures;
|
|
50
51
|
hasControl: boolean;
|
package/lib/ble/fm.js
CHANGED
|
@@ -21,6 +21,7 @@ const power_meter_1 = __importDefault(require("../modes/power-meter"));
|
|
|
21
21
|
const ble_st_mode_1 = __importDefault(require("./ble-st-mode"));
|
|
22
22
|
const ble_erg_mode_1 = __importDefault(require("./ble-erg-mode"));
|
|
23
23
|
const consts_1 = require("./consts");
|
|
24
|
+
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
24
25
|
const cwABike = {
|
|
25
26
|
race: 0.35,
|
|
26
27
|
triathlon: 0.29,
|
|
@@ -101,7 +102,6 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
101
102
|
const hasStatus = characteristics.find(c => c === consts_1.FTMS_STATUS) !== undefined;
|
|
102
103
|
const hasCP = characteristics.find(c => c === consts_1.FTMS_CP) !== undefined;
|
|
103
104
|
const hasIndoorBike = characteristics.find(c => c === consts_1.INDOOR_BIKE_DATA) !== undefined;
|
|
104
|
-
const hasTacx = characteristics.find(c => c === consts_1.TACX_FE_C_RX) !== undefined && characteristics.find(c => c === consts_1.TACX_FE_C_TX) !== undefined;
|
|
105
105
|
return hasStatus && hasCP && hasIndoorBike;
|
|
106
106
|
}
|
|
107
107
|
subscribeWriteResponse(cuuid) {
|
|
@@ -185,8 +185,8 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
185
185
|
return BleFitnessMachineDevice.services;
|
|
186
186
|
}
|
|
187
187
|
isBike() {
|
|
188
|
-
return this.features
|
|
189
|
-
(this.features.targetSettings & TargetSettingFeatureFlag.IndoorBikeSimulationParametersSupported) !== 0;
|
|
188
|
+
return this.features === undefined ||
|
|
189
|
+
((this.features.targetSettings & TargetSettingFeatureFlag.IndoorBikeSimulationParametersSupported) !== 0);
|
|
190
190
|
}
|
|
191
191
|
isPower() {
|
|
192
192
|
if (this.hasService('1818'))
|
|
@@ -539,6 +539,7 @@ class BleFitnessMachineDevice extends ble_device_1.BleDevice {
|
|
|
539
539
|
exports.default = BleFitnessMachineDevice;
|
|
540
540
|
BleFitnessMachineDevice.services = [consts_1.FTMS];
|
|
541
541
|
BleFitnessMachineDevice.characteristics = ['2acc', consts_1.INDOOR_BIKE_DATA, '2ad6', '2ad8', consts_1.FTMS_CP, consts_1.FTMS_STATUS];
|
|
542
|
+
BleFitnessMachineDevice.detectionPriority = 100;
|
|
542
543
|
ble_interface_1.default.register('BleFitnessMachineDevice', 'fm', BleFitnessMachineDevice, BleFitnessMachineDevice.services);
|
|
543
544
|
class FmAdapter extends Device_1.default {
|
|
544
545
|
constructor(device, protocol) {
|
|
@@ -685,7 +686,17 @@ class FmAdapter extends Device_1.default {
|
|
|
685
686
|
break;
|
|
686
687
|
}
|
|
687
688
|
}
|
|
688
|
-
yield this.device.requestControl();
|
|
689
|
+
let hasControl = yield this.device.requestControl();
|
|
690
|
+
if (!hasControl) {
|
|
691
|
+
let retry = 1;
|
|
692
|
+
while (!hasControl && retry < 3) {
|
|
693
|
+
yield sleep(1000);
|
|
694
|
+
hasControl = yield this.device.requestControl();
|
|
695
|
+
retry++;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
if (!hasControl)
|
|
699
|
+
throw new Error('could not establish control');
|
|
689
700
|
const startRequest = this.getCyclingMode().getBikeInitRequest();
|
|
690
701
|
yield this.sendUpdate(startRequest);
|
|
691
702
|
bleDevice.on('data', (data) => {
|
package/lib/ble/hrm.d.ts
CHANGED
package/lib/ble/hrm.js
CHANGED
|
@@ -65,6 +65,7 @@ class BleHrmDevice extends ble_device_1.BleDevice {
|
|
|
65
65
|
exports.default = BleHrmDevice;
|
|
66
66
|
BleHrmDevice.services = ['180d'];
|
|
67
67
|
BleHrmDevice.characteristics = ['2a37', '2a38', '2a39', '2a3c'];
|
|
68
|
+
BleHrmDevice.detectionPriority = 1;
|
|
68
69
|
ble_interface_1.default.register('BleHrmDevice', 'hr', BleHrmDevice, BleHrmDevice.services);
|
|
69
70
|
class HrmAdapter extends Device_1.default {
|
|
70
71
|
constructor(device, protocol) {
|
package/lib/ble/pwr.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ declare type CrankData = {
|
|
|
24
24
|
export default class BleCyclingPowerDevice extends BleDevice {
|
|
25
25
|
static services: string[];
|
|
26
26
|
static characteristics: string[];
|
|
27
|
+
static detectionPriority: number;
|
|
27
28
|
instantaneousPower: number;
|
|
28
29
|
balance: number;
|
|
29
30
|
accTorque: number;
|
package/lib/ble/pwr.js
CHANGED
|
@@ -163,6 +163,7 @@ class BleCyclingPowerDevice extends ble_device_1.BleDevice {
|
|
|
163
163
|
exports.default = BleCyclingPowerDevice;
|
|
164
164
|
BleCyclingPowerDevice.services = [consts_1.CSP];
|
|
165
165
|
BleCyclingPowerDevice.characteristics = [consts_1.CSP_MEASUREMENT, consts_1.CSP_FEATURE, '2a5d', '2a3c'];
|
|
166
|
+
BleCyclingPowerDevice.detectionPriority = 1;
|
|
166
167
|
ble_interface_1.default.register('BleCyclingPowerDevice', 'cp', BleCyclingPowerDevice, BleCyclingPowerDevice.services);
|
|
167
168
|
class PwrAdapter extends Device_1.default {
|
|
168
169
|
constructor(device, protocol) {
|
package/lib/ble/tacx.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export default class TacxAdvancedFitnessMachineDevice extends BleFitnessMachineD
|
|
|
28
28
|
static services: string[];
|
|
29
29
|
static characteristics: string[];
|
|
30
30
|
static PROFILE: string;
|
|
31
|
+
static detectionPriority: number;
|
|
31
32
|
prevCrankData: CrankData;
|
|
32
33
|
currentCrankData: CrankData;
|
|
33
34
|
timeOffset: number;
|
package/lib/ble/tacx.js
CHANGED
|
@@ -84,7 +84,6 @@ class TacxAdvancedFitnessMachineDevice extends fm_1.default {
|
|
|
84
84
|
return false;
|
|
85
85
|
const hasTacxCP = characteristics.find(c => (0, ble_1.matches)(c, consts_1.TACX_FE_C_RX)) !== undefined &&
|
|
86
86
|
characteristics.find(c => (0, ble_1.matches)(c, consts_1.TACX_FE_C_TX)) !== undefined;
|
|
87
|
-
const hasFTMS = characteristics.find(c => (0, ble_1.matches)(c, consts_1.FTMS_CP)) !== undefined;
|
|
88
87
|
return hasTacxCP;
|
|
89
88
|
}
|
|
90
89
|
setCharacteristicUUIDs(uuids) {
|
|
@@ -658,6 +657,7 @@ exports.default = TacxAdvancedFitnessMachineDevice;
|
|
|
658
657
|
TacxAdvancedFitnessMachineDevice.services = [consts_1.TACX_FE_C_BLE];
|
|
659
658
|
TacxAdvancedFitnessMachineDevice.characteristics = ['2acc', '2ad2', '2ad6', '2ad8', '2ad9', '2ada', consts_1.TACX_FE_C_RX, consts_1.TACX_FE_C_TX];
|
|
660
659
|
TacxAdvancedFitnessMachineDevice.PROFILE = PROFILE_ID;
|
|
660
|
+
TacxAdvancedFitnessMachineDevice.detectionPriority = 10;
|
|
661
661
|
ble_interface_1.default.register('TacxBleFEDevice', 'tacx-ble-fec', TacxAdvancedFitnessMachineDevice, TacxAdvancedFitnessMachineDevice.services);
|
|
662
662
|
class TacxBleFEAdapter extends fm_1.FmAdapter {
|
|
663
663
|
constructor(device, protocol) {
|
package/lib/ble/wahoo-kickr.d.ts
CHANGED
|
@@ -42,6 +42,7 @@ declare type CrankData = {
|
|
|
42
42
|
export default class WahooAdvancedFitnessMachineDevice extends BleFitnessMachineDevice {
|
|
43
43
|
static services: string[];
|
|
44
44
|
static characteristics: string[];
|
|
45
|
+
static detectionPriority: number;
|
|
45
46
|
prevCrankData: CrankData;
|
|
46
47
|
currentCrankData: CrankData;
|
|
47
48
|
timeOffset: number;
|
package/lib/ble/wahoo-kickr.js
CHANGED
|
@@ -424,6 +424,7 @@ class WahooAdvancedFitnessMachineDevice extends fm_1.default {
|
|
|
424
424
|
exports.default = WahooAdvancedFitnessMachineDevice;
|
|
425
425
|
WahooAdvancedFitnessMachineDevice.services = [consts_1.CSP];
|
|
426
426
|
WahooAdvancedFitnessMachineDevice.characteristics = ['2acc', '2ad2', '2ad6', '2ad8', '2ad9', '2ada', consts_1.WAHOO_ADVANCED_TRAINER_CP];
|
|
427
|
+
WahooAdvancedFitnessMachineDevice.detectionPriority = 5;
|
|
427
428
|
ble_interface_1.default.register('WahooAdvancedFitnessMachineDevice', 'wahoo-fm', WahooAdvancedFitnessMachineDevice, WahooAdvancedFitnessMachineDevice.services);
|
|
428
429
|
class WahooAdvancedFmAdapter extends fm_1.FmAdapter {
|
|
429
430
|
constructor(device, protocol) {
|
|
@@ -13,6 +13,7 @@ export default class ERGCyclingMode extends PowerBasedCyclingModeBase implements
|
|
|
13
13
|
chain: number[];
|
|
14
14
|
cassette: number[];
|
|
15
15
|
event: ERGEvent;
|
|
16
|
+
static isERG: boolean;
|
|
16
17
|
constructor(adapter: DaumAdapter, props?: any);
|
|
17
18
|
getName(): string;
|
|
18
19
|
getDescription(): string;
|
package/lib/modes/simulator.d.ts
CHANGED
package/lib/modes/simulator.js
CHANGED