incyclist-devices 2.0.0-beta.1 → 2.0.1
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 +238 -0
- package/lib/adapters.d.ts +1 -0
- package/lib/adapters.js +19 -0
- package/lib/antv2/adapter-factory.d.ts +8 -7
- package/lib/antv2/adapter-factory.js +4 -2
- package/lib/antv2/adapter.d.ts +3 -2
- package/lib/antv2/adapter.js +15 -4
- package/lib/antv2/ant-interface.d.ts +6 -2
- package/lib/antv2/ant-interface.js +27 -21
- package/lib/antv2/binding.d.ts +1 -1
- package/lib/antv2/binding.js +1 -1
- package/lib/antv2/fe/adapter.d.ts +12 -9
- package/lib/antv2/fe/adapter.js +67 -27
- package/lib/antv2/hr/adapter.d.ts +6 -5
- package/lib/antv2/hr/adapter.js +19 -16
- package/lib/antv2/index.d.ts +2 -2
- package/lib/antv2/pwr/adapter.d.ts +6 -4
- package/lib/antv2/pwr/adapter.js +24 -16
- package/lib/antv2/sensor-factory.d.ts +2 -2
- package/lib/antv2/types.d.ts +5 -2
- package/lib/antv2/types.js +3 -0
- package/lib/antv2/utils.d.ts +3 -0
- package/lib/antv2/utils.js +12 -1
- package/lib/base/adpater.d.ts +14 -2
- package/lib/base/adpater.js +43 -4
- package/lib/ble/adapter-factory.d.ts +18 -16
- package/lib/ble/adapter-factory.js +54 -45
- package/lib/ble/base/adapter.d.ts +53 -0
- package/lib/ble/{adapter.js → base/adapter.js} +111 -9
- package/lib/ble/base/comms-utils.d.ts +7 -0
- package/lib/ble/base/comms-utils.js +91 -0
- package/lib/ble/{ble-comms.d.ts → base/comms.d.ts} +27 -17
- package/lib/ble/{ble-comms.js → base/comms.js} +179 -53
- package/lib/ble/bindings/index.d.ts +2 -0
- package/lib/ble/bindings/index.js +8 -0
- package/lib/ble/bindings/linux.d.ts +15 -0
- package/lib/ble/bindings/linux.js +39 -0
- package/lib/ble/bindings/mock.d.ts +9 -0
- package/lib/ble/bindings/mock.js +108 -0
- package/lib/ble/bindings/types.d.ts +57 -0
- package/lib/ble/bindings/types.js +96 -0
- package/lib/ble/ble-interface.d.ts +34 -46
- package/lib/ble/ble-interface.js +242 -345
- package/lib/ble/ble-peripheral.d.ts +4 -2
- package/lib/ble/ble-peripheral.js +39 -8
- package/lib/ble/consts.d.ts +1 -0
- package/lib/ble/consts.js +2 -1
- package/lib/ble/cp/adapter.d.ts +1 -2
- package/lib/ble/cp/adapter.js +2 -15
- package/lib/ble/cp/comm.d.ts +8 -5
- package/lib/ble/cp/comm.js +12 -27
- package/lib/ble/elite/adapter.d.ts +1 -2
- package/lib/ble/elite/adapter.js +12 -19
- package/lib/ble/elite/comms.d.ts +8 -4
- package/lib/ble/elite/comms.js +12 -25
- package/lib/ble/fm/adapter.d.ts +3 -2
- package/lib/ble/fm/adapter.js +129 -70
- package/lib/ble/fm/comms.d.ts +8 -8
- package/lib/ble/fm/comms.js +33 -55
- package/lib/ble/fm/types.d.ts +5 -0
- package/lib/ble/hr/adapter.d.ts +1 -4
- package/lib/ble/hr/adapter.js +1 -18
- package/lib/ble/hr/comm.d.ts +6 -2
- package/lib/ble/hr/comm.js +6 -2
- package/lib/ble/hr/mock.d.ts +7 -0
- package/lib/ble/hr/mock.js +47 -0
- package/lib/ble/index.d.ts +2 -1
- package/lib/ble/index.js +5 -5
- package/lib/ble/peripheral-cache.d.ts +43 -0
- package/lib/ble/peripheral-cache.js +107 -0
- package/lib/ble/tacx/adapter.d.ts +1 -1
- package/lib/ble/tacx/adapter.js +20 -14
- package/lib/ble/tacx/comms.d.ts +6 -6
- package/lib/ble/tacx/comms.js +10 -43
- package/lib/ble/types.d.ts +54 -27
- package/lib/ble/types.js +0 -17
- package/lib/ble/utils.d.ts +15 -5
- package/lib/ble/utils.js +25 -66
- package/lib/ble/wahoo/adapter.d.ts +1 -1
- package/lib/ble/wahoo/adapter.js +12 -10
- package/lib/ble/wahoo/comms.d.ts +7 -6
- package/lib/ble/wahoo/comms.js +15 -17
- package/lib/index.d.ts +10 -7
- package/lib/index.js +21 -25
- package/lib/interfaces.d.ts +2 -1
- package/lib/interfaces.js +4 -0
- package/lib/modes/power-base.js +4 -0
- package/lib/serial/adapter.d.ts +5 -0
- package/lib/serial/adapter.js +19 -0
- package/lib/serial/bindings/tcp.d.ts +2 -1
- package/lib/serial/bindings/tcp.js +19 -5
- package/lib/serial/daum/DaumAdapter.d.ts +1 -1
- package/lib/serial/daum/DaumAdapter.js +16 -10
- package/lib/serial/daum/premium/adapter.d.ts +1 -0
- package/lib/serial/daum/premium/adapter.js +9 -2
- package/lib/serial/daum/premium/comms.js +10 -3
- package/lib/serial/daum/premium/mock.js +0 -1
- package/lib/serial/index.d.ts +3 -3
- package/lib/serial/index.js +2 -2
- package/lib/serial/kettler/ergo-racer/adapter.d.ts +1 -4
- package/lib/serial/kettler/ergo-racer/adapter.js +15 -39
- package/lib/serial/serial-interface.d.ts +3 -1
- package/lib/serial/serial-interface.js +43 -17
- package/lib/simulator/Simulator.d.ts +2 -0
- package/lib/simulator/Simulator.js +8 -5
- package/lib/types/adapter.d.ts +10 -3
- package/lib/types/device.d.ts +3 -0
- package/lib/types/interface.d.ts +7 -3
- package/package.json +3 -5
- package/lib/ble/adapter.d.ts +0 -41
- package/lib/ble/ble.d.ts +0 -57
- package/lib/ble/ble.js +0 -48
- package/lib/device.d.ts +0 -0
- package/lib/device.js +0 -0
package/lib/antv2/fe/adapter.js
CHANGED
|
@@ -37,13 +37,15 @@ class AntFEAdapter extends adapter_1.ControllableAntAdapter {
|
|
|
37
37
|
this.dataMsgCount = 0;
|
|
38
38
|
this.logger = new gd_eventlog_1.EventLogger('Ant+FE');
|
|
39
39
|
this.isReconnecting = false;
|
|
40
|
+
this.startProps = {};
|
|
40
41
|
this.capabilities = [
|
|
41
42
|
capabilities_1.IncyclistCapability.Power, capabilities_1.IncyclistCapability.Speed, capabilities_1.IncyclistCapability.Cadence,
|
|
42
43
|
capabilities_1.IncyclistCapability.Control
|
|
43
44
|
];
|
|
44
45
|
}
|
|
45
46
|
createSensor(settings) {
|
|
46
|
-
|
|
47
|
+
const sensor = sensor_factory_1.default.create(AntFEAdapter.ANT_PROFILE_NAME, Number(settings.deviceID));
|
|
48
|
+
return sensor;
|
|
47
49
|
}
|
|
48
50
|
getName() {
|
|
49
51
|
if (this.settings.name)
|
|
@@ -51,14 +53,20 @@ class AntFEAdapter extends adapter_1.ControllableAntAdapter {
|
|
|
51
53
|
const deviceID = this.sensor.getDeviceID();
|
|
52
54
|
return `Ant+FE ${deviceID}`;
|
|
53
55
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
getUniqueName() {
|
|
57
|
+
if (this.settings.name)
|
|
58
|
+
return this.settings.name;
|
|
59
|
+
const { DeviceID, ManId } = this.deviceData;
|
|
57
60
|
const brand = (0, utils_1.getBrand)(ManId);
|
|
58
61
|
if (brand)
|
|
59
|
-
return `${brand} FE ${DeviceID}
|
|
62
|
+
return `${brand} FE ${DeviceID}`;
|
|
60
63
|
else
|
|
61
|
-
return `${this.getName()}
|
|
64
|
+
return `${this.getName()}`;
|
|
65
|
+
}
|
|
66
|
+
getDisplayName() {
|
|
67
|
+
const { InstantaneousPower } = this.deviceData;
|
|
68
|
+
const pwrStr = InstantaneousPower ? ` (${InstantaneousPower})` : '';
|
|
69
|
+
return `${this.getUniqueName()}${pwrStr}`;
|
|
62
70
|
}
|
|
63
71
|
getSupportedCyclingModes() {
|
|
64
72
|
return [ant_fe_st_mode_1.default, ant_fe_erg_mode_1.default, ant_fe_adv_st_mode_1.default];
|
|
@@ -73,17 +81,17 @@ class AntFEAdapter extends adapter_1.ControllableAntAdapter {
|
|
|
73
81
|
});
|
|
74
82
|
return logData;
|
|
75
83
|
}
|
|
76
|
-
sendUpdate(request) {
|
|
84
|
+
sendUpdate(request, forced = false) {
|
|
77
85
|
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
-
if (this.paused || this.isReconnecting)
|
|
86
|
+
if ((this.paused || this.isReconnecting) && !forced)
|
|
87
|
+
return;
|
|
88
|
+
let isReset = request.reset && Object.keys(request).length === 1;
|
|
89
|
+
const update = isReset ? this.getCyclingMode().getBikeInitRequest() : this.getCyclingMode().sendBikeUpdate(request);
|
|
90
|
+
if (!update)
|
|
79
91
|
return;
|
|
80
|
-
const update = this.getCyclingMode().sendBikeUpdate(request);
|
|
81
92
|
this.logger.logEvent({ message: 'send bike update requested', update, request });
|
|
82
93
|
try {
|
|
83
94
|
const fe = this.sensor;
|
|
84
|
-
const isReset = (!update || update.reset || Object.keys(update).length === 0);
|
|
85
|
-
if (isReset)
|
|
86
|
-
yield fe.sendTrackResistance(0);
|
|
87
95
|
if (update.slope !== undefined) {
|
|
88
96
|
yield fe.sendTrackResistance(update.slope);
|
|
89
97
|
}
|
|
@@ -106,7 +114,7 @@ class AntFEAdapter extends adapter_1.ControllableAntAdapter {
|
|
|
106
114
|
this.dataMsgCount++;
|
|
107
115
|
this.lastDataTS = Date.now();
|
|
108
116
|
super.onDeviceData(deviceData);
|
|
109
|
-
if (!this.started || this.isStopped())
|
|
117
|
+
if (!this.started || this.isStopped() || this.paused)
|
|
110
118
|
return;
|
|
111
119
|
if (!this.ivDataTimeout && this.dataMsgCount > 0) {
|
|
112
120
|
this.startDataTimeoutCheck();
|
|
@@ -114,21 +122,23 @@ class AntFEAdapter extends adapter_1.ControllableAntAdapter {
|
|
|
114
122
|
try {
|
|
115
123
|
const logData = this.getLogData(deviceData, ['PairedDevices', 'RawData']);
|
|
116
124
|
this.logger.logEvent({ message: 'onDeviceData', data: logData });
|
|
117
|
-
if (
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
this.lastUpdate = Date.now();
|
|
124
|
-
}
|
|
125
|
-
}
|
|
125
|
+
if (!this.canSendUpdate())
|
|
126
|
+
return;
|
|
127
|
+
let incyclistData = this.mapToCycleModeData(deviceData);
|
|
128
|
+
incyclistData = this.getCyclingMode().updateData(incyclistData);
|
|
129
|
+
this.data = this.transformData(incyclistData);
|
|
130
|
+
this.emitData(this.data);
|
|
126
131
|
}
|
|
127
132
|
catch (err) {
|
|
128
133
|
this.logger.logEvent({ message: 'error', fn: 'onDeviceData()', error: err.message || err, stack: err.stack });
|
|
129
134
|
}
|
|
130
135
|
}
|
|
131
|
-
|
|
136
|
+
canSendUpdate() {
|
|
137
|
+
if (!this.hasDataListeners() || this.paused)
|
|
138
|
+
return false;
|
|
139
|
+
return super.canSendUpdate();
|
|
140
|
+
}
|
|
141
|
+
mapToCycleModeData(deviceData) {
|
|
132
142
|
const data = {
|
|
133
143
|
isPedalling: false,
|
|
134
144
|
power: 0,
|
|
@@ -169,13 +179,16 @@ class AntFEAdapter extends adapter_1.ControllableAntAdapter {
|
|
|
169
179
|
}
|
|
170
180
|
start(props) {
|
|
171
181
|
return __awaiter(this, void 0, void 0, function* () {
|
|
172
|
-
|
|
182
|
+
const wasPaused = this.paused;
|
|
183
|
+
this.paused = false;
|
|
184
|
+
if (this.started && !wasPaused) {
|
|
173
185
|
return true;
|
|
186
|
+
}
|
|
174
187
|
const connected = yield this.connect();
|
|
175
188
|
if (!connected)
|
|
176
189
|
throw new Error(`could not start device, reason:could not connect`);
|
|
177
190
|
this.startProps = props;
|
|
178
|
-
this.logEvent({ message: 'starting device
|
|
191
|
+
this.logEvent({ message: 'starting device', props, isStarted: this.started, isReconnecting: this.isReconnecting });
|
|
179
192
|
const opts = props || {};
|
|
180
193
|
const { args = {}, user = {} } = opts;
|
|
181
194
|
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -218,7 +231,7 @@ class AntFEAdapter extends adapter_1.ControllableAntAdapter {
|
|
|
218
231
|
}
|
|
219
232
|
catch (_a) { }
|
|
220
233
|
this.started = false;
|
|
221
|
-
return reject(new Error(
|
|
234
|
+
return reject(new Error('could not start device, reason:timeout'));
|
|
222
235
|
}
|
|
223
236
|
}
|
|
224
237
|
status = { userSent: false, slopeSent: false };
|
|
@@ -236,7 +249,22 @@ class AntFEAdapter extends adapter_1.ControllableAntAdapter {
|
|
|
236
249
|
const userWeight = args.userWeight || user.weight || adpater_1.DEFAULT_USER_WEIGHT;
|
|
237
250
|
const bikeWeight = args.bikeWeight || defaultBikeWeight;
|
|
238
251
|
status.userSent = status.userSent || (yield fe.sendUserConfiguration(userWeight, bikeWeight, args.wheelDiameter, args.gearRatio));
|
|
239
|
-
|
|
252
|
+
if (!status.slopeSent) {
|
|
253
|
+
const startRequest = this.getCyclingMode().getBikeInitRequest();
|
|
254
|
+
if (startRequest) {
|
|
255
|
+
if (startRequest.targetPower !== undefined && startRequest.targetPower !== null) {
|
|
256
|
+
status.slopeSent = yield fe.sendTargetPower(startRequest.targetPower);
|
|
257
|
+
}
|
|
258
|
+
else if (startRequest.slope !== undefined && startRequest.slope !== null) {
|
|
259
|
+
status.slopeSent = yield fe.sendTrackResistance(startRequest.slope);
|
|
260
|
+
}
|
|
261
|
+
else
|
|
262
|
+
status.slopeSent = true;
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
status.slopeSent = yield fe.sendTrackResistance(0.0);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
240
268
|
}
|
|
241
269
|
catch (err) {
|
|
242
270
|
this.logger.logEvent({ message: 'sending FE message error', error: err.message });
|
|
@@ -294,6 +322,18 @@ class AntFEAdapter extends adapter_1.ControllableAntAdapter {
|
|
|
294
322
|
}
|
|
295
323
|
});
|
|
296
324
|
}
|
|
325
|
+
setCyclingMode(mode, settings) {
|
|
326
|
+
const modeChange = this.cyclingMode.getName() !== mode;
|
|
327
|
+
super.setCyclingMode(mode, settings);
|
|
328
|
+
console.log('~~~ setCyclingMode', mode, modeChange, this.started, this.stopped, this.paused, this.isReconnecting, this.data);
|
|
329
|
+
if (modeChange && this.started && !this.stopped) {
|
|
330
|
+
if (this.getCyclingMode() instanceof ant_fe_erg_mode_1.default) {
|
|
331
|
+
const power = this.data.power;
|
|
332
|
+
const request = power ? { targetPower: power } : this.getCyclingMode().getBikeInitRequest();
|
|
333
|
+
this.sendUpdate(request, true);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
297
337
|
}
|
|
298
338
|
exports.default = AntFEAdapter;
|
|
299
339
|
AntFEAdapter.INCYCLIST_PROFILE_NAME = 'Smart Trainer';
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { HeartRateSensorState, ISensor } from "incyclist-ant-plus";
|
|
1
|
+
import { HeartRateSensorState, ISensor, Profile } from "incyclist-ant-plus";
|
|
2
2
|
import AntAdapter from "../adapter";
|
|
3
|
-
import { AntDeviceProperties, AntDeviceSettings } from "../types";
|
|
3
|
+
import { AntDeviceProperties, AntDeviceSettings, LegacyProfile } from "../types";
|
|
4
4
|
export default class AntHrAdapter extends AntAdapter {
|
|
5
|
-
static INCYCLIST_PROFILE_NAME:
|
|
6
|
-
static ANT_PROFILE_NAME:
|
|
5
|
+
static INCYCLIST_PROFILE_NAME: LegacyProfile;
|
|
6
|
+
static ANT_PROFILE_NAME: Profile;
|
|
7
7
|
constructor(settings: AntDeviceSettings, props?: AntDeviceProperties);
|
|
8
8
|
createSensor(settings: AntDeviceSettings): ISensor;
|
|
9
9
|
getName(): string;
|
|
10
|
+
getUniqueName(): string;
|
|
10
11
|
getDisplayName(): string;
|
|
11
12
|
onDeviceData(deviceData: HeartRateSensorState): void;
|
|
12
|
-
|
|
13
|
+
mapData(deviceData: HeartRateSensorState): void;
|
|
13
14
|
hasData(): boolean;
|
|
14
15
|
}
|
package/lib/antv2/hr/adapter.js
CHANGED
|
@@ -30,14 +30,20 @@ class AntHrAdapter extends adapter_1.default {
|
|
|
30
30
|
const deviceID = this.sensor.getDeviceID();
|
|
31
31
|
return `Ant+HR ${deviceID}`;
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
getUniqueName() {
|
|
34
|
+
if (this.settings.name)
|
|
35
|
+
return this.settings.name;
|
|
36
|
+
const { DeviceID, ManId } = this.deviceData;
|
|
36
37
|
const brand = (0, utils_1.getBrand)(ManId);
|
|
37
38
|
if (brand)
|
|
38
|
-
return `${brand}
|
|
39
|
+
return `${brand} HR ${DeviceID}`;
|
|
39
40
|
else
|
|
40
|
-
return `${this.getName()}
|
|
41
|
+
return `${this.getName()}`;
|
|
42
|
+
}
|
|
43
|
+
getDisplayName() {
|
|
44
|
+
const { ComputedHeartRate } = this.deviceData;
|
|
45
|
+
const hrmStr = ComputedHeartRate ? ` (${ComputedHeartRate})` : '';
|
|
46
|
+
return `${this.getUniqueName()}${hrmStr}`;
|
|
41
47
|
}
|
|
42
48
|
onDeviceData(deviceData) {
|
|
43
49
|
this.dataMsgCount++;
|
|
@@ -48,21 +54,18 @@ class AntHrAdapter extends adapter_1.default {
|
|
|
48
54
|
if (!this.ivDataTimeout)
|
|
49
55
|
this.startDataTimeoutCheck();
|
|
50
56
|
try {
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
this.lastUpdate = Date.now();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
57
|
+
if (!this.canSendUpdate())
|
|
58
|
+
return;
|
|
59
|
+
this.logEvent({ message: 'onDeviceData', data: deviceData });
|
|
60
|
+
this.mapData(deviceData);
|
|
61
|
+
this.emitData(this.data);
|
|
59
62
|
}
|
|
60
63
|
catch (err) {
|
|
61
64
|
}
|
|
62
65
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
mapData(deviceData) {
|
|
67
|
+
if (deviceData.ComputedHeartRate)
|
|
68
|
+
this.data.heartrate = deviceData.ComputedHeartRate;
|
|
66
69
|
}
|
|
67
70
|
hasData() {
|
|
68
71
|
return this.deviceData.ComputedHeartRate !== undefined && this.deviceData.ComputedHeartRate !== null;
|
package/lib/antv2/index.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ import AntPwrAdapter from "./pwr";
|
|
|
2
2
|
import AntFEAdapter from "./fe";
|
|
3
3
|
import AntHrAdapter from "./hr";
|
|
4
4
|
import AntAdapterFactory from "./adapter-factory";
|
|
5
|
-
import AntInterface from "./ant-interface";
|
|
5
|
+
import AntInterface, { AntInterfaceProps } from "./ant-interface";
|
|
6
6
|
import { AntDeviceSettings, AntScanProps } from "./types";
|
|
7
|
-
export { AntAdapterFactory, AntFEAdapter, AntHrAdapter, AntPwrAdapter, AntDeviceSettings, AntScanProps, AntInterface };
|
|
7
|
+
export { AntAdapterFactory, AntFEAdapter, AntHrAdapter, AntPwrAdapter, AntDeviceSettings, AntScanProps, AntInterface, AntInterfaceProps };
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import { ISensor } from "incyclist-ant-plus";
|
|
1
|
+
import { ISensor, Profile } from "incyclist-ant-plus";
|
|
2
2
|
import { ControllableAntAdapter } from "../adapter";
|
|
3
3
|
import CyclingMode, { IncyclistBikeData } from '../../modes/cycling-mode';
|
|
4
|
-
import { AntDeviceProperties, AntDeviceSettings } from "../types";
|
|
4
|
+
import { AntDeviceProperties, AntDeviceSettings, LegacyProfile } from "../types";
|
|
5
5
|
import { DeviceData } from "../../types/data";
|
|
6
6
|
export default class AntPwrAdapter extends ControllableAntAdapter {
|
|
7
|
-
static INCYCLIST_PROFILE_NAME:
|
|
8
|
-
static ANT_PROFILE_NAME:
|
|
7
|
+
static INCYCLIST_PROFILE_NAME: LegacyProfile;
|
|
8
|
+
static ANT_PROFILE_NAME: Profile;
|
|
9
9
|
protected distanceInternal?: number;
|
|
10
10
|
constructor(settings: AntDeviceSettings, props?: AntDeviceProperties);
|
|
11
11
|
createSensor(settings: AntDeviceSettings): ISensor;
|
|
12
12
|
getName(): string;
|
|
13
|
+
getUniqueName(): string;
|
|
13
14
|
getDisplayName(): string;
|
|
14
15
|
getDefaultCyclingMode(): CyclingMode;
|
|
15
16
|
getSupportedCyclingModes(): any[];
|
|
16
17
|
getLogData(data: any, excludeList: any): any;
|
|
17
18
|
onDeviceData(deviceData: any): void;
|
|
19
|
+
canSendUpdate(): boolean;
|
|
18
20
|
sendUpdate(request: any): void;
|
|
19
21
|
mapData(deviceData: any): IncyclistBikeData;
|
|
20
22
|
transformData(bikeData: IncyclistBikeData): DeviceData;
|
package/lib/antv2/pwr/adapter.js
CHANGED
|
@@ -33,14 +33,20 @@ class AntPwrAdapter extends adapter_1.ControllableAntAdapter {
|
|
|
33
33
|
const deviceID = this.sensor.getDeviceID();
|
|
34
34
|
return `Ant+PWR ${deviceID}`;
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
getUniqueName() {
|
|
37
|
+
if (this.settings.name)
|
|
38
|
+
return this.settings.name;
|
|
39
|
+
const { DeviceID, ManId } = this.deviceData;
|
|
39
40
|
const brand = (0, utils_1.getBrand)(ManId);
|
|
40
41
|
if (brand)
|
|
41
|
-
return `${brand} PWR ${DeviceID}
|
|
42
|
+
return `${brand} PWR ${DeviceID}`;
|
|
42
43
|
else
|
|
43
|
-
return `${this.getName()}
|
|
44
|
+
return `${this.getName()}`;
|
|
45
|
+
}
|
|
46
|
+
getDisplayName() {
|
|
47
|
+
const { Power } = this.deviceData;
|
|
48
|
+
const pwrStr = Power ? ` (${Power})` : '';
|
|
49
|
+
return `${this.getUniqueName()}${pwrStr}`;
|
|
44
50
|
}
|
|
45
51
|
getDefaultCyclingMode() {
|
|
46
52
|
return new power_meter_1.default(this);
|
|
@@ -64,21 +70,23 @@ class AntPwrAdapter extends adapter_1.ControllableAntAdapter {
|
|
|
64
70
|
if (!this.ivDataTimeout)
|
|
65
71
|
this.startDataTimeoutCheck();
|
|
66
72
|
try {
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this.lastUpdate = Date.now();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
73
|
+
if (!this.canSendUpdate())
|
|
74
|
+
return;
|
|
75
|
+
const logData = this.getLogData(deviceData, ['PairedDevices', 'RawData']);
|
|
76
|
+
this.logger.logEvent({ message: 'onDeviceData', data: logData });
|
|
77
|
+
let incyclistData = this.mapData(deviceData);
|
|
78
|
+
incyclistData = this.getCyclingMode().updateData(incyclistData);
|
|
79
|
+
const data = this.transformData(incyclistData);
|
|
80
|
+
this.emitData(data);
|
|
78
81
|
}
|
|
79
82
|
catch (err) {
|
|
80
83
|
}
|
|
81
84
|
}
|
|
85
|
+
canSendUpdate() {
|
|
86
|
+
if (!this.hasDataListeners() || this.paused)
|
|
87
|
+
return false;
|
|
88
|
+
return super.canSendUpdate();
|
|
89
|
+
}
|
|
82
90
|
sendUpdate(request) {
|
|
83
91
|
if (this.isPaused())
|
|
84
92
|
return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ISensor } from "incyclist-ant-plus";
|
|
1
|
+
import { ISensor, Profile } from "incyclist-ant-plus";
|
|
2
2
|
export default class SensorFactory {
|
|
3
|
-
static create(profile:
|
|
3
|
+
static create(profile: Profile, deviceID?: number): ISensor;
|
|
4
4
|
static createAll(): ISensor[];
|
|
5
5
|
}
|
package/lib/antv2/types.d.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
import { Profile } from 'incyclist-ant-plus';
|
|
1
2
|
import IncyclistDevice from '../base/adpater';
|
|
2
3
|
import { DeviceProperties, DeviceSettings, IncyclistScanProps } from '../types/device';
|
|
3
4
|
export interface AntDeviceSettings extends DeviceSettings {
|
|
4
5
|
deviceID?: string;
|
|
5
|
-
profile:
|
|
6
|
+
profile: Profile | LegacyProfile;
|
|
6
7
|
protocol?: string;
|
|
7
8
|
}
|
|
9
|
+
export type LegacyProfile = 'Heartrate Monitor' | 'Power Meter' | 'Smart Trainer' | 'Speed Sensor' | 'Cadence Sensor' | 'Speed + Cadence Sensor';
|
|
10
|
+
export declare const isLegacyProfile: (o: unknown) => boolean;
|
|
8
11
|
export type DeviceFoundCallback = (device: IncyclistDevice, protocol: string) => void;
|
|
9
12
|
export type ScanFinishedCallback = (id: number) => void;
|
|
10
13
|
export interface AntScanProps extends IncyclistScanProps {
|
|
11
|
-
profiles?:
|
|
14
|
+
profiles?: Profile[];
|
|
12
15
|
id?: number;
|
|
13
16
|
onDeviceFound?: DeviceFoundCallback;
|
|
14
17
|
onScanFinished?: ScanFinishedCallback;
|
package/lib/antv2/types.js
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isLegacyProfile = void 0;
|
|
4
|
+
const isLegacyProfile = (o) => o === 'Heartrate Monitor' || o === 'Power Meter' || o === 'Smart Trainer' || o === 'Speed Sensor' || o === 'Cadence Sensor' || o === 'Speed + Cadence Sensor';
|
|
5
|
+
exports.isLegacyProfile = isLegacyProfile;
|
package/lib/antv2/utils.d.ts
CHANGED
package/lib/antv2/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getBrand = void 0;
|
|
3
|
+
exports.mapLegacyProfile = exports.getBrand = void 0;
|
|
4
4
|
const brands = [
|
|
5
5
|
'Garmin,1',
|
|
6
6
|
'garmin_fr405_antfs,2',
|
|
@@ -179,3 +179,14 @@ const getBrand = (manId) => {
|
|
|
179
179
|
return;
|
|
180
180
|
};
|
|
181
181
|
exports.getBrand = getBrand;
|
|
182
|
+
const mapLegacyProfile = (legacy) => {
|
|
183
|
+
switch (legacy) {
|
|
184
|
+
case 'Heartrate Monitor': return 'HR';
|
|
185
|
+
case 'Power Meter': return 'PWR';
|
|
186
|
+
case 'Smart Trainer': return 'FE';
|
|
187
|
+
case 'Cadence Sensor': return 'CAD';
|
|
188
|
+
case 'Speed Sensor': return 'SPD';
|
|
189
|
+
case 'Speed + Cadence Sensor': return 'SC';
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
exports.mapLegacyProfile = mapLegacyProfile;
|
package/lib/base/adpater.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { EventEmitter } from "stream";
|
|
3
2
|
import CyclingMode from "../modes/cycling-mode";
|
|
4
3
|
import { DeviceProperties, DeviceSettings } from "../types/device";
|
|
5
4
|
import { Bike, IncyclistDeviceAdapter, OnDeviceDataCallback } from '../types/adapter';
|
|
6
5
|
import { User } from "../types/user";
|
|
7
6
|
import { IncyclistCapability } from "../types/capabilities";
|
|
8
7
|
import { EventLogger } from "gd-eventlog";
|
|
8
|
+
import { DeviceData } from "../types/data";
|
|
9
|
+
import EventEmitter from "events";
|
|
9
10
|
export declare const DEFAULT_BIKE_WEIGHT = 10;
|
|
10
11
|
export declare const DEFAULT_USER_WEIGHT = 75;
|
|
11
12
|
export declare const DEFAULT_PROPS: DeviceProperties;
|
|
@@ -13,6 +14,8 @@ export default class IncyclistDevice extends EventEmitter implements IncyclistDe
|
|
|
13
14
|
onDataFn: OnDeviceDataCallback;
|
|
14
15
|
settings: DeviceSettings;
|
|
15
16
|
props: DeviceProperties;
|
|
17
|
+
lastUpdate?: number;
|
|
18
|
+
updateFrequency: number;
|
|
16
19
|
capabilities: IncyclistCapability[];
|
|
17
20
|
protected logger: EventLogger;
|
|
18
21
|
started: boolean;
|
|
@@ -22,30 +25,39 @@ export default class IncyclistDevice extends EventEmitter implements IncyclistDe
|
|
|
22
25
|
connect(): Promise<boolean>;
|
|
23
26
|
close(): Promise<boolean>;
|
|
24
27
|
check(): Promise<boolean>;
|
|
25
|
-
|
|
28
|
+
isControllable(): boolean;
|
|
29
|
+
isEqual(settings: DeviceSettings): boolean;
|
|
26
30
|
getCapabilities(): IncyclistCapability[];
|
|
27
31
|
hasCapability(capability: IncyclistCapability): boolean;
|
|
32
|
+
addCapability(capability: IncyclistCapability): void;
|
|
28
33
|
update(): void;
|
|
29
34
|
start(props?: DeviceProperties): Promise<boolean>;
|
|
30
35
|
stop(): Promise<boolean>;
|
|
31
36
|
pause(): Promise<boolean>;
|
|
32
37
|
resume(): Promise<boolean>;
|
|
33
38
|
logEvent(event: any): void;
|
|
39
|
+
getMaxUpdateFrequency(): number;
|
|
40
|
+
setMaxUpdateFrequency(value: number): void;
|
|
34
41
|
sendUpdate(request: any): void;
|
|
35
42
|
getID(): string;
|
|
36
43
|
getDisplayName(): string;
|
|
37
44
|
getName(): string;
|
|
45
|
+
getUniqueName(): string;
|
|
38
46
|
getSettings(): DeviceSettings;
|
|
39
47
|
getInterface(): string;
|
|
40
48
|
onData(callback: OnDeviceDataCallback): void;
|
|
49
|
+
canSendUpdate(): boolean;
|
|
50
|
+
emitData(data: DeviceData): void;
|
|
41
51
|
isStopped(): boolean;
|
|
42
52
|
isStarted(): boolean;
|
|
43
53
|
isPaused(): boolean;
|
|
54
|
+
hasDataListeners(): boolean | OnDeviceDataCallback;
|
|
44
55
|
}
|
|
45
56
|
export declare class ControllableDevice extends IncyclistDevice implements Bike {
|
|
46
57
|
cyclingMode: CyclingMode;
|
|
47
58
|
user?: User;
|
|
48
59
|
constructor(settings: DeviceSettings, props?: DeviceProperties);
|
|
60
|
+
isControllable(): boolean;
|
|
49
61
|
setUser(user: User): void;
|
|
50
62
|
setBikeProps(props: DeviceProperties): void;
|
|
51
63
|
getWeight(): number;
|
package/lib/base/adpater.js
CHANGED
|
@@ -8,16 +8,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
15
|
exports.ControllableDevice = exports.DEFAULT_PROPS = exports.DEFAULT_USER_WEIGHT = exports.DEFAULT_BIKE_WEIGHT = void 0;
|
|
13
|
-
const
|
|
16
|
+
const events_1 = __importDefault(require("events"));
|
|
14
17
|
exports.DEFAULT_BIKE_WEIGHT = 10;
|
|
15
18
|
exports.DEFAULT_USER_WEIGHT = 75;
|
|
16
19
|
exports.DEFAULT_PROPS = {
|
|
17
20
|
userWeight: exports.DEFAULT_USER_WEIGHT,
|
|
18
21
|
bikeWeight: exports.DEFAULT_BIKE_WEIGHT
|
|
19
22
|
};
|
|
20
|
-
class IncyclistDevice extends
|
|
23
|
+
class IncyclistDevice extends events_1.default {
|
|
21
24
|
constructor(settings, props) {
|
|
22
25
|
super();
|
|
23
26
|
this.onDataFn = undefined;
|
|
@@ -31,11 +34,18 @@ class IncyclistDevice extends stream_1.EventEmitter {
|
|
|
31
34
|
connect() { throw new Error('not implemented'); }
|
|
32
35
|
close() { throw new Error('not implemented'); }
|
|
33
36
|
check() { throw new Error("Method not implemented."); }
|
|
37
|
+
isControllable() {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
34
40
|
isEqual(settings) { throw new Error("Method not implemented."); }
|
|
35
41
|
getCapabilities() { return this.capabilities; }
|
|
36
42
|
hasCapability(capability) {
|
|
37
43
|
return this.capabilities.find(c => c === capability) !== undefined;
|
|
38
44
|
}
|
|
45
|
+
addCapability(capability) {
|
|
46
|
+
if (!this.capabilities.includes(capability))
|
|
47
|
+
this.capabilities.push(capability);
|
|
48
|
+
}
|
|
39
49
|
update() { throw new Error("Method not implemented."); }
|
|
40
50
|
start(props) { throw new Error("Method not implemented."); }
|
|
41
51
|
stop() { throw new Error("Method not implemented."); }
|
|
@@ -52,10 +62,16 @@ class IncyclistDevice extends stream_1.EventEmitter {
|
|
|
52
62
|
});
|
|
53
63
|
}
|
|
54
64
|
logEvent(event) {
|
|
55
|
-
if (!this.logger)
|
|
65
|
+
if (!this.logger || this.paused)
|
|
56
66
|
return;
|
|
57
67
|
this.logger.logEvent(event);
|
|
58
68
|
}
|
|
69
|
+
getMaxUpdateFrequency() {
|
|
70
|
+
return this.updateFrequency;
|
|
71
|
+
}
|
|
72
|
+
setMaxUpdateFrequency(value) {
|
|
73
|
+
this.updateFrequency = value;
|
|
74
|
+
}
|
|
59
75
|
sendUpdate(request) { throw new Error("Method not implemented."); }
|
|
60
76
|
getID() { throw new Error('not implemented'); }
|
|
61
77
|
getDisplayName() {
|
|
@@ -64,6 +80,9 @@ class IncyclistDevice extends stream_1.EventEmitter {
|
|
|
64
80
|
getName() {
|
|
65
81
|
return this.settings.name;
|
|
66
82
|
}
|
|
83
|
+
getUniqueName() {
|
|
84
|
+
throw new Error("Method not implemented.");
|
|
85
|
+
}
|
|
67
86
|
getSettings() {
|
|
68
87
|
return this.settings;
|
|
69
88
|
}
|
|
@@ -73,6 +92,20 @@ class IncyclistDevice extends stream_1.EventEmitter {
|
|
|
73
92
|
onData(callback) {
|
|
74
93
|
this.onDataFn = callback;
|
|
75
94
|
}
|
|
95
|
+
canSendUpdate() {
|
|
96
|
+
const updateFrequency = this.getMaxUpdateFrequency();
|
|
97
|
+
if (updateFrequency === -1 || updateFrequency === undefined)
|
|
98
|
+
return true;
|
|
99
|
+
return (!this.lastUpdate || (Date.now() - this.lastUpdate) > updateFrequency);
|
|
100
|
+
}
|
|
101
|
+
emitData(data) {
|
|
102
|
+
if (!this.canSendUpdate())
|
|
103
|
+
return;
|
|
104
|
+
if (this.onDataFn)
|
|
105
|
+
this.onDataFn(data);
|
|
106
|
+
this.emit('data', this.getSettings(), data);
|
|
107
|
+
this.lastUpdate = Date.now();
|
|
108
|
+
}
|
|
76
109
|
isStopped() {
|
|
77
110
|
return this.stopped;
|
|
78
111
|
}
|
|
@@ -82,6 +115,9 @@ class IncyclistDevice extends stream_1.EventEmitter {
|
|
|
82
115
|
isPaused() {
|
|
83
116
|
return this.paused;
|
|
84
117
|
}
|
|
118
|
+
hasDataListeners() {
|
|
119
|
+
return this.onDataFn || this.listenerCount('data') > 0;
|
|
120
|
+
}
|
|
85
121
|
}
|
|
86
122
|
exports.default = IncyclistDevice;
|
|
87
123
|
class ControllableDevice extends IncyclistDevice {
|
|
@@ -90,13 +126,16 @@ class ControllableDevice extends IncyclistDevice {
|
|
|
90
126
|
this.cyclingMode = this.getDefaultCyclingMode();
|
|
91
127
|
this.user = {};
|
|
92
128
|
}
|
|
129
|
+
isControllable() {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
93
132
|
setUser(user) {
|
|
94
133
|
this.user = user;
|
|
95
134
|
if (!user.weight)
|
|
96
135
|
this.user.weight = exports.DEFAULT_USER_WEIGHT;
|
|
97
136
|
}
|
|
98
137
|
setBikeProps(props) {
|
|
99
|
-
const { user, userWeight
|
|
138
|
+
const { user, userWeight } = props || {};
|
|
100
139
|
if (user)
|
|
101
140
|
this.setUser(user);
|
|
102
141
|
if (userWeight)
|
|
@@ -1,31 +1,33 @@
|
|
|
1
1
|
import { DeviceProperties } from "../types/device";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
2
|
+
import BleAdapter from "./base/adapter";
|
|
3
|
+
import { BleDeviceSettings, BleProtocol } from "./types";
|
|
4
|
+
import { BleComms } from "./base/comms";
|
|
5
5
|
export interface BleAdapterInfo {
|
|
6
|
-
protocol:
|
|
7
|
-
profile: string;
|
|
6
|
+
protocol: BleProtocol;
|
|
8
7
|
Adapter: typeof BleAdapter;
|
|
9
8
|
Comm: typeof BleComms;
|
|
10
9
|
}
|
|
11
|
-
export declare function mapLegacyProfile(profile: any): {
|
|
12
|
-
profile: any;
|
|
13
|
-
protocol: string;
|
|
14
|
-
};
|
|
15
10
|
export default class BleAdapterFactory {
|
|
16
11
|
static _instance: BleAdapterFactory;
|
|
17
|
-
|
|
12
|
+
implementations: BleAdapterInfo[];
|
|
13
|
+
instances: BleAdapter[];
|
|
18
14
|
static getInstance(): BleAdapterFactory;
|
|
19
15
|
constructor();
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
getAdapterInfo(protocol: BleProtocol): BleAdapterInfo;
|
|
17
|
+
getAll(): BleAdapterInfo[];
|
|
22
18
|
createInstance(settings: BleDeviceSettings, props?: DeviceProperties): BleAdapter;
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
removeInstance(query: {
|
|
20
|
+
settings?: BleDeviceSettings;
|
|
21
|
+
adapter?: BleAdapter;
|
|
22
|
+
}): void;
|
|
23
|
+
find(settings?: BleDeviceSettings): BleAdapter;
|
|
24
|
+
register(protocol: BleProtocol, Adapter: typeof BleAdapter, Comm: typeof BleComms): void;
|
|
25
|
+
getAllInstances(): BleAdapter[];
|
|
26
|
+
getAllSupportedComms(): (typeof BleComms)[];
|
|
27
|
+
getAllSupportedAdapters(): (typeof BleAdapter)[];
|
|
25
28
|
getAllSupportedServices(): string[];
|
|
26
29
|
getDeviceClasses(peripheral: any, props?: {
|
|
27
|
-
|
|
28
|
-
profile?: string;
|
|
30
|
+
protocol?: BleProtocol;
|
|
29
31
|
services?: string[];
|
|
30
32
|
}): (typeof BleComms)[];
|
|
31
33
|
}
|