incyclist-devices 2.3.0-beta.2 → 2.3.0-beta.20
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/README.MD +55 -0
- package/lib/antv2/base/adapter.d.ts +2 -2
- package/lib/base/adpater.d.ts +4 -0
- package/lib/base/adpater.js +16 -2
- package/lib/ble/adapter-factory.d.ts +24 -20
- package/lib/ble/adapter-factory.js +36 -13
- package/lib/ble/base/adapter.d.ts +6 -3
- package/lib/ble/base/adapter.js +72 -38
- package/lib/ble/base/comms.d.ts +74 -2
- package/lib/ble/base/comms.js +596 -3
- package/lib/ble/base/interface.d.ts +14 -5
- package/lib/ble/base/interface.js +125 -66
- package/lib/ble/base/peripheral.d.ts +7 -3
- package/lib/ble/base/peripheral.js +76 -22
- package/lib/ble/base/sensor.d.ts +1 -1
- package/lib/ble/base/sensor.js +17 -3
- package/lib/ble/ble-interface.d.ts +4 -7
- package/lib/ble/ble-interface.js +2 -16
- package/lib/ble/ble-peripheral.d.ts +0 -1
- package/lib/ble/ble-peripheral.js +11 -7
- package/lib/ble/characteristics/csc/features.d.ts +10 -0
- package/lib/ble/characteristics/csc/features.js +19 -0
- package/lib/ble/characteristics/csc/measurement.d.ts +33 -0
- package/lib/ble/characteristics/csc/measurement.js +109 -0
- package/lib/ble/characteristics/types.d.ts +6 -0
- package/lib/ble/characteristics/types.js +2 -0
- package/lib/ble/consts.d.ts +1 -0
- package/lib/ble/consts.js +2 -1
- package/lib/ble/cp/comm.d.ts +1 -1
- package/lib/ble/cp/comm.js +2 -2
- package/lib/ble/csc/adapter.d.ts +17 -0
- package/lib/ble/csc/adapter.js +66 -0
- package/lib/ble/csc/index.d.ts +3 -0
- package/lib/ble/csc/index.js +19 -0
- package/lib/ble/csc/sensor.d.ts +21 -0
- package/lib/ble/csc/sensor.js +64 -0
- package/lib/ble/csc/types.d.ts +6 -0
- package/lib/ble/csc/types.js +2 -0
- package/lib/ble/elite/comms.d.ts +1 -1
- package/lib/ble/elite/comms.js +2 -2
- package/lib/ble/fm/adapter.d.ts +4 -3
- package/lib/ble/fm/adapter.js +53 -49
- package/lib/ble/fm/comms.d.ts +1 -1
- package/lib/ble/fm/comms.js +3 -3
- package/lib/ble/fm/sensor.d.ts +1 -1
- package/lib/ble/fm/sensor.js +6 -5
- package/lib/ble/hr/comm.d.ts +1 -1
- package/lib/ble/hr/comm.js +2 -2
- package/lib/ble/index.js +2 -0
- package/lib/ble/tacx/adapter.d.ts +1 -1
- package/lib/ble/tacx/adapter.js +12 -10
- package/lib/ble/tacx/comms.d.ts +1 -1
- package/lib/ble/tacx/comms.js +2 -2
- package/lib/ble/tacx/sensor.js +9 -3
- package/lib/ble/types.d.ts +8 -2
- package/lib/ble/utils.d.ts +1 -0
- package/lib/ble/utils.js +5 -1
- package/lib/ble/wahoo/adapter.d.ts +1 -0
- package/lib/ble/wahoo/adapter.js +14 -0
- package/lib/ble/wahoo/comms.d.ts +1 -1
- package/lib/ble/wahoo/comms.js +2 -2
- package/lib/ble/wahoo/sensor.js +3 -6
- package/lib/direct-connect/base/interface.d.ts +1 -0
- package/lib/direct-connect/base/interface.js +9 -4
- package/lib/direct-connect/base/peripheral.d.ts +4 -4
- package/lib/direct-connect/base/peripheral.js +106 -31
- package/lib/direct-connect/messages/message.d.ts +1 -0
- package/lib/direct-connect/messages/message.js +16 -1
- package/lib/modes/ant-fe-adv-st-mode.d.ts +7 -1
- package/lib/modes/ant-fe-adv-st-mode.js +4 -3
- package/lib/types/adapter.d.ts +3 -0
- package/lib/types/interface.d.ts +1 -0
- package/lib/utils/task.d.ts +3 -0
- package/lib/utils/task.js +12 -0
- package/package.json +1 -1
package/lib/ble/fm/adapter.js
CHANGED
|
@@ -20,11 +20,12 @@ const sensor_1 = __importDefault(require("./sensor"));
|
|
|
20
20
|
const adapter_1 = __importDefault(require("../base/adapter"));
|
|
21
21
|
const consts_1 = require("./consts");
|
|
22
22
|
const types_1 = require("../../types");
|
|
23
|
-
const
|
|
23
|
+
const utils_1 = require("../../utils/utils");
|
|
24
24
|
class BleFmAdapter extends adapter_1.default {
|
|
25
25
|
constructor(settings, props) {
|
|
26
26
|
super(settings, props);
|
|
27
27
|
this.distanceInternal = 0;
|
|
28
|
+
this.requestControlRetryDelay = 1000;
|
|
28
29
|
this.logger = new gd_eventlog_1.EventLogger('BLE-FM');
|
|
29
30
|
this.device = new sensor_1.default(this.getPeripheral(), { logger: this.logger });
|
|
30
31
|
this.capabilities = [
|
|
@@ -46,7 +47,7 @@ class BleFmAdapter extends adapter_1.default {
|
|
|
46
47
|
getSupportedCyclingModes() {
|
|
47
48
|
var _a;
|
|
48
49
|
const modes = [power_meter_1.default];
|
|
49
|
-
const features = (_a = this.
|
|
50
|
+
const features = (_a = this.getSensor()) === null || _a === void 0 ? void 0 : _a.features;
|
|
50
51
|
if (!features)
|
|
51
52
|
return [power_meter_1.default, antble_smarttrainer_1.default, antble_erg_1.default];
|
|
52
53
|
if (features.setPower === undefined || features.setPower)
|
|
@@ -57,7 +58,7 @@ class BleFmAdapter extends adapter_1.default {
|
|
|
57
58
|
}
|
|
58
59
|
getDefaultCyclingMode() {
|
|
59
60
|
var _a;
|
|
60
|
-
const features = (_a = this.
|
|
61
|
+
const features = (_a = this.getSensor()) === null || _a === void 0 ? void 0 : _a.features;
|
|
61
62
|
if (!features)
|
|
62
63
|
return new antble_smarttrainer_1.default(this);
|
|
63
64
|
if (features.setSlope === undefined || features.setSlope)
|
|
@@ -117,15 +118,16 @@ class BleFmAdapter extends adapter_1.default {
|
|
|
117
118
|
}
|
|
118
119
|
initControl(_startProps) {
|
|
119
120
|
return __awaiter(this, void 0, void 0, function* () {
|
|
121
|
+
if (!this.isStarting())
|
|
122
|
+
return;
|
|
120
123
|
this.setConstants();
|
|
121
124
|
yield this.establishControl();
|
|
122
|
-
this.setConstants();
|
|
123
125
|
yield this.sendInitialRequest();
|
|
124
126
|
});
|
|
125
127
|
}
|
|
126
128
|
setConstants() {
|
|
127
129
|
const mode = this.getCyclingMode();
|
|
128
|
-
const sensor = this.
|
|
130
|
+
const sensor = this.getSensor();
|
|
129
131
|
if (mode === null || mode === void 0 ? void 0 : mode.getSetting('bikeType')) {
|
|
130
132
|
const bikeType = mode.getSetting('bikeType').toLowerCase();
|
|
131
133
|
sensor.setCrr(consts_1.cRR);
|
|
@@ -146,38 +148,30 @@ class BleFmAdapter extends adapter_1.default {
|
|
|
146
148
|
return __awaiter(this, void 0, void 0, function* () {
|
|
147
149
|
if (!this.isStarting())
|
|
148
150
|
return false;
|
|
149
|
-
let
|
|
150
|
-
let
|
|
151
|
-
const sensor = this.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
151
|
+
let hasControl = false;
|
|
152
|
+
let tryCnt = 0;
|
|
153
|
+
const sensor = this.getSensor();
|
|
154
|
+
return new Promise((resolve) => {
|
|
155
|
+
this.startTask.notifyOnStop(() => {
|
|
156
|
+
resolve(false);
|
|
157
|
+
});
|
|
158
|
+
const waitUntilControl = () => __awaiter(this, void 0, void 0, function* () {
|
|
159
|
+
while (!hasControl && this.isStarting()) {
|
|
160
|
+
if (tryCnt++ === 0) {
|
|
161
|
+
this.logEvent({ message: 'requesting control', device: this.getName(), interface: this.getInterface() });
|
|
159
162
|
}
|
|
160
|
-
|
|
163
|
+
hasControl = yield sensor.requestControl();
|
|
161
164
|
if (hasControl) {
|
|
162
|
-
|
|
163
|
-
resolve(
|
|
165
|
+
this.logEvent({ message: 'control granted', device: this.getName(), interface: this.getInterface() });
|
|
166
|
+
resolve(this.isStarting());
|
|
164
167
|
}
|
|
165
|
-
else
|
|
166
|
-
|
|
167
|
-
clearInterval(iv);
|
|
168
|
+
else {
|
|
169
|
+
yield (0, utils_1.sleep)(this.requestControlRetryDelay);
|
|
168
170
|
}
|
|
169
|
-
}
|
|
171
|
+
}
|
|
170
172
|
});
|
|
171
|
-
|
|
172
|
-
};
|
|
173
|
-
waitTask = new task_1.InteruptableTask(wait(), {
|
|
174
|
-
errorOnTimeout: false,
|
|
175
|
-
timeout: 10000
|
|
173
|
+
waitUntilControl();
|
|
176
174
|
});
|
|
177
|
-
const hasControl = yield waitTask.run();
|
|
178
|
-
clearInterval(iv);
|
|
179
|
-
if (!hasControl && this.isStarting())
|
|
180
|
-
throw new Error('could not establish control');
|
|
181
175
|
});
|
|
182
176
|
}
|
|
183
177
|
sendInitialRequest() {
|
|
@@ -187,23 +181,33 @@ class BleFmAdapter extends adapter_1.default {
|
|
|
187
181
|
});
|
|
188
182
|
}
|
|
189
183
|
checkCapabilities() {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
var _a, _b, _c;
|
|
186
|
+
const before = this.capabilities.join(',');
|
|
187
|
+
const sensor = this.getSensor();
|
|
188
|
+
if (!sensor.features) {
|
|
189
|
+
try {
|
|
190
|
+
yield sensor.getFitnessMachineFeatures();
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
this.logEvent({ message: 'error getting fitness machine features', device: this.getName(), interface: this.getInterface(), error: err });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (((_a = sensor.features) === null || _a === void 0 ? void 0 : _a.heartrate) && !this.hasCapability(types_1.IncyclistCapability.HeartRate)) {
|
|
197
|
+
this.capabilities.push(types_1.IncyclistCapability.HeartRate);
|
|
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);
|
|
204
|
+
}
|
|
205
|
+
const after = this.capabilities.join(',');
|
|
206
|
+
if (before !== after) {
|
|
207
|
+
this.logEvent({ message: 'device capabilities updated', name: this.getSettings().name, interface: this.getSettings().interface, capabilities: this.capabilities });
|
|
208
|
+
this.emit('device-info', this.getSettings(), { capabilities: this.capabilities });
|
|
209
|
+
}
|
|
210
|
+
});
|
|
207
211
|
}
|
|
208
212
|
sendUpdate(request_1) {
|
|
209
213
|
return __awaiter(this, arguments, void 0, function* (request, enforced = false) {
|
|
@@ -212,7 +216,7 @@ class BleFmAdapter extends adapter_1.default {
|
|
|
212
216
|
try {
|
|
213
217
|
const update = this.getCyclingMode().sendBikeUpdate(request);
|
|
214
218
|
this.logEvent({ message: 'send bike update requested', profile: this.getProfile(), update, request });
|
|
215
|
-
const device = this.
|
|
219
|
+
const device = this.getSensor();
|
|
216
220
|
if (update.slope !== undefined) {
|
|
217
221
|
yield device.setSlope(update.slope);
|
|
218
222
|
}
|
package/lib/ble/fm/comms.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BleProtocol, BleWriteProps, IBlePeripheralConnector } from "../types";
|
|
2
2
|
import { IndoorBikeData, IndoorBikeFeatures } from "./types";
|
|
3
|
-
import { BleComms } from "../base/
|
|
3
|
+
import { BleComms } from "../base/comms";
|
|
4
4
|
import { LegacyProfile } from "../../antv2/types";
|
|
5
5
|
export default class BleFitnessMachineDevice extends BleComms {
|
|
6
6
|
static protocol: BleProtocol;
|
package/lib/ble/fm/comms.js
CHANGED
|
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const consts_1 = require("../consts");
|
|
13
|
-
const
|
|
13
|
+
const comms_1 = require("../base/comms");
|
|
14
14
|
const utils_1 = require("../utils");
|
|
15
15
|
const bit = (nr) => (1 << nr);
|
|
16
16
|
const IndoorBikeDataFlag = {
|
|
@@ -66,7 +66,7 @@ const TargetSettingFeatureFlag = {
|
|
|
66
66
|
SpinDownControlSupported: bit(15),
|
|
67
67
|
TargetedCadenceConfigurationSupported: bit(16)
|
|
68
68
|
};
|
|
69
|
-
class BleFitnessMachineDevice extends
|
|
69
|
+
class BleFitnessMachineDevice extends comms_1.BleComms {
|
|
70
70
|
constructor(props) {
|
|
71
71
|
super(props);
|
|
72
72
|
this.features = undefined;
|
|
@@ -92,7 +92,7 @@ class BleFitnessMachineDevice extends sensor_1.BleComms {
|
|
|
92
92
|
subscribeWriteResponse(cuuid) {
|
|
93
93
|
return __awaiter(this, void 0, void 0, function* () {
|
|
94
94
|
this.logEvent({ message: 'subscribe to CP response', characteristics: cuuid });
|
|
95
|
-
const connector = this.
|
|
95
|
+
const connector = this.ble.peripheralCache.getConnector(this.peripheral);
|
|
96
96
|
const isAlreadySubscribed = connector.isSubscribed(cuuid);
|
|
97
97
|
if (!isAlreadySubscribed) {
|
|
98
98
|
connector.removeAllListeners(cuuid);
|
package/lib/ble/fm/sensor.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export default class BleFitnessMachineDevice extends TBleSensor {
|
|
|
34
34
|
protected parseHrm(_data: Uint8Array): IndoorBikeData;
|
|
35
35
|
protected parseIndoorBikeData(_data: Uint8Array): IndoorBikeData;
|
|
36
36
|
protected parseFitnessMachineStatus(_data: Uint8Array): IndoorBikeData;
|
|
37
|
-
|
|
37
|
+
getFitnessMachineFeatures(): Promise<IndoorBikeFeatures | undefined>;
|
|
38
38
|
protected writeFtmsMessage(requestedOpCode: any, data: any, props?: BleWriteProps): Promise<number>;
|
|
39
39
|
setTargetInclination(inclination: number): Promise<boolean>;
|
|
40
40
|
setIndoorBikeSimulation(windSpeed: number, gradient: number, crr: number, cw: number): Promise<boolean>;
|
package/lib/ble/fm/sensor.js
CHANGED
|
@@ -100,8 +100,6 @@ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
|
|
|
100
100
|
this.logEvent({ message: 'setTargetPower', power, skip: (this.data.targetPower !== undefined && this.data.targetPower === power) });
|
|
101
101
|
if (this.data.targetPower !== undefined && this.data.targetPower === power)
|
|
102
102
|
return true;
|
|
103
|
-
if (!this.hasControl)
|
|
104
|
-
return;
|
|
105
103
|
const hasControl = yield this.requestControl();
|
|
106
104
|
if (!hasControl) {
|
|
107
105
|
this.logEvent({ message: 'setTargetPower failed', reason: 'control is disabled' });
|
|
@@ -111,15 +109,15 @@ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
|
|
|
111
109
|
data.writeUInt8(5, 0);
|
|
112
110
|
data.writeInt16LE(Math.round(power), 1);
|
|
113
111
|
const res = yield this.writeFtmsMessage(5, data);
|
|
112
|
+
if (res === 5) {
|
|
113
|
+
this.hasControl = false;
|
|
114
|
+
}
|
|
114
115
|
return (res === 1);
|
|
115
116
|
});
|
|
116
117
|
}
|
|
117
118
|
setSlope(slope) {
|
|
118
119
|
return __awaiter(this, void 0, void 0, function* () {
|
|
119
120
|
this.logEvent({ message: 'setSlope', slope });
|
|
120
|
-
const hasControl = yield this.requestControl();
|
|
121
|
-
if (!hasControl)
|
|
122
|
-
return;
|
|
123
121
|
const { windSpeed, crr, cw } = this;
|
|
124
122
|
return yield this.setIndoorBikeSimulation(windSpeed, slope, crr, cw);
|
|
125
123
|
});
|
|
@@ -331,6 +329,9 @@ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
|
|
|
331
329
|
data.writeUInt8(Math.round(crr * 10000), 5);
|
|
332
330
|
data.writeUInt8(Math.round(cw * 100), 6);
|
|
333
331
|
const res = yield this.writeFtmsMessage(17, data);
|
|
332
|
+
if (res === 5) {
|
|
333
|
+
this.hasControl = false;
|
|
334
|
+
}
|
|
334
335
|
return (res === 1);
|
|
335
336
|
});
|
|
336
337
|
}
|
package/lib/ble/hr/comm.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LegacyProfile } from '../../antv2/types';
|
|
2
|
-
import { BleComms } from '../base/
|
|
2
|
+
import { BleComms } from '../base/comms';
|
|
3
3
|
import { BleProtocol } from '../types';
|
|
4
4
|
import { HrmData } from './types';
|
|
5
5
|
export default class BleHrmDevice extends BleComms {
|
package/lib/ble/hr/comm.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const comms_1 = require("../base/comms");
|
|
4
4
|
const consts_1 = require("../consts");
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
|
-
class BleHrmDevice extends
|
|
6
|
+
class BleHrmDevice extends comms_1.BleComms {
|
|
7
7
|
constructor(props) {
|
|
8
8
|
super(props);
|
|
9
9
|
this.heartrate = undefined;
|
package/lib/ble/index.js
CHANGED
|
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "BleInterface", { enumerable: true, get: function
|
|
|
30
30
|
const factories_1 = require("./factories");
|
|
31
31
|
Object.defineProperty(exports, "BleInterfaceFactory", { enumerable: true, get: function () { return factories_1.BleMultiTransportInterfaceFactory; } });
|
|
32
32
|
Object.defineProperty(exports, "BleAdapterFactory", { enumerable: true, get: function () { return factories_1.BleAdapterFactory; } });
|
|
33
|
+
const csc_1 = require("./csc");
|
|
33
34
|
['ble', 'wifi'].forEach(i => {
|
|
34
35
|
const af = factories_1.BleAdapterFactory.getInstance(i);
|
|
35
36
|
af.register('hr', hr_1.BleHrmAdapter, hr_1.BleHrmComms);
|
|
@@ -37,6 +38,7 @@ Object.defineProperty(exports, "BleAdapterFactory", { enumerable: true, get: fun
|
|
|
37
38
|
af.register('fm', fm_1.BleFmAdapter, fm_1.BleFmComms);
|
|
38
39
|
af.register('wahoo', wahoo_1.BleWahooAdapter, wahoo_1.BleWahooComms);
|
|
39
40
|
af.register('tacx', tacx_1.BleTacxAdapter, tacx_1.BleTacxComms);
|
|
41
|
+
af.register('csc', csc_1.BleCSCAdapter, csc_1.BleCyclingSpeedCadenceDevice);
|
|
40
42
|
});
|
|
41
43
|
factories_1.BleMultiTransportInterfaceFactory.register('ble', interface_1.BleInterfaceFactory);
|
|
42
44
|
__exportStar(require("./utils"), exports);
|
|
@@ -9,5 +9,5 @@ export default class BleTacxAdapter extends BleFmAdapter {
|
|
|
9
9
|
updateSensor(peripheral: IBlePeripheral): void;
|
|
10
10
|
getProfile(): LegacyProfile;
|
|
11
11
|
protected initControl(props?: BleStartProperties): Promise<void>;
|
|
12
|
-
protected checkCapabilities(): void
|
|
12
|
+
protected checkCapabilities(): Promise<void>;
|
|
13
13
|
}
|
package/lib/ble/tacx/adapter.js
CHANGED
|
@@ -41,7 +41,7 @@ class BleTacxAdapter extends fm_1.BleFmAdapter {
|
|
|
41
41
|
initControl(props) {
|
|
42
42
|
return __awaiter(this, void 0, void 0, function* () {
|
|
43
43
|
var _a;
|
|
44
|
-
const sensor = this.
|
|
44
|
+
const sensor = this.getSensor();
|
|
45
45
|
const { user, wheelDiameter, gearRatio, bikeWeight = consts_1.DEFAULT_BIKE_WEIGHT } = props || {};
|
|
46
46
|
const userWeight = ((_a = user === null || user === void 0 ? void 0 : user.weight) !== null && _a !== void 0 ? _a : consts_1.DEFAULT_USER_WEIGHT);
|
|
47
47
|
sensor.sendTrackResistance(0.0);
|
|
@@ -51,15 +51,17 @@ class BleTacxAdapter extends fm_1.BleFmAdapter {
|
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
53
|
checkCapabilities() {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
const before = this.capabilities.join(',');
|
|
56
|
+
const sensor = this.getSensor();
|
|
57
|
+
if (sensor.features && sensor.features.heartrate && !this.hasCapability(types_1.IncyclistCapability.HeartRate)) {
|
|
58
|
+
this.capabilities.push(types_1.IncyclistCapability.HeartRate);
|
|
59
|
+
}
|
|
60
|
+
const after = this.capabilities.join(',');
|
|
61
|
+
if (before !== after) {
|
|
62
|
+
this.emit('device-info', this.getSettings(), { capabilities: this.capabilities });
|
|
63
|
+
}
|
|
64
|
+
});
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
BleTacxAdapter.INCYCLIST_PROFILE_NAME = 'Smart Trainer';
|
package/lib/ble/tacx/comms.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LegacyProfile } from "../../antv2/types";
|
|
2
2
|
import { CrankData } from "../cp";
|
|
3
3
|
import { IndoorBikeData } from "../fm";
|
|
4
|
-
import BleFitnessMachineDevice from "../fm/
|
|
4
|
+
import BleFitnessMachineDevice from "../fm/comms";
|
|
5
5
|
import { BleProtocol, IBlePeripheralConnector } from "../types";
|
|
6
6
|
import { BleFeBikeData } from "./types";
|
|
7
7
|
export default class TacxAdvancedFitnessMachineDevice extends BleFitnessMachineDevice {
|
package/lib/ble/tacx/comms.js
CHANGED
|
@@ -13,7 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
const consts_1 = require("../consts");
|
|
16
|
-
const
|
|
16
|
+
const comms_1 = __importDefault(require("../fm/comms"));
|
|
17
17
|
const utils_1 = require("../utils");
|
|
18
18
|
var ANTMessages;
|
|
19
19
|
(function (ANTMessages) {
|
|
@@ -37,7 +37,7 @@ const PROFILE_ID = 'Tacx SmartTrainer';
|
|
|
37
37
|
const SYNC_BYTE = 0xA4;
|
|
38
38
|
const DEFAULT_CHANNEL = 5;
|
|
39
39
|
const ACKNOWLEDGED_DATA = 0x4F;
|
|
40
|
-
class TacxAdvancedFitnessMachineDevice extends
|
|
40
|
+
class TacxAdvancedFitnessMachineDevice extends comms_1.default {
|
|
41
41
|
constructor(props) {
|
|
42
42
|
super(props);
|
|
43
43
|
this.prevCrankData = undefined;
|
package/lib/ble/tacx/sensor.js
CHANGED
|
@@ -43,7 +43,7 @@ class TacxAdvancedFitnessMachineDevice extends sensor_1.default {
|
|
|
43
43
|
}
|
|
44
44
|
this.messageCnt++;
|
|
45
45
|
try {
|
|
46
|
-
const uuid = characteristic.
|
|
46
|
+
const uuid = (0, utils_1.beautifyUUID)(characteristic).toLowerCase();
|
|
47
47
|
let res = undefined;
|
|
48
48
|
if (uuid && (0, utils_1.matches)(uuid, this.tacxRx)) {
|
|
49
49
|
res = this.parseFECMessage(data);
|
|
@@ -452,8 +452,14 @@ class TacxAdvancedFitnessMachineDevice extends sensor_1.default {
|
|
|
452
452
|
sendMessage(message) {
|
|
453
453
|
return __awaiter(this, void 0, void 0, function* () {
|
|
454
454
|
this.logEvent({ message: 'write', characteristic: this.tacxTx, data: message.toString('hex') });
|
|
455
|
-
|
|
456
|
-
|
|
455
|
+
try {
|
|
456
|
+
yield this.write(this.tacxTx, message, { withoutResponse: true });
|
|
457
|
+
return true;
|
|
458
|
+
}
|
|
459
|
+
catch (err) {
|
|
460
|
+
this.logEvent({ message: 'write failed', characteristic: this.tacxTx, reason: err.message });
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
457
463
|
});
|
|
458
464
|
}
|
|
459
465
|
sendUserConfiguration(userWeight, bikeWeight, wheelDiameter, gearRatio) {
|
package/lib/ble/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import EventEmitter from "events";
|
|
2
2
|
import { EventLogger } from "gd-eventlog";
|
|
3
3
|
import { DeviceProperties, DeviceSettings, DeviceStartProperties, IncyclistInterface, IncyclistScanProps, InterfaceProps } from "../types";
|
|
4
|
-
export type BleProtocol = 'hr' | 'fm' | 'cp' | 'tacx' | 'wahoo' | 'elite';
|
|
4
|
+
export type BleProtocol = 'hr' | 'fm' | 'cp' | 'tacx' | 'wahoo' | 'elite' | 'csc';
|
|
5
5
|
export type BleInterfaceState = 'unknown' | 'resetting' | 'unsupported' | 'unauthorized' | 'poweredOff' | 'poweredOn';
|
|
6
6
|
export interface BleBinding extends EventEmitter {
|
|
7
7
|
startScanning(serviceUUIDs?: string[], allowDuplicates?: boolean, callback?: (error?: Error) => void): void;
|
|
@@ -13,11 +13,17 @@ export interface BleBinding extends EventEmitter {
|
|
|
13
13
|
state: BleInterfaceState;
|
|
14
14
|
on(eventName: string | symbol, listener: (...args: any[]) => void): this;
|
|
15
15
|
}
|
|
16
|
+
export interface BleRawAdvertisement {
|
|
17
|
+
address?: string;
|
|
18
|
+
localName?: string;
|
|
19
|
+
serviceUuids?: string[];
|
|
20
|
+
rssi?: number;
|
|
21
|
+
}
|
|
16
22
|
export interface BleRawPeripheral extends EventEmitter {
|
|
17
23
|
id?: string;
|
|
18
24
|
address?: string;
|
|
19
25
|
name?: string;
|
|
20
|
-
services: [];
|
|
26
|
+
services: any[];
|
|
21
27
|
advertisement: any;
|
|
22
28
|
state: string;
|
|
23
29
|
connectAsync(): Promise<void>;
|
package/lib/ble/utils.d.ts
CHANGED
|
@@ -19,4 +19,5 @@ export declare const beautifyUUID: (str: string, withX?: boolean) => string;
|
|
|
19
19
|
export declare const fullUUID: (str: string) => string;
|
|
20
20
|
export declare const propertyVal: (properties: BleProperty[]) => number;
|
|
21
21
|
export declare const propertyFromVal: (val: number) => BleProperty[];
|
|
22
|
+
export declare const bit: (nr: any) => number;
|
|
22
23
|
export {};
|
package/lib/ble/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.propertyFromVal = exports.propertyVal = exports.fullUUID = exports.beautifyUUID = exports.parseUUID = void 0;
|
|
3
|
+
exports.bit = exports.propertyFromVal = exports.propertyVal = exports.fullUUID = exports.beautifyUUID = exports.parseUUID = void 0;
|
|
4
4
|
exports.mapLegacyProfile = mapLegacyProfile;
|
|
5
5
|
exports.uuid = uuid;
|
|
6
6
|
exports.matches = matches;
|
|
@@ -138,3 +138,7 @@ const propertyFromVal = (val) => {
|
|
|
138
138
|
return res;
|
|
139
139
|
};
|
|
140
140
|
exports.propertyFromVal = propertyFromVal;
|
|
141
|
+
const bit = (nr) => {
|
|
142
|
+
return (1 << nr);
|
|
143
|
+
};
|
|
144
|
+
exports.bit = bit;
|
package/lib/ble/wahoo/adapter.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
2
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
13
|
};
|
|
@@ -28,6 +37,11 @@ class BleWahooAdapter extends fm_1.BleFmAdapter {
|
|
|
28
37
|
updateSensor(peripheral) {
|
|
29
38
|
this.device = new sensor_1.default(peripheral, { logger: this.logger });
|
|
30
39
|
}
|
|
40
|
+
checkCapabilities() {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
this.logEvent({ message: 'device capabilities updated', name: this.getSettings().name, interface: this.getSettings().interface, capabilities: this.capabilities });
|
|
43
|
+
});
|
|
44
|
+
}
|
|
31
45
|
}
|
|
32
46
|
BleWahooAdapter.INCYCLIST_PROFILE_NAME = 'Smart Trainer';
|
|
33
47
|
exports.default = BleWahooAdapter;
|
package/lib/ble/wahoo/comms.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LegacyProfile } from "../../antv2/types";
|
|
2
2
|
import { CrankData } from "../cp";
|
|
3
3
|
import { IndoorBikeData } from "../fm";
|
|
4
|
-
import BleFitnessMachineDevice from "../fm/
|
|
4
|
+
import BleFitnessMachineDevice from "../fm/comms";
|
|
5
5
|
import { BleProtocol, BleWriteProps, IBlePeripheralConnector } from "../types";
|
|
6
6
|
export declare const enum OpCode {
|
|
7
7
|
unlock = 32,
|
package/lib/ble/wahoo/comms.js
CHANGED
|
@@ -15,10 +15,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
const _1 = require(".");
|
|
16
16
|
const consts_1 = require("../../base/consts");
|
|
17
17
|
const consts_2 = require("../consts");
|
|
18
|
-
const
|
|
18
|
+
const comms_1 = __importDefault(require("../fm/comms"));
|
|
19
19
|
const utils_1 = require("../utils");
|
|
20
20
|
const ErgWriteDelay = 2000;
|
|
21
|
-
class BleWahooDevice extends
|
|
21
|
+
class BleWahooDevice extends comms_1.default {
|
|
22
22
|
constructor(props) {
|
|
23
23
|
super(props);
|
|
24
24
|
this.prevCrankData = undefined;
|
package/lib/ble/wahoo/sensor.js
CHANGED
|
@@ -43,11 +43,8 @@ class BleWahooDevice extends sensor_1.default {
|
|
|
43
43
|
return [consts_2.INDOOR_BIKE_DATA, consts_2.FTMS_STATUS, consts_2.CSP_MEASUREMENT, consts_2.HR_MEASUREMENT];
|
|
44
44
|
}
|
|
45
45
|
onData(characteristic, data) {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
return false;
|
|
49
|
-
const uuid = characteristic.toLowerCase();
|
|
50
|
-
let res = undefined;
|
|
46
|
+
const uuid = (0, utils_1.beautifyUUID)(characteristic).toLowerCase();
|
|
47
|
+
let res;
|
|
51
48
|
switch (uuid) {
|
|
52
49
|
case consts_2.CSP_MEASUREMENT:
|
|
53
50
|
res = this.parsePower(data);
|
|
@@ -62,7 +59,7 @@ class BleWahooDevice extends sensor_1.default {
|
|
|
62
59
|
res = this.parseFitnessMachineStatus(data);
|
|
63
60
|
break;
|
|
64
61
|
default:
|
|
65
|
-
this.logEvent({ message: 'data', uuid, data: data.toString('hex') });
|
|
62
|
+
this.logEvent({ message: 'data', uuid, data: Buffer.from(data).toString('hex') });
|
|
66
63
|
break;
|
|
67
64
|
}
|
|
68
65
|
if (res) {
|
|
@@ -29,6 +29,7 @@ export default class DirectConnectInterface extends EventEmitter implements IBle
|
|
|
29
29
|
protected connected: boolean;
|
|
30
30
|
static getInstance(props?: InterfaceProps): DirectConnectInterface;
|
|
31
31
|
constructor(props: InterfaceProps);
|
|
32
|
+
setProps(props: InterfaceProps): void;
|
|
32
33
|
createPeripheral(announcement: MulticastDnsAnnouncement): IBlePeripheral;
|
|
33
34
|
createDeviceSetting(service: MulticastDnsAnnouncement): BleDeviceSettings;
|
|
34
35
|
createPeripheralFromSettings(settings: DeviceSettings): IBlePeripheral;
|
|
@@ -27,6 +27,7 @@ class DirectConnectInterface extends events_1.default {
|
|
|
27
27
|
if (DirectConnectInterface._instance === undefined)
|
|
28
28
|
DirectConnectInterface._instance = new DirectConnectInterface(props);
|
|
29
29
|
else {
|
|
30
|
+
DirectConnectInterface._instance.setProps(props);
|
|
30
31
|
if (props.binding) {
|
|
31
32
|
DirectConnectInterface._instance.setBinding(props.binding);
|
|
32
33
|
}
|
|
@@ -54,9 +55,13 @@ class DirectConnectInterface extends events_1.default {
|
|
|
54
55
|
}
|
|
55
56
|
this.internalEvents = new events_1.default();
|
|
56
57
|
this.instance = ++instanceId;
|
|
57
|
-
|
|
58
|
+
const { enabled } = props;
|
|
59
|
+
if (this.binding && (enabled !== null && enabled !== void 0 ? enabled : false))
|
|
58
60
|
this.autoConnect();
|
|
59
61
|
}
|
|
62
|
+
setProps(props) {
|
|
63
|
+
this.props = props;
|
|
64
|
+
}
|
|
60
65
|
createPeripheral(announcement) {
|
|
61
66
|
return peripheral_1.DirectConnectPeripheral.create(announcement);
|
|
62
67
|
}
|
|
@@ -83,7 +88,7 @@ class DirectConnectInterface extends events_1.default {
|
|
|
83
88
|
setBinding(binding) {
|
|
84
89
|
const prev = this.binding;
|
|
85
90
|
this.binding = binding;
|
|
86
|
-
if (!prev)
|
|
91
|
+
if (!prev && this.props.enabled)
|
|
87
92
|
this.autoConnect();
|
|
88
93
|
}
|
|
89
94
|
getBinding() {
|
|
@@ -238,10 +243,10 @@ class DirectConnectInterface extends events_1.default {
|
|
|
238
243
|
this.services[idx] = { ts: Date.now(), service };
|
|
239
244
|
}
|
|
240
245
|
else {
|
|
241
|
-
this.logEvent({ message: 'device announced', device: service.name, announcement: service, source });
|
|
242
246
|
this.services.push({ ts: Date.now(), service });
|
|
243
|
-
if (
|
|
247
|
+
if (!((_a = service.serviceUUIDs) === null || _a === void 0 ? void 0 : _a.length))
|
|
244
248
|
return;
|
|
249
|
+
this.logEvent({ message: 'device announced', device: service.name, announcement: service, source });
|
|
245
250
|
this.emitDevice(service);
|
|
246
251
|
(_b = this.matching) === null || _b === void 0 ? void 0 : _b.push(service.name);
|
|
247
252
|
}
|
|
@@ -21,24 +21,24 @@ export declare class DirectConnectPeripheral implements IBlePeripheral {
|
|
|
21
21
|
constructor(announcement: MulticastDnsAnnouncement);
|
|
22
22
|
get services(): BleService[];
|
|
23
23
|
connect(): Promise<boolean>;
|
|
24
|
-
disconnect(): Promise<boolean>;
|
|
24
|
+
disconnect(connectionLost?: boolean): Promise<boolean>;
|
|
25
25
|
isConnected(): boolean;
|
|
26
26
|
isConnecting(): boolean;
|
|
27
27
|
onDisconnect(callback: () => void): void;
|
|
28
28
|
discoverServices(): Promise<string[]>;
|
|
29
29
|
discoverCharacteristics(serviceUUID: string): Promise<BleCharacteristic[]>;
|
|
30
|
-
subscribe(characteristicUUID: string, callback
|
|
30
|
+
subscribe(characteristicUUID: string, callback?: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
|
|
31
31
|
unsubscribe(characteristicUUID: string): Promise<boolean>;
|
|
32
32
|
subscribeAll(callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
|
|
33
33
|
subscribeSelected(characteristics: string[], callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
|
|
34
|
-
unsubscribeAll(): Promise<
|
|
34
|
+
unsubscribeAll(connectionLost?: boolean): Promise<void>;
|
|
35
35
|
read(characteristicUUID: string): Promise<Buffer>;
|
|
36
36
|
write(characteristicUUID: string, data: Buffer, options?: BleWriteProps): Promise<Buffer>;
|
|
37
37
|
protected startConnection(): Promise<boolean>;
|
|
38
38
|
protected onPortError(err: Error): void;
|
|
39
39
|
protected onPortClose(): Promise<void>;
|
|
40
40
|
protected getPath(): string;
|
|
41
|
-
protected stopConnection(): Promise<boolean>;
|
|
41
|
+
protected stopConnection(connectionLost?: boolean): Promise<boolean>;
|
|
42
42
|
protected getNextSeqNo(): number;
|
|
43
43
|
protected send(seqNo: number, data: Buffer): Promise<Buffer>;
|
|
44
44
|
protected getNextMessage(data: Buffer): Buffer;
|