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.
Files changed (159) hide show
  1. package/lib/adapters.d.ts +1 -1
  2. package/lib/antv2/adapter-factory.d.ts +4 -15
  3. package/lib/antv2/adapter.d.ts +15 -15
  4. package/lib/antv2/adapter.js +67 -21
  5. package/lib/antv2/ant-interface.d.ts +3 -11
  6. package/lib/antv2/ant-interface.js +1 -1
  7. package/lib/antv2/base/adapter.d.ts +62 -0
  8. package/lib/antv2/base/adapter.js +360 -0
  9. package/lib/antv2/base/ant-interface.d.ts +35 -0
  10. package/lib/antv2/base/ant-interface.js +285 -0
  11. package/lib/antv2/base/binding.d.ts +13 -0
  12. package/lib/antv2/base/binding.js +27 -0
  13. package/lib/antv2/cad/adapter.d.ts +10 -0
  14. package/lib/antv2/cad/adapter.js +25 -0
  15. package/lib/antv2/cad/index.d.ts +2 -0
  16. package/lib/antv2/cad/index.js +7 -0
  17. package/lib/antv2/consts.d.ts +2 -0
  18. package/lib/antv2/consts.js +5 -0
  19. package/lib/antv2/factories/adapter-factory.d.ts +14 -0
  20. package/lib/antv2/factories/adapter-factory.js +65 -0
  21. package/lib/antv2/factories/sensor-factory.d.ts +5 -0
  22. package/lib/antv2/factories/sensor-factory.js +22 -0
  23. package/lib/antv2/fe/adapter.d.ts +24 -29
  24. package/lib/antv2/fe/adapter.js +208 -225
  25. package/lib/antv2/hr/adapter.d.ts +6 -15
  26. package/lib/antv2/hr/adapter.js +7 -55
  27. package/lib/antv2/hr copy/adapter.d.ts +11 -0
  28. package/lib/antv2/hr copy/adapter.js +30 -0
  29. package/lib/antv2/hr copy/index.d.ts +2 -0
  30. package/lib/antv2/hr copy/index.js +7 -0
  31. package/lib/antv2/index.d.ts +5 -4
  32. package/lib/antv2/index.js +4 -2
  33. package/lib/antv2/pwr/adapter.d.ts +9 -33
  34. package/lib/antv2/pwr/adapter.js +19 -140
  35. package/lib/antv2/types.d.ts +23 -4
  36. package/lib/base/adpater.d.ts +39 -60
  37. package/lib/base/adpater.js +139 -161
  38. package/lib/base/consts.d.ts +4 -0
  39. package/lib/base/consts.js +9 -0
  40. package/lib/ble/adapter-factory.d.ts +10 -11
  41. package/lib/ble/base/adapter.d.ts +7 -14
  42. package/lib/ble/base/adapter.js +2 -36
  43. package/lib/ble/ble-interface.d.ts +5 -7
  44. package/lib/ble/cp/adapter.d.ts +6 -8
  45. package/lib/ble/cp/adapter.js +8 -27
  46. package/lib/ble/elite/adapter.d.ts +7 -8
  47. package/lib/ble/elite/adapter.js +5 -25
  48. package/lib/ble/fm/adapter.d.ts +6 -7
  49. package/lib/ble/fm/adapter.js +13 -34
  50. package/lib/ble/hr/adapter.d.ts +5 -8
  51. package/lib/ble/hr/adapter.js +2 -2
  52. package/lib/ble/peripheral-cache.d.ts +2 -3
  53. package/lib/ble/tacx/adapter.d.ts +2 -3
  54. package/lib/ble/tacx/adapter.js +8 -8
  55. package/lib/ble/types.d.ts +1 -2
  56. package/lib/ble/wahoo/adapter.d.ts +2 -2
  57. package/lib/ble/wahoo/adapter.js +6 -6
  58. package/lib/ble/wahoo/comms.js +16 -16
  59. package/lib/factories/adapters.d.ts +7 -0
  60. package/lib/factories/adapters.js +49 -0
  61. package/lib/factories/index.d.ts +3 -0
  62. package/lib/factories/index.js +10 -0
  63. package/lib/factories/interfaces.d.ts +7 -0
  64. package/lib/factories/interfaces.js +27 -0
  65. package/lib/index.d.ts +5 -6
  66. package/lib/index.js +4 -9
  67. package/lib/interfaces.d.ts +1 -1
  68. package/lib/modes/ant-fe-adv-st-mode.d.ts +1 -1
  69. package/lib/modes/antble-erg.d.ts +1 -1
  70. package/lib/modes/antble-smarttrainer.d.ts +2 -2
  71. package/lib/modes/base.d.ts +5 -5
  72. package/lib/modes/daum-classic-standard.d.ts +3 -2
  73. package/lib/modes/daum-erg.d.ts +3 -3
  74. package/lib/modes/daum-premium-standard.d.ts +3 -2
  75. package/lib/modes/daum-smarttrainer.d.ts +3 -2
  76. package/lib/modes/kettler-erg.d.ts +3 -3
  77. package/lib/modes/power-base.d.ts +3 -3
  78. package/lib/modes/power-base.js +2 -2
  79. package/lib/modes/power-meter.d.ts +3 -2
  80. package/lib/modes/simulator.d.ts +2 -1
  81. package/lib/modes/types.d.ts +2 -13
  82. package/lib/serial/SinglePathScanner.d.ts +17 -0
  83. package/lib/serial/SinglePathScanner.js +87 -0
  84. package/lib/serial/adapter-factory.d.ts +6 -6
  85. package/lib/serial/adapter.d.ts +6 -11
  86. package/lib/serial/base/adapter.d.ts +17 -0
  87. package/lib/serial/base/adapter.js +67 -0
  88. package/lib/serial/base/comms.d.ts +62 -0
  89. package/lib/serial/base/comms.js +280 -0
  90. package/lib/serial/base/serial-interface.d.ts +36 -0
  91. package/lib/serial/base/serial-interface.js +288 -0
  92. package/lib/serial/base/serial-scanner.d.ts +16 -0
  93. package/lib/serial/base/serial-scanner.js +87 -0
  94. package/lib/serial/base/serialport.d.ts +17 -0
  95. package/lib/serial/base/serialport.js +87 -0
  96. package/lib/serial/comms.d.ts +2 -2
  97. package/lib/serial/daum/DaumAdapter.d.ts +12 -24
  98. package/lib/serial/daum/DaumAdapter.js +40 -59
  99. package/lib/serial/daum/classic/PROTOCOL_NAME.d.ts +2 -0
  100. package/lib/serial/daum/classic/PROTOCOL_NAME.js +5 -0
  101. package/lib/serial/daum/classic/adapter.d.ts +8 -20
  102. package/lib/serial/daum/classic/adapter.js +28 -58
  103. package/lib/serial/daum/classic/comms.d.ts +4 -6
  104. package/lib/serial/daum/classic/comms.js +2 -2
  105. package/lib/serial/daum/classic/consts.d.ts +2 -0
  106. package/lib/serial/daum/classic/consts.js +5 -0
  107. package/lib/serial/daum/classic/mock.js +4 -3
  108. package/lib/serial/daum/classic/types.d.ts +8 -10
  109. package/lib/serial/daum/classic/utils.d.ts +1 -2
  110. package/lib/serial/daum/consts.d.ts +0 -19
  111. package/lib/serial/daum/consts.js +0 -22
  112. package/lib/serial/daum/premium/adapter.d.ts +8 -11
  113. package/lib/serial/daum/premium/adapter.js +27 -53
  114. package/lib/serial/daum/premium/comms.d.ts +4 -7
  115. package/lib/serial/daum/premium/comms.js +23 -22
  116. package/lib/serial/daum/premium/mock.d.ts +1 -1
  117. package/lib/serial/daum/premium/mock.js +2 -2
  118. package/lib/serial/daum/premium/types.d.ts +32 -17
  119. package/lib/serial/daum/premium/types.js +8 -8
  120. package/lib/serial/daum/premium/utils.d.ts +2 -3
  121. package/lib/serial/daum/premium/utils.js +3 -3
  122. package/lib/serial/daum/types.d.ts +4 -1
  123. package/lib/serial/daum/types.js +9 -1
  124. package/lib/serial/factories/adapter-factory.d.ts +14 -0
  125. package/lib/serial/factories/adapter-factory.js +30 -0
  126. package/lib/serial/index.d.ts +8 -5
  127. package/lib/serial/index.js +15 -15
  128. package/lib/serial/kettler/comms.d.ts +1 -1
  129. package/lib/serial/kettler/ergo-racer/adapter.d.ts +11 -18
  130. package/lib/serial/kettler/ergo-racer/adapter.js +9 -21
  131. package/lib/serial/kettler/types.d.ts +8 -0
  132. package/lib/serial/kettler/types.js +2 -0
  133. package/lib/serial/serial-interface.d.ts +2 -32
  134. package/lib/serial/serial-interface.js +3 -76
  135. package/lib/serial/serial-scanner.d.ts +16 -0
  136. package/lib/serial/serial-scanner.js +87 -0
  137. package/lib/serial/serialport.d.ts +1 -13
  138. package/lib/serial/types.d.ts +45 -0
  139. package/lib/serial/types.js +9 -0
  140. package/lib/simulator/Simulator.d.ts +10 -13
  141. package/lib/simulator/Simulator.js +11 -23
  142. package/lib/types/Command.d.ts +8 -0
  143. package/lib/types/Command.js +2 -0
  144. package/lib/types/adapter.d.ts +22 -33
  145. package/lib/types/adapter.js +0 -68
  146. package/lib/types/command.d.ts +0 -8
  147. package/lib/types/command.js +0 -2
  148. package/lib/types/data.d.ts +12 -1
  149. package/lib/types/device.d.ts +8 -23
  150. package/lib/types/device.js +9 -8
  151. package/lib/types/index.d.ts +6 -0
  152. package/lib/types/index.js +22 -0
  153. package/lib/types/route.d.ts +0 -19
  154. package/lib/types/route.js +0 -2
  155. package/lib/types/types.d.ts +8 -0
  156. package/lib/types/types.js +2 -0
  157. package/lib/utils/utils.d.ts +1 -0
  158. package/lib/utils/utils.js +22 -4
  159. package/package.json +1 -1
@@ -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
- exports.AntFeControl = void 0;
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 utils_2 = require("../../utils/utils");
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 adpater_1 = require("../../base/adpater");
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
- getLogData(data, excludeList) {
89
- const logData = JSON.parse(JSON.stringify(data));
90
- excludeList.forEach((key) => {
91
- delete logData[key];
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 (!this.started || this.isStopped())
129
- return;
130
- if (!this.ivDataTimeout && this.dataMsgCount > 0) {
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
- mapToCycleModeData(deviceData) {
79
+ mapData(deviceData) {
153
80
  const data = {
154
81
  isPedalling: false,
155
82
  power: 0,
156
- pedalRpm: undefined,
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 || (data.pedalRpm === undefined && data.power > 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(bikeData) {
172
- if (bikeData === undefined)
173
- return;
174
- let distance = 0;
175
- if (this.distanceInternal !== undefined && bikeData.distanceInternal !== undefined) {
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
- return data;
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
- if (wasStopped)
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: this.isReconnecting });
207
- const opts = props || {};
208
- const { args = {}, user = {} } = opts;
209
- return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
210
- const { startupTimeout = 20000, reconnectTimeout = 2000 } = props || {};
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
- let hasData = false;
230
- while (!success && retry < MAX_RETRIES && !timeoutOccured) {
231
- retry++;
232
- if (!this.sensorConnected) {
233
- this.logEvent({ message: 'start sensor', props });
234
- this.sensorConnected = yield this.ant.startSensor(this.sensor, this.onDeviceData.bind(this));
235
- if (this.sensorConnected) {
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
- status = { userSent: false, slopeSent: false };
256
- if (!hasData) {
257
- yield (0, utils_2.sleep)(reconnectTimeout);
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
- if (!this.isReconnecting) {
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
- stopTimeoutCheck();
302
- resolve(true);
175
+ return true;
303
176
  }
304
177
  else {
305
- this.logEvent({ message: 'ANT FE start failed' });
306
- stopTimeoutCheck();
307
- if (!hasData) {
308
- reject(new Error('could not start device, reason: no data received'));
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 (this.sensorConnected) {
311
- reject(new Error('could not start device, reason: could not send FE commands'));
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
- reject(new Error('could not start device, reason: could not connect'));
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.isReconnecting = true;
334
- try {
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 (_a) {
340
+ catch (err) {
341
+ console.log(err);
361
342
  return false;
362
343
  }
363
344
  }
364
- else {
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, ISensor, Profile } from "incyclist-ant-plus";
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
- import { NonControllableDevice } from "../../base/adpater";
5
- type HeartRateSensorData = {
6
- heartrate: number;
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
- onDeviceData(deviceData: HeartRateSensorState): void;
17
- mapData(deviceData: HeartRateSensorState): void;
9
+ mapToAdapterData(deviceData: HeartRateSensorState): void;
18
10
  hasData(): boolean;
19
11
  }
20
- export {};
@@ -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 utils_1 = require("../utils");
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.deviceData = {
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
- onDeviceData(deviceData) {
49
- this.dataMsgCount++;
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
+ }