incyclist-devices 2.1.0 → 2.1.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/lib/adapters.d.ts +1 -1
- package/lib/antv2/adapter-factory.d.ts +4 -15
- package/lib/antv2/adapter.d.ts +15 -15
- package/lib/antv2/adapter.js +67 -21
- package/lib/antv2/ant-interface.d.ts +3 -11
- package/lib/antv2/ant-interface.js +1 -1
- package/lib/antv2/base/adapter.d.ts +62 -0
- package/lib/antv2/base/adapter.js +360 -0
- package/lib/antv2/base/ant-interface.d.ts +35 -0
- package/lib/antv2/base/ant-interface.js +285 -0
- package/lib/antv2/base/binding.d.ts +13 -0
- package/lib/antv2/base/binding.js +27 -0
- package/lib/antv2/cad/adapter.d.ts +10 -0
- package/lib/antv2/cad/adapter.js +25 -0
- package/lib/antv2/cad/index.d.ts +2 -0
- package/lib/antv2/cad/index.js +7 -0
- package/lib/antv2/consts.d.ts +2 -0
- package/lib/antv2/consts.js +5 -0
- package/lib/antv2/factories/adapter-factory.d.ts +14 -0
- package/lib/antv2/factories/adapter-factory.js +65 -0
- package/lib/antv2/factories/sensor-factory.d.ts +5 -0
- package/lib/antv2/factories/sensor-factory.js +22 -0
- package/lib/antv2/fe/adapter.d.ts +24 -29
- package/lib/antv2/fe/adapter.js +208 -225
- package/lib/antv2/hr/adapter.d.ts +6 -15
- package/lib/antv2/hr/adapter.js +7 -55
- package/lib/antv2/hr copy/adapter.d.ts +11 -0
- package/lib/antv2/hr copy/adapter.js +30 -0
- package/lib/antv2/hr copy/index.d.ts +2 -0
- package/lib/antv2/hr copy/index.js +7 -0
- package/lib/antv2/index.d.ts +5 -4
- package/lib/antv2/index.js +4 -2
- package/lib/antv2/pwr/adapter.d.ts +9 -33
- package/lib/antv2/pwr/adapter.js +19 -140
- package/lib/antv2/types.d.ts +23 -4
- package/lib/base/adpater.d.ts +39 -60
- package/lib/base/adpater.js +139 -161
- package/lib/base/consts.d.ts +4 -0
- package/lib/base/consts.js +9 -0
- package/lib/ble/adapter-factory.d.ts +10 -11
- package/lib/ble/base/adapter.d.ts +7 -14
- package/lib/ble/base/adapter.js +2 -36
- package/lib/ble/ble-interface.d.ts +5 -7
- package/lib/ble/cp/adapter.d.ts +6 -8
- package/lib/ble/cp/adapter.js +8 -27
- package/lib/ble/elite/adapter.d.ts +7 -8
- package/lib/ble/elite/adapter.js +5 -25
- package/lib/ble/fm/adapter.d.ts +6 -7
- package/lib/ble/fm/adapter.js +13 -34
- package/lib/ble/hr/adapter.d.ts +5 -8
- package/lib/ble/hr/adapter.js +2 -2
- package/lib/ble/peripheral-cache.d.ts +2 -3
- package/lib/ble/tacx/adapter.d.ts +2 -3
- package/lib/ble/tacx/adapter.js +8 -8
- package/lib/ble/types.d.ts +1 -2
- package/lib/ble/wahoo/adapter.d.ts +2 -2
- package/lib/ble/wahoo/adapter.js +6 -6
- package/lib/ble/wahoo/comms.js +16 -16
- package/lib/factories/adapters.d.ts +7 -0
- package/lib/factories/adapters.js +49 -0
- package/lib/factories/index.d.ts +3 -0
- package/lib/factories/index.js +10 -0
- package/lib/factories/interfaces.d.ts +7 -0
- package/lib/factories/interfaces.js +27 -0
- package/lib/index.d.ts +5 -6
- package/lib/index.js +4 -9
- package/lib/interfaces.d.ts +1 -1
- package/lib/modes/ant-fe-adv-st-mode.d.ts +1 -1
- package/lib/modes/antble-erg.d.ts +1 -1
- package/lib/modes/antble-smarttrainer.d.ts +2 -2
- package/lib/modes/base.d.ts +5 -5
- package/lib/modes/daum-classic-standard.d.ts +3 -2
- package/lib/modes/daum-erg.d.ts +3 -3
- package/lib/modes/daum-premium-standard.d.ts +3 -2
- package/lib/modes/daum-smarttrainer.d.ts +3 -2
- package/lib/modes/kettler-erg.d.ts +3 -3
- package/lib/modes/power-base.d.ts +3 -3
- package/lib/modes/power-base.js +2 -2
- package/lib/modes/power-meter.d.ts +3 -2
- package/lib/modes/simulator.d.ts +2 -1
- package/lib/modes/types.d.ts +2 -13
- package/lib/serial/SinglePathScanner.d.ts +17 -0
- package/lib/serial/SinglePathScanner.js +87 -0
- package/lib/serial/adapter-factory.d.ts +6 -6
- package/lib/serial/adapter.d.ts +6 -11
- package/lib/serial/base/adapter.d.ts +17 -0
- package/lib/serial/base/adapter.js +67 -0
- package/lib/serial/base/comms.d.ts +62 -0
- package/lib/serial/base/comms.js +280 -0
- package/lib/serial/base/serial-interface.d.ts +36 -0
- package/lib/serial/base/serial-interface.js +288 -0
- package/lib/serial/base/serial-scanner.d.ts +16 -0
- package/lib/serial/base/serial-scanner.js +87 -0
- package/lib/serial/base/serialport.d.ts +17 -0
- package/lib/serial/base/serialport.js +87 -0
- package/lib/serial/comms.d.ts +2 -2
- package/lib/serial/daum/DaumAdapter.d.ts +12 -24
- package/lib/serial/daum/DaumAdapter.js +40 -59
- package/lib/serial/daum/classic/PROTOCOL_NAME.d.ts +2 -0
- package/lib/serial/daum/classic/PROTOCOL_NAME.js +5 -0
- package/lib/serial/daum/classic/adapter.d.ts +8 -20
- package/lib/serial/daum/classic/adapter.js +28 -58
- package/lib/serial/daum/classic/comms.d.ts +4 -6
- package/lib/serial/daum/classic/comms.js +2 -2
- package/lib/serial/daum/classic/consts.d.ts +2 -0
- package/lib/serial/daum/classic/consts.js +5 -0
- package/lib/serial/daum/classic/mock.js +4 -3
- package/lib/serial/daum/classic/types.d.ts +8 -10
- package/lib/serial/daum/classic/utils.d.ts +1 -2
- package/lib/serial/daum/consts.d.ts +0 -19
- package/lib/serial/daum/consts.js +0 -22
- package/lib/serial/daum/premium/adapter.d.ts +8 -11
- package/lib/serial/daum/premium/adapter.js +27 -53
- package/lib/serial/daum/premium/comms.d.ts +4 -7
- package/lib/serial/daum/premium/comms.js +23 -22
- package/lib/serial/daum/premium/mock.d.ts +1 -1
- package/lib/serial/daum/premium/mock.js +2 -2
- package/lib/serial/daum/premium/types.d.ts +32 -17
- package/lib/serial/daum/premium/types.js +8 -8
- package/lib/serial/daum/premium/utils.d.ts +2 -3
- package/lib/serial/daum/premium/utils.js +3 -3
- package/lib/serial/daum/types.d.ts +4 -1
- package/lib/serial/daum/types.js +9 -1
- package/lib/serial/factories/adapter-factory.d.ts +14 -0
- package/lib/serial/factories/adapter-factory.js +30 -0
- package/lib/serial/index.d.ts +8 -5
- package/lib/serial/index.js +15 -15
- package/lib/serial/kettler/comms.d.ts +1 -1
- package/lib/serial/kettler/ergo-racer/adapter.d.ts +11 -18
- package/lib/serial/kettler/ergo-racer/adapter.js +9 -21
- package/lib/serial/kettler/types.d.ts +8 -0
- package/lib/serial/kettler/types.js +2 -0
- package/lib/serial/serial-interface.d.ts +2 -32
- package/lib/serial/serial-interface.js +3 -76
- package/lib/serial/serial-scanner.d.ts +16 -0
- package/lib/serial/serial-scanner.js +87 -0
- package/lib/serial/serialport.d.ts +1 -13
- package/lib/serial/types.d.ts +45 -0
- package/lib/serial/types.js +9 -0
- package/lib/simulator/Simulator.d.ts +10 -13
- package/lib/simulator/Simulator.js +11 -23
- package/lib/types/Command.d.ts +8 -0
- package/lib/types/Command.js +2 -0
- package/lib/types/adapter.d.ts +22 -33
- package/lib/types/adapter.js +0 -68
- package/lib/types/command.d.ts +0 -8
- package/lib/types/command.js +0 -2
- package/lib/types/data.d.ts +12 -1
- package/lib/types/device.d.ts +8 -23
- package/lib/types/device.js +9 -8
- package/lib/types/index.d.ts +6 -0
- package/lib/types/index.js +22 -0
- package/lib/types/route.d.ts +0 -19
- package/lib/types/route.js +0 -2
- package/lib/types/types.d.ts +8 -0
- package/lib/types/types.js +2 -0
- package/lib/utils/utils.d.ts +1 -0
- package/lib/utils/utils.js +22 -4
- package/package.json +1 -1
package/lib/antv2/fe/adapter.js
CHANGED
|
@@ -12,47 +12,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
|
|
16
|
-
const adapter_1 = __importDefault(require("../adapter"));
|
|
17
|
-
const utils_1 = require("../utils");
|
|
18
|
-
const gd_eventlog_1 = require("gd-eventlog");
|
|
15
|
+
const adapter_1 = __importDefault(require("../base/adapter"));
|
|
19
16
|
const ant_fe_adv_st_mode_1 = __importDefault(require("../../modes/ant-fe-adv-st-mode"));
|
|
20
|
-
const
|
|
21
|
-
const sensor_factory_1 = __importDefault(require("../sensor-factory"));
|
|
17
|
+
const utils_1 = require("../../utils/utils");
|
|
22
18
|
const capabilities_1 = require("../../types/capabilities");
|
|
23
|
-
const
|
|
19
|
+
const consts_1 = require("../../base/consts");
|
|
24
20
|
const antble_erg_1 = __importDefault(require("../../modes/antble-erg"));
|
|
25
21
|
const antble_smarttrainer_1 = __importDefault(require("../../modes/antble-smarttrainer"));
|
|
26
22
|
const DEFAULT_BIKE_WEIGHT_MOUNTAIN = 14.5;
|
|
27
23
|
const MAX_RETRIES = 3;
|
|
28
|
-
class AntFeControl extends adpater_1.ControllableDevice {
|
|
29
|
-
getSupportedCyclingModes() {
|
|
30
|
-
return [antble_smarttrainer_1.default, antble_erg_1.default, ant_fe_adv_st_mode_1.default];
|
|
31
|
-
}
|
|
32
|
-
getDefaultCyclingMode() {
|
|
33
|
-
return new antble_smarttrainer_1.default(this.adapter);
|
|
34
|
-
}
|
|
35
|
-
sendInitCommands() {
|
|
36
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
-
return true;
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
exports.AntFeControl = AntFeControl;
|
|
42
24
|
class AntFEAdapter extends adapter_1.default {
|
|
43
25
|
constructor(settings, props) {
|
|
44
|
-
if (settings.protocol && settings.profile !== AntFEAdapter.INCYCLIST_PROFILE_NAME)
|
|
45
|
-
throw new Error('Incorrect Profile');
|
|
46
|
-
if (!settings.protocol && settings.profile !== AntFEAdapter.ANT_PROFILE_NAME)
|
|
47
|
-
throw new Error('Incorrect Profile');
|
|
48
26
|
super(settings, props);
|
|
49
|
-
this.setControl(new AntFeControl(this, props));
|
|
50
|
-
this.deviceData = {
|
|
51
|
-
DeviceID: this.sensor.getDeviceID()
|
|
52
|
-
};
|
|
53
|
-
this.dataMsgCount = 0;
|
|
54
|
-
this.logger = new gd_eventlog_1.EventLogger('Ant+FE');
|
|
55
|
-
this.isReconnecting = false;
|
|
56
27
|
this.startProps = {};
|
|
57
28
|
this.sensorConnected = false;
|
|
58
29
|
this.capabilities = [
|
|
@@ -60,46 +31,23 @@ class AntFEAdapter extends adapter_1.default {
|
|
|
60
31
|
capabilities_1.IncyclistCapability.Control
|
|
61
32
|
];
|
|
62
33
|
}
|
|
63
|
-
createSensor(settings) {
|
|
64
|
-
const sensor = sensor_factory_1.default.create(AntFEAdapter.ANT_PROFILE_NAME, Number(settings.deviceID));
|
|
65
|
-
return sensor;
|
|
66
|
-
}
|
|
67
|
-
getName() {
|
|
68
|
-
if (this.settings.name)
|
|
69
|
-
return this.settings.name;
|
|
70
|
-
const deviceID = this.sensor.getDeviceID();
|
|
71
|
-
return `Ant+FE ${deviceID}`;
|
|
72
|
-
}
|
|
73
|
-
getUniqueName() {
|
|
74
|
-
if (this.settings.name)
|
|
75
|
-
return this.settings.name;
|
|
76
|
-
const { DeviceID, ManId } = this.deviceData;
|
|
77
|
-
const brand = (0, utils_1.getBrand)(ManId);
|
|
78
|
-
if (brand)
|
|
79
|
-
return `${brand} FE ${DeviceID}`;
|
|
80
|
-
else
|
|
81
|
-
return `${this.getName()}`;
|
|
82
|
-
}
|
|
83
34
|
getDisplayName() {
|
|
84
35
|
const { InstantaneousPower } = this.deviceData;
|
|
85
36
|
const pwrStr = InstantaneousPower ? ` (${InstantaneousPower})` : '';
|
|
86
37
|
return `${this.getUniqueName()}${pwrStr}`;
|
|
87
38
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return logData;
|
|
39
|
+
getDefaultReconnectDelay() {
|
|
40
|
+
return 2000;
|
|
41
|
+
}
|
|
42
|
+
isReconnecting() {
|
|
43
|
+
return this.promiseReconnect !== null && this.promiseReconnect !== undefined;
|
|
94
44
|
}
|
|
95
45
|
sendUpdate(request, forced = false) {
|
|
96
46
|
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
-
if ((this.paused || this.isReconnecting) && !forced)
|
|
47
|
+
if ((this.paused || this.isReconnecting()) && !forced)
|
|
98
48
|
return;
|
|
99
49
|
let isReset = request.reset && Object.keys(request).length === 1;
|
|
100
50
|
const update = isReset ? this.getCyclingMode().getBikeInitRequest() : this.getCyclingMode().sendBikeUpdate(request);
|
|
101
|
-
if (!update)
|
|
102
|
-
return;
|
|
103
51
|
this.logEvent({ message: 'send bike update requested', update, request });
|
|
104
52
|
try {
|
|
105
53
|
const fe = this.sensor;
|
|
@@ -122,200 +70,226 @@ class AntFEAdapter extends adapter_1.default {
|
|
|
122
70
|
});
|
|
123
71
|
}
|
|
124
72
|
onDeviceData(deviceData) {
|
|
125
|
-
this.dataMsgCount++;
|
|
126
|
-
this.lastDataTS = Date.now();
|
|
127
73
|
super.onDeviceData(deviceData);
|
|
128
|
-
if (
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
this.startDataTimeoutCheck();
|
|
132
|
-
}
|
|
133
|
-
try {
|
|
134
|
-
const logData = this.getLogData(deviceData, ['PairedDevices', 'RawData']);
|
|
135
|
-
this.logEvent({ message: 'onDeviceData', data: logData, paused: this.paused });
|
|
136
|
-
if (!this.canSendUpdate())
|
|
137
|
-
return;
|
|
138
|
-
let incyclistData = this.mapToCycleModeData(deviceData);
|
|
139
|
-
incyclistData = this.getCyclingMode().updateData(incyclistData);
|
|
140
|
-
this.data = this.transformData(incyclistData);
|
|
141
|
-
this.emitData(this.data);
|
|
74
|
+
if (deviceData.HeartRate && !this.hasCapability(capabilities_1.IncyclistCapability.HeartRate)) {
|
|
75
|
+
this.capabilities.push(capabilities_1.IncyclistCapability.HeartRate);
|
|
76
|
+
this.emit('device-info', this.getSettings(), { capabilities: this.capabilities });
|
|
142
77
|
}
|
|
143
|
-
catch (err) {
|
|
144
|
-
this.logEvent({ message: 'error', fn: 'onDeviceData()', error: err.message || err, stack: err.stack });
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
canSendUpdate() {
|
|
148
|
-
if (!this.hasDataListeners() || this.paused)
|
|
149
|
-
return false;
|
|
150
|
-
return super.canSendUpdate();
|
|
151
78
|
}
|
|
152
|
-
|
|
79
|
+
mapData(deviceData) {
|
|
153
80
|
const data = {
|
|
154
81
|
isPedalling: false,
|
|
155
82
|
power: 0,
|
|
156
|
-
pedalRpm:
|
|
83
|
+
pedalRpm: 0,
|
|
157
84
|
speed: 0,
|
|
158
|
-
heartrate: 0,
|
|
159
|
-
distanceInternal: 0,
|
|
160
|
-
slope: undefined,
|
|
161
|
-
time: undefined
|
|
162
85
|
};
|
|
163
86
|
data.speed = (deviceData.VirtualSpeed !== undefined ? deviceData.VirtualSpeed : (deviceData.RealSpeed || 0)) * 3.6;
|
|
164
87
|
data.slope = (deviceData.Incline !== undefined ? deviceData.Incline : data.slope);
|
|
165
88
|
data.power = (deviceData.InstantaneousPower !== undefined ? deviceData.InstantaneousPower : data.power);
|
|
166
|
-
data.time = (deviceData.ElapsedTime !== undefined ? deviceData.ElapsedTime : data.time);
|
|
167
89
|
data.pedalRpm = (deviceData.Cadence !== undefined ? deviceData.Cadence : data.pedalRpm);
|
|
168
|
-
data.isPedalling = data.pedalRpm > 0 ||
|
|
90
|
+
data.isPedalling = data.pedalRpm > 0 || data.power > 0;
|
|
91
|
+
if (deviceData.HeartRate !== undefined)
|
|
92
|
+
data.heartrate = deviceData.HeartRate;
|
|
93
|
+
if (deviceData.Distance !== undefined)
|
|
94
|
+
data.distanceInternal = deviceData.Distance;
|
|
95
|
+
if (deviceData.ElapsedTime !== undefined)
|
|
96
|
+
data.time = deviceData.ElapsedTime;
|
|
169
97
|
return data;
|
|
170
98
|
}
|
|
171
|
-
transformData(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
distance = bikeData.distanceInternal - this.distanceInternal;
|
|
177
|
-
}
|
|
178
|
-
if (bikeData.distanceInternal !== undefined)
|
|
179
|
-
this.distanceInternal = bikeData.distanceInternal;
|
|
180
|
-
const data = {
|
|
181
|
-
speed: bikeData.speed,
|
|
182
|
-
slope: bikeData.slope,
|
|
183
|
-
power: bikeData.power !== undefined ? Math.round(bikeData.power) : undefined,
|
|
184
|
-
cadence: bikeData.pedalRpm !== undefined ? Math.round(bikeData.pedalRpm) : undefined,
|
|
185
|
-
heartrate: bikeData.heartrate !== undefined ? Math.round(bikeData.heartrate) : undefined,
|
|
186
|
-
distance,
|
|
99
|
+
transformData(adapterData, deviceData) {
|
|
100
|
+
const data = Object.assign(this.data, {
|
|
101
|
+
power: adapterData.power,
|
|
102
|
+
speed: adapterData.speed,
|
|
103
|
+
cadence: adapterData.pedalRpm,
|
|
187
104
|
timestamp: Date.now()
|
|
188
|
-
};
|
|
189
|
-
|
|
105
|
+
});
|
|
106
|
+
if (adapterData.distanceInternal !== undefined) {
|
|
107
|
+
if (data.internalDistanceCounter !== undefined)
|
|
108
|
+
data.distance = adapterData.distanceInternal - data.internalDistanceCounter;
|
|
109
|
+
data.internalDistanceCounter = adapterData.distanceInternal;
|
|
110
|
+
}
|
|
111
|
+
if (deviceData.Distance)
|
|
112
|
+
data.deviceDistanceCounter = deviceData.Distance;
|
|
113
|
+
if (adapterData.heartrate)
|
|
114
|
+
data.heartrate = adapterData.heartrate;
|
|
115
|
+
if (adapterData.slope)
|
|
116
|
+
data.slope = adapterData.slope;
|
|
117
|
+
if (adapterData.time)
|
|
118
|
+
data.deviceTime = adapterData.time;
|
|
119
|
+
this.data = data;
|
|
190
120
|
}
|
|
191
121
|
start(props) {
|
|
122
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
123
|
+
const isReconnect = (props === null || props === void 0 ? void 0 : props.reconnect) || false;
|
|
124
|
+
const startProps = Object.assign({}, props || {});
|
|
125
|
+
delete startProps.reconnect;
|
|
126
|
+
return yield this.performStart(props, isReconnect);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
performStart(props, isReconnect) {
|
|
192
130
|
return __awaiter(this, void 0, void 0, function* () {
|
|
193
131
|
const wasPaused = this.paused;
|
|
194
132
|
const wasStopped = this.stopped;
|
|
195
|
-
this.startProps = props
|
|
133
|
+
this.startProps = props;
|
|
196
134
|
if (wasPaused)
|
|
197
135
|
this.resume();
|
|
198
|
-
|
|
199
|
-
this.stopped = false;
|
|
136
|
+
this.stopped = false;
|
|
200
137
|
if (this.started && !wasPaused && !wasStopped) {
|
|
201
138
|
return true;
|
|
202
139
|
}
|
|
203
140
|
const connected = yield this.connect();
|
|
204
141
|
if (!connected)
|
|
205
142
|
throw new Error(`could not start device, reason:could not connect`);
|
|
206
|
-
this.logEvent({ message: 'starting device', props, isStarted: this.started, isReconnecting:
|
|
207
|
-
const
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const totalTimeout = Math.min(startupTimeout + 10000, startupTimeout * 2);
|
|
212
|
-
let to, timeoutOccured = false;
|
|
213
|
-
const stopTimeoutCheck = () => {
|
|
214
|
-
if (to) {
|
|
215
|
-
clearTimeout(to);
|
|
216
|
-
to = null;
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
to = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
220
|
-
reject(new Error(`could not start device, reason:timeout`));
|
|
221
|
-
this.started = false;
|
|
222
|
-
to = null;
|
|
223
|
-
timeoutOccured = true;
|
|
224
|
-
}), totalTimeout);
|
|
143
|
+
this.logEvent({ message: 'starting device', props, isStarted: this.started, isReconnecting: isReconnect });
|
|
144
|
+
const { startupTimeout = this.getDefaultStartupTimeout(), reconnectTimeout = this.getDefaultReconnectDelay() } = props || {};
|
|
145
|
+
const totalTimeout = Math.min(startupTimeout + 10000, startupTimeout * 2);
|
|
146
|
+
let status = { timeout: false, sensorStarted: false, hasData: false, userSent: false, slopeSent: false };
|
|
147
|
+
const doStart = () => __awaiter(this, void 0, void 0, function* () {
|
|
225
148
|
this.setFEDefaultTimeout();
|
|
226
149
|
let success = false;
|
|
227
|
-
let status = { userSent: false, slopeSent: false };
|
|
228
150
|
let retry = 0;
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
this.logEvent({ message: 'sensor started', props });
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
if (this.sensorConnected && !hasData) {
|
|
240
|
-
try {
|
|
241
|
-
yield this.waitForData(startupTimeout);
|
|
242
|
-
hasData = true;
|
|
243
|
-
}
|
|
244
|
-
catch (err) {
|
|
245
|
-
stopTimeoutCheck();
|
|
246
|
-
try {
|
|
247
|
-
yield yield this.ant.stopSensor(this.sensor);
|
|
248
|
-
this.sensorConnected = false;
|
|
249
|
-
}
|
|
250
|
-
catch (_a) { }
|
|
251
|
-
this.started = false;
|
|
252
|
-
return reject(new Error('could not start device, reason:no data received'));
|
|
253
|
-
}
|
|
151
|
+
if (isReconnect) {
|
|
152
|
+
status.userSent = true;
|
|
153
|
+
status.slopeSent = true;
|
|
154
|
+
}
|
|
155
|
+
while (!success && retry < MAX_RETRIES && !status.timeout) {
|
|
156
|
+
if (retry !== 0) {
|
|
157
|
+
console.log('~~~ RETRY', status);
|
|
254
158
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
159
|
+
retry++;
|
|
160
|
+
yield this.initSensor(status, props);
|
|
161
|
+
yield this.waitForInitialData(status, startupTimeout);
|
|
162
|
+
yield this.sendInititalUserMessage(status, props);
|
|
163
|
+
yield this.sendInitialRequest(status, props);
|
|
164
|
+
if (!status.hasData) {
|
|
165
|
+
yield this.stopSensor();
|
|
166
|
+
yield (0, utils_1.sleep)(reconnectTimeout);
|
|
258
167
|
continue;
|
|
259
168
|
}
|
|
260
|
-
|
|
261
|
-
try {
|
|
262
|
-
const fe = this.sensor;
|
|
263
|
-
const mode = this.getCyclingMode();
|
|
264
|
-
const bikeType = mode ? mode.getSetting('bikeType').toLowerCase() : 'race';
|
|
265
|
-
const defaultBikeWeight = bikeType === 'mountain' ? DEFAULT_BIKE_WEIGHT_MOUNTAIN : adpater_1.DEFAULT_BIKE_WEIGHT;
|
|
266
|
-
const userWeight = args.userWeight || user.weight || adpater_1.DEFAULT_USER_WEIGHT;
|
|
267
|
-
const bikeWeight = args.bikeWeight || defaultBikeWeight;
|
|
268
|
-
status.userSent = status.userSent || (yield fe.sendUserConfiguration(userWeight, bikeWeight, args.wheelDiameter, args.gearRatio));
|
|
269
|
-
if (!status.slopeSent) {
|
|
270
|
-
const startRequest = this.getCyclingMode().getBikeInitRequest();
|
|
271
|
-
if (startRequest) {
|
|
272
|
-
if (startRequest.targetPower !== undefined && startRequest.targetPower !== null) {
|
|
273
|
-
status.slopeSent = yield fe.sendTargetPower(startRequest.targetPower);
|
|
274
|
-
}
|
|
275
|
-
else if (startRequest.slope !== undefined && startRequest.slope !== null) {
|
|
276
|
-
status.slopeSent = yield fe.sendTrackResistance(startRequest.slope);
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
status.slopeSent = true;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
283
|
-
status.slopeSent = yield fe.sendTrackResistance(0.0);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
catch (err) {
|
|
288
|
-
this.logEvent({ message: 'sending FE message error', error: err.message });
|
|
289
|
-
this.started = false;
|
|
290
|
-
}
|
|
291
|
-
success = status.userSent && status.slopeSent;
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
success = true;
|
|
295
|
-
}
|
|
169
|
+
success = status.sensorStarted && status.hasData && status.userSent && status.slopeSent;
|
|
296
170
|
}
|
|
297
171
|
if (success) {
|
|
298
172
|
this.logEvent({ message: 'ANT FE start success' });
|
|
299
173
|
this.started = true;
|
|
300
174
|
this.paused = false;
|
|
301
|
-
|
|
302
|
-
resolve(true);
|
|
175
|
+
return true;
|
|
303
176
|
}
|
|
304
177
|
else {
|
|
305
|
-
this.
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
178
|
+
this.started = false;
|
|
179
|
+
if (!status.sensorStarted) {
|
|
180
|
+
this.logEvent({ message: 'ANT FE start failed', reason: 'could not connect' });
|
|
181
|
+
throw new Error('could not start device, reason:could not connect');
|
|
309
182
|
}
|
|
310
|
-
else if (
|
|
311
|
-
|
|
183
|
+
else if (!status.hasData) {
|
|
184
|
+
this.logEvent({ message: 'ANT FE start failed', reason: 'no data received' });
|
|
185
|
+
throw new Error('could not start device, reason:no data received');
|
|
312
186
|
}
|
|
313
187
|
else {
|
|
314
|
-
|
|
188
|
+
this.logEvent({ message: 'ANT FE start failed', reason: 'could not send FE commands' });
|
|
189
|
+
throw new Error('could not start device, reason:could not send FE commands');
|
|
315
190
|
}
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
try {
|
|
194
|
+
yield (0, utils_1.runWithTimeout)(doStart(), totalTimeout);
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
if (err.message === 'Timeout') {
|
|
316
198
|
this.started = false;
|
|
199
|
+
status.timeout = true;
|
|
200
|
+
throw new Error(`could not start device, reason:timeout`);
|
|
317
201
|
}
|
|
318
|
-
|
|
202
|
+
throw err;
|
|
203
|
+
}
|
|
204
|
+
return true;
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
waitForInitialData(status, startupTimeout) {
|
|
208
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
209
|
+
if ((status.sensorStarted && status.hasData) || !status.sensorStarted || status.timeout)
|
|
210
|
+
return;
|
|
211
|
+
this.logEvent({ message: 'wait for sensor data', });
|
|
212
|
+
status.hasData = yield this.waitForData(startupTimeout);
|
|
213
|
+
if (status.hasData)
|
|
214
|
+
this.logEvent({ message: 'sensor data received', });
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
stopSensor() {
|
|
218
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
219
|
+
if (!this.sensorConnected)
|
|
220
|
+
return;
|
|
221
|
+
try {
|
|
222
|
+
yield yield this.ant.stopSensor(this.sensor);
|
|
223
|
+
this.sensorConnected = false;
|
|
224
|
+
}
|
|
225
|
+
catch (_a) { }
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
initSensor(status, props) {
|
|
229
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
230
|
+
status.sensorStarted = this.sensorConnected;
|
|
231
|
+
if (status.sensorStarted || status.timeout)
|
|
232
|
+
return;
|
|
233
|
+
this.logEvent({ message: 'start sensor', props });
|
|
234
|
+
try {
|
|
235
|
+
this.sensorConnected = yield this.startSensor();
|
|
236
|
+
if (this.sensorConnected) {
|
|
237
|
+
this.logEvent({ message: 'sensor started', props });
|
|
238
|
+
status.sensorStarted = true;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch (err) {
|
|
242
|
+
this.logEvent({ message: 'start sensor failed', reason: err.message, props });
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
sendInititalUserMessage(status, props) {
|
|
247
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
248
|
+
if (!status.sensorStarted || !status.hasData || status.userSent || status.timeout)
|
|
249
|
+
return;
|
|
250
|
+
const opts = props || {};
|
|
251
|
+
const { args = {}, user = {} } = opts;
|
|
252
|
+
const fe = this.sensor;
|
|
253
|
+
try {
|
|
254
|
+
const mode = this.getCyclingMode();
|
|
255
|
+
const bikeType = mode ? mode.getSetting('bikeType').toLowerCase() : 'race';
|
|
256
|
+
const defaultBikeWeight = bikeType === 'mountain' ? DEFAULT_BIKE_WEIGHT_MOUNTAIN : consts_1.DEFAULT_BIKE_WEIGHT;
|
|
257
|
+
const userWeight = args.userWeight || user.weight || consts_1.DEFAULT_USER_WEIGHT;
|
|
258
|
+
const bikeWeight = args.bikeWeight || defaultBikeWeight;
|
|
259
|
+
status.userSent = status.userSent || (yield fe.sendUserConfiguration(userWeight, bikeWeight, args.wheelDiameter, args.gearRatio));
|
|
260
|
+
}
|
|
261
|
+
catch (err) {
|
|
262
|
+
this.logEvent({ message: 'sending FE message error', error: err.message });
|
|
263
|
+
status.userSent = false;
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
sendInitialRequest(status, props) {
|
|
268
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
269
|
+
if (!status.sensorStarted || !status.hasData || status.slopeSent || status.timeout)
|
|
270
|
+
return;
|
|
271
|
+
const fe = this.sensor;
|
|
272
|
+
try {
|
|
273
|
+
const startRequest = this.getCyclingMode().getBikeInitRequest();
|
|
274
|
+
if (startRequest) {
|
|
275
|
+
if (startRequest.targetPower !== undefined && startRequest.targetPower !== null) {
|
|
276
|
+
status.slopeSent = yield fe.sendTargetPower(startRequest.targetPower);
|
|
277
|
+
}
|
|
278
|
+
else if (startRequest.slope !== undefined && startRequest.slope !== null) {
|
|
279
|
+
status.slopeSent = yield fe.sendTrackResistance(startRequest.slope);
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
status.slopeSent = true;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
status.slopeSent = yield fe.sendTrackResistance(0.0);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
this.logEvent({ message: 'sending FE message error', error: err.message });
|
|
291
|
+
status.slopeSent = false;
|
|
292
|
+
}
|
|
319
293
|
});
|
|
320
294
|
}
|
|
321
295
|
setFEDefaultTimeout() {
|
|
@@ -330,20 +304,26 @@ class AntFEAdapter extends adapter_1.default {
|
|
|
330
304
|
reconnect() {
|
|
331
305
|
return __awaiter(this, void 0, void 0, function* () {
|
|
332
306
|
this.logEvent({ message: 'reconnect to device' });
|
|
333
|
-
this.
|
|
334
|
-
|
|
335
|
-
yield this.stop();
|
|
336
|
-
yield this.start(this.startProps);
|
|
337
|
-
this.started = true;
|
|
338
|
-
this.isReconnecting = false;
|
|
339
|
-
this.logEvent({ message: 'reconnect success' });
|
|
340
|
-
return true;
|
|
341
|
-
}
|
|
342
|
-
catch (err) {
|
|
343
|
-
this.logEvent({ message: 'reconnect failed' });
|
|
344
|
-
this.isReconnecting = false;
|
|
345
|
-
return false;
|
|
307
|
+
if (this.promiseReconnect) {
|
|
308
|
+
return yield this.promiseReconnect;
|
|
346
309
|
}
|
|
310
|
+
const doReconnect = () => __awaiter(this, void 0, void 0, function* () {
|
|
311
|
+
try {
|
|
312
|
+
yield this.stop();
|
|
313
|
+
yield this.performStart(this.startProps, true);
|
|
314
|
+
this.started = true;
|
|
315
|
+
this.logEvent({ message: 'reconnect success' });
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
catch (err) {
|
|
319
|
+
this.logEvent({ message: 'reconnect failed' });
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
this.promiseReconnect = doReconnect();
|
|
324
|
+
const res = yield this.promiseReconnect;
|
|
325
|
+
this.promiseReconnect = null;
|
|
326
|
+
return res;
|
|
347
327
|
});
|
|
348
328
|
}
|
|
349
329
|
sendInitCommands() {
|
|
@@ -357,16 +337,19 @@ class AntFEAdapter extends adapter_1.default {
|
|
|
357
337
|
return true;
|
|
358
338
|
}
|
|
359
339
|
}
|
|
360
|
-
catch (
|
|
340
|
+
catch (err) {
|
|
341
|
+
console.log(err);
|
|
361
342
|
return false;
|
|
362
343
|
}
|
|
363
344
|
}
|
|
364
|
-
|
|
365
|
-
return false;
|
|
366
|
-
}
|
|
345
|
+
return false;
|
|
367
346
|
});
|
|
368
347
|
}
|
|
369
348
|
}
|
|
370
349
|
AntFEAdapter.INCYCLIST_PROFILE_NAME = 'Smart Trainer';
|
|
371
350
|
AntFEAdapter.ANT_PROFILE_NAME = 'FE';
|
|
351
|
+
AntFEAdapter.controllers = {
|
|
352
|
+
modes: [antble_smarttrainer_1.default, antble_erg_1.default, ant_fe_adv_st_mode_1.default],
|
|
353
|
+
default: antble_smarttrainer_1.default
|
|
354
|
+
};
|
|
372
355
|
exports.default = AntFEAdapter;
|
|
@@ -1,20 +1,11 @@
|
|
|
1
|
-
import { HeartRateSensorState,
|
|
2
|
-
import AntAdapter from "../adapter";
|
|
1
|
+
import { HeartRateSensorState, Profile } from "incyclist-ant-plus";
|
|
2
|
+
import AntAdapter from "../base/adapter";
|
|
3
3
|
import { AntDeviceProperties, AntDeviceSettings, LegacyProfile } from "../types";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
};
|
|
8
|
-
export default class AntHrAdapter extends AntAdapter<NonControllableDevice<AntDeviceProperties>, HeartRateSensorState, HeartRateSensorData> {
|
|
9
|
-
static INCYCLIST_PROFILE_NAME: LegacyProfile;
|
|
10
|
-
static ANT_PROFILE_NAME: Profile;
|
|
4
|
+
export default class AntHrAdapter extends AntAdapter<HeartRateSensorState> {
|
|
5
|
+
protected static INCYCLIST_PROFILE_NAME: LegacyProfile;
|
|
6
|
+
protected static ANT_PROFILE_NAME: Profile;
|
|
11
7
|
constructor(settings: AntDeviceSettings, props?: AntDeviceProperties);
|
|
12
|
-
createSensor(settings: AntDeviceSettings): ISensor;
|
|
13
|
-
getName(): string;
|
|
14
|
-
getUniqueName(): string;
|
|
15
8
|
getDisplayName(): string;
|
|
16
|
-
|
|
17
|
-
mapData(deviceData: HeartRateSensorState): void;
|
|
9
|
+
mapToAdapterData(deviceData: HeartRateSensorState): void;
|
|
18
10
|
hasData(): boolean;
|
|
19
11
|
}
|
|
20
|
-
export {};
|
package/lib/antv2/hr/adapter.js
CHANGED
|
@@ -3,71 +3,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const adapter_1 = __importDefault(require("../adapter"));
|
|
7
|
-
const
|
|
8
|
-
const gd_eventlog_1 = require("gd-eventlog");
|
|
9
|
-
const sensor_factory_1 = __importDefault(require("../sensor-factory"));
|
|
10
|
-
const capabilities_1 = require("../../types/capabilities");
|
|
6
|
+
const adapter_1 = __importDefault(require("../base/adapter"));
|
|
7
|
+
const types_1 = require("../../types");
|
|
11
8
|
class AntHrAdapter extends adapter_1.default {
|
|
12
9
|
constructor(settings, props) {
|
|
13
|
-
if (settings.protocol && settings.profile !== AntHrAdapter.INCYCLIST_PROFILE_NAME)
|
|
14
|
-
throw new Error('Incorrect Profile');
|
|
15
|
-
if (!settings.protocol && settings.profile !== AntHrAdapter.ANT_PROFILE_NAME)
|
|
16
|
-
throw new Error('Incorrect Profile');
|
|
17
10
|
super(settings, props);
|
|
18
|
-
this.
|
|
19
|
-
DeviceID: this.sensor.getDeviceID()
|
|
20
|
-
};
|
|
21
|
-
this.logger = new gd_eventlog_1.EventLogger('Ant+Hrm');
|
|
22
|
-
this.capabilities = [capabilities_1.IncyclistCapability.HeartRate];
|
|
23
|
-
}
|
|
24
|
-
createSensor(settings) {
|
|
25
|
-
return sensor_factory_1.default.create(AntHrAdapter.ANT_PROFILE_NAME, Number(settings.deviceID));
|
|
26
|
-
}
|
|
27
|
-
getName() {
|
|
28
|
-
if (this.settings.name)
|
|
29
|
-
return this.settings.name;
|
|
30
|
-
const deviceID = this.sensor.getDeviceID();
|
|
31
|
-
return `Ant+HR ${deviceID}`;
|
|
32
|
-
}
|
|
33
|
-
getUniqueName() {
|
|
34
|
-
if (this.settings.name)
|
|
35
|
-
return this.settings.name;
|
|
36
|
-
const { DeviceID, ManId } = this.deviceData;
|
|
37
|
-
const brand = (0, utils_1.getBrand)(ManId);
|
|
38
|
-
if (brand)
|
|
39
|
-
return `${brand} HR ${DeviceID}`;
|
|
40
|
-
else
|
|
41
|
-
return `${this.getName()}`;
|
|
11
|
+
this.capabilities = [types_1.IncyclistCapability.HeartRate];
|
|
42
12
|
}
|
|
43
13
|
getDisplayName() {
|
|
44
14
|
const { ComputedHeartRate } = this.deviceData;
|
|
45
15
|
const hrmStr = ComputedHeartRate ? ` (${ComputedHeartRate})` : '';
|
|
46
16
|
return `${this.getUniqueName()}${hrmStr}`;
|
|
47
17
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
this.lastDataTS = Date.now();
|
|
51
|
-
super.onDeviceData(deviceData);
|
|
52
|
-
if (!this.started)
|
|
53
|
-
return;
|
|
54
|
-
if (!this.ivDataTimeout)
|
|
55
|
-
this.startDataTimeoutCheck();
|
|
56
|
-
try {
|
|
57
|
-
if (!this.canSendUpdate())
|
|
58
|
-
return;
|
|
59
|
-
this.logEvent({ message: 'onDeviceData', data: deviceData });
|
|
60
|
-
if (this.paused)
|
|
61
|
-
return;
|
|
62
|
-
this.mapData(deviceData);
|
|
63
|
-
this.emitData(this.data);
|
|
64
|
-
}
|
|
65
|
-
catch (err) {
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
mapData(deviceData) {
|
|
69
|
-
if (deviceData.ComputedHeartRate)
|
|
18
|
+
mapToAdapterData(deviceData) {
|
|
19
|
+
if (deviceData.ComputedHeartRate) {
|
|
70
20
|
this.data.heartrate = deviceData.ComputedHeartRate;
|
|
21
|
+
this.data.timestamp = Date.now();
|
|
22
|
+
}
|
|
71
23
|
}
|
|
72
24
|
hasData() {
|
|
73
25
|
return this.deviceData.ComputedHeartRate !== undefined && this.deviceData.ComputedHeartRate !== null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { HeartRateSensorState, Profile } from "incyclist-ant-plus";
|
|
2
|
+
import AntAdapter from "../base/adapter";
|
|
3
|
+
import { AntDeviceProperties, AntDeviceSettings, LegacyProfile } from "../types";
|
|
4
|
+
export default class AntHrAdapter extends AntAdapter<HeartRateSensorState> {
|
|
5
|
+
protected static INCYCLIST_PROFILE_NAME: LegacyProfile;
|
|
6
|
+
protected static ANT_PROFILE_NAME: Profile;
|
|
7
|
+
constructor(settings: AntDeviceSettings, props?: AntDeviceProperties);
|
|
8
|
+
getDisplayName(): string;
|
|
9
|
+
mapToAdapterData(deviceData: HeartRateSensorState): void;
|
|
10
|
+
hasData(): boolean;
|
|
11
|
+
}
|