incyclist-devices 2.3.0-beta.7 → 2.3.0-beta.8

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.
@@ -37,6 +37,7 @@ export default class IncyclistDevice<P extends DeviceProperties> extends EventEm
37
37
  resume(): Promise<boolean>;
38
38
  connect(): Promise<boolean>;
39
39
  close(): Promise<boolean>;
40
+ resetData(): void;
40
41
  getControllerInfo(): ControllerConfig | undefined;
41
42
  isControllable(): boolean;
42
43
  getCapabilities(): IncyclistCapability[];
@@ -100,6 +100,9 @@ class IncyclistDevice extends events_1.default {
100
100
  }
101
101
  connect() { throw new Error('not implemented'); }
102
102
  close() { throw new Error('not implemented'); }
103
+ resetData() {
104
+ delete this.lastUpdate;
105
+ }
103
106
  getControllerInfo() {
104
107
  const a = this.constructor;
105
108
  const config = a.controllers;
@@ -87,6 +87,7 @@ class BleAdapter extends adpater_1.default {
87
87
  return (_a = this.device) === null || _a === void 0 ? void 0 : _a.isConnected();
88
88
  }
89
89
  resetData() {
90
+ super.resetData();
90
91
  this.dataMsgCount = 0;
91
92
  this.deviceData = {};
92
93
  this.data = {};
@@ -183,10 +184,7 @@ class BleAdapter extends adpater_1.default {
183
184
  this.stopped = false;
184
185
  if (wasPaused)
185
186
  this.resume();
186
- if (this.started && !wasPaused && !wasStopped) {
187
- return 'done';
188
- }
189
- if (this.started && wasPaused) {
187
+ if (this.started && !wasStopped) {
190
188
  return 'done';
191
189
  }
192
190
  const connected = yield this.connect();
@@ -261,6 +259,7 @@ class BleAdapter extends adpater_1.default {
261
259
  const preCheckResult = yield this.startPreChecks(props);
262
260
  if (preCheckResult === 'done') {
263
261
  yield (0, utils_1.resolveNextTick)();
262
+ this.logEvent({ message: `start result: ${this.started ? 'success' : 'failed'}`, preCheckResult, device: this.getName(), interface: this.getInterface(), protocol: this.getProtocolName() });
264
263
  return this.started;
265
264
  }
266
265
  if (preCheckResult === 'connection-failed') {
@@ -270,27 +269,37 @@ class BleAdapter extends adpater_1.default {
270
269
  }
271
270
  this.logEvent({ message: 'starting device', device: this.getName(), interface: this.getInterface(), props, isStarted: this.started });
272
271
  try {
272
+ this.resetData();
273
+ this.stopped = false;
273
274
  const connected = yield this.startSensor();
274
275
  if (connected) {
275
276
  this.logEvent({ message: 'peripheral connected', device: this.getName(), interface: this.getInterface(), props });
276
277
  }
277
278
  else {
278
279
  this.logEvent({ message: 'peripheral connection failed', device: this.getName(), interface: this.getInterface(), reason: 'unknown', props });
280
+ this.stopped = true;
279
281
  return false;
280
282
  }
281
283
  yield this.waitForInitialData(timeout);
282
284
  this.checkCapabilities();
283
285
  if (this.hasCapability(types_1.IncyclistCapability.Control))
284
286
  yield this.initControl(startProps);
285
- this.resetData();
286
287
  this.stopped = false;
287
288
  this.started = true;
288
289
  if (wasPaused)
289
290
  this.resume();
291
+ if (!this.isStarting()) {
292
+ this.started = false;
293
+ this.stopped = true;
294
+ return false;
295
+ }
296
+ this.logEvent({ message: 'start result: success', device: this.getName(), interface: this.getInterface(), protocol: this.getProtocolName() });
290
297
  return true;
291
298
  }
292
299
  catch (err) {
293
300
  this.logEvent({ message: 'start result: error', error: err.message, device: this.getName(), interface: this.getInterface(), protocol: this.getProtocolName() });
301
+ this.started = false;
302
+ this.stopped = true;
294
303
  return false;
295
304
  }
296
305
  });
@@ -319,6 +328,8 @@ class BleAdapter extends adpater_1.default {
319
328
  if (this.isStarting()) {
320
329
  yield this.startTask.stop();
321
330
  }
331
+ this.started = false;
332
+ this.resetData();
322
333
  let reason = 'unknown';
323
334
  let stopped = false;
324
335
  if (!this.getComms()) {
@@ -338,8 +349,9 @@ class BleAdapter extends adpater_1.default {
338
349
  else {
339
350
  this.logEvent({ message: 'stopping device failed', device: this.getName(), interface: this.getInterface(), reason });
340
351
  }
341
- this.started = false;
352
+ this.resetData();
342
353
  this.stopped = true;
354
+ this.started = false;
343
355
  return stopped;
344
356
  });
345
357
  }
@@ -7,8 +7,9 @@ import { IAdapter, IncyclistAdapterData, IncyclistBikeData } from '../../types';
7
7
  import { LegacyProfile } from '../../antv2/types';
8
8
  export default class BleFmAdapter extends BleAdapter<IndoorBikeData, BleFitnessMachineDevice> {
9
9
  protected static INCYCLIST_PROFILE_NAME: LegacyProfile;
10
- distanceInternal: number;
11
- connectPromise: Promise<boolean>;
10
+ protected distanceInternal: number;
11
+ protected connectPromise: Promise<boolean>;
12
+ protected requestControlRetryDelay: number;
12
13
  constructor(settings: BleDeviceSettings, props?: BleDeviceProperties);
13
14
  updateSensor(peripheral: IBlePeripheral): void;
14
15
  isSame(device: IAdapter): boolean;
@@ -20,11 +20,12 @@ const sensor_1 = __importDefault(require("./sensor"));
20
20
  const adapter_1 = __importDefault(require("../base/adapter"));
21
21
  const consts_1 = require("./consts");
22
22
  const types_1 = require("../../types");
23
- const task_1 = require("../../utils/task");
23
+ const utils_1 = require("../../utils/utils");
24
24
  class BleFmAdapter extends adapter_1.default {
25
25
  constructor(settings, props) {
26
26
  super(settings, props);
27
27
  this.distanceInternal = 0;
28
+ this.requestControlRetryDelay = 1000;
28
29
  this.logger = new gd_eventlog_1.EventLogger('BLE-FM');
29
30
  this.device = new sensor_1.default(this.getPeripheral(), { logger: this.logger });
30
31
  this.capabilities = [
@@ -117,6 +118,8 @@ class BleFmAdapter extends adapter_1.default {
117
118
  }
118
119
  initControl(_startProps) {
119
120
  return __awaiter(this, void 0, void 0, function* () {
121
+ if (!this.isStarting())
122
+ return;
120
123
  this.setConstants();
121
124
  yield this.establishControl();
122
125
  this.setConstants();
@@ -146,38 +149,30 @@ class BleFmAdapter extends adapter_1.default {
146
149
  return __awaiter(this, void 0, void 0, function* () {
147
150
  if (!this.isStarting())
148
151
  return false;
149
- let waitTask;
150
- let iv;
152
+ let hasControl = false;
153
+ let tryCnt = 0;
151
154
  const sensor = this.getComms();
152
- const wait = () => {
153
- const res = new Promise((resolve) => {
154
- iv = setInterval(() => __awaiter(this, void 0, void 0, function* () {
155
- if (!this.isStarting() || !(waitTask === null || waitTask === void 0 ? void 0 : waitTask.isRunning)) {
156
- resolve(false);
157
- clearInterval(iv);
158
- return;
155
+ return new Promise((resolve) => {
156
+ this.startTask.notifyOnStop(() => {
157
+ resolve(false);
158
+ });
159
+ const waitUntilControl = () => __awaiter(this, void 0, void 0, function* () {
160
+ while (!hasControl && this.isStarting()) {
161
+ if (tryCnt++ === 0) {
162
+ this.logEvent({ message: 'requesting control', device: this.getName(), interface: this.getInterface() });
159
163
  }
160
- const hasControl = yield sensor.requestControl();
164
+ hasControl = yield sensor.requestControl();
161
165
  if (hasControl) {
162
- clearInterval(iv);
163
- resolve(true);
166
+ this.logEvent({ message: 'control granted', device: this.getName(), interface: this.getInterface() });
167
+ resolve(this.isStarting());
164
168
  }
165
- else if (!this.isStarting() || !(waitTask === null || waitTask === void 0 ? void 0 : waitTask.isRunning)) {
166
- resolve(false);
167
- clearInterval(iv);
169
+ else {
170
+ yield (0, utils_1.sleep)(this.requestControlRetryDelay);
168
171
  }
169
- }), 1000);
172
+ }
170
173
  });
171
- return res;
172
- };
173
- waitTask = new task_1.InteruptableTask(wait(), {
174
- errorOnTimeout: false,
175
- timeout: 10000
174
+ waitUntilControl();
176
175
  });
177
- const hasControl = yield waitTask.run();
178
- clearInterval(iv);
179
- if (!hasControl && this.isStarting())
180
- throw new Error('could not establish control');
181
176
  });
182
177
  }
183
178
  sendInitialRequest() {
@@ -212,7 +207,7 @@ class BleFmAdapter extends adapter_1.default {
212
207
  try {
213
208
  const update = this.getCyclingMode().sendBikeUpdate(request);
214
209
  this.logEvent({ message: 'send bike update requested', profile: this.getProfile(), update, request });
215
- const device = this.device;
210
+ const device = this.getComms();
216
211
  if (update.slope !== undefined) {
217
212
  yield device.setSlope(update.slope);
218
213
  }
@@ -46,5 +46,6 @@ export interface IAdapter extends EventEmitter, IBike, ISensor {
46
46
  resume(): Promise<boolean>;
47
47
  connect(): Promise<boolean>;
48
48
  close(): Promise<boolean>;
49
+ resetData(): void;
49
50
  onData(callback: OnDeviceDataCallback): any;
50
51
  }
@@ -30,15 +30,18 @@ export declare class InteruptableTask<T extends TaskState, P> {
30
30
  protected props?: TaskProps<T, P>;
31
31
  protected internalEvents: EventEmitter<[never]>;
32
32
  protected promise?: Promise<P>;
33
+ protected onStopNotifiers: Array<() => void>;
33
34
  constructor(promise: Promise<any>, props?: TaskProps<T, P>);
34
35
  getPromise(): Promise<P>;
35
36
  getState(): T;
36
37
  run(): Promise<P>;
38
+ notifyOnStop(cb: () => void): void;
37
39
  start(): void;
38
40
  stop(): Promise<boolean>;
39
41
  isRunning(): boolean;
40
42
  protected clearTimeout(): void;
41
43
  protected onTimeout(): void;
44
+ protected sendStopNotification(): void;
42
45
  protected logEvent(event: any): void;
43
46
  }
44
47
  export {};
package/lib/utils/task.js CHANGED
@@ -20,6 +20,7 @@ class InteruptableTask {
20
20
  var _a;
21
21
  this.internalState = { isRunning: false };
22
22
  this.internalEvents = new events_1.default();
23
+ this.onStopNotifiers = [];
23
24
  this.state = ((_a = props === null || props === void 0 ? void 0 : props.state) !== null && _a !== void 0 ? _a : {});
24
25
  this.props = props;
25
26
  delete this.props.state;
@@ -39,6 +40,9 @@ class InteruptableTask {
39
40
  return this.internalState.promise;
40
41
  });
41
42
  }
43
+ notifyOnStop(cb) {
44
+ this.onStopNotifiers.push(cb);
45
+ }
42
46
  start() {
43
47
  this.internalState.promise = new Promise((resolve, reject) => {
44
48
  var _a;
@@ -59,6 +63,7 @@ class InteruptableTask {
59
63
  isRunning: false,
60
64
  };
61
65
  this.internalEvents.removeAllListeners();
66
+ this.sendStopNotification();
62
67
  if (this.getState().result === 'completed' || this.getState().result === 'error')
63
68
  return;
64
69
  if (this.props.onDone)
@@ -119,6 +124,12 @@ class InteruptableTask {
119
124
  else
120
125
  resolve(null);
121
126
  }
127
+ sendStopNotification() {
128
+ this.onStopNotifiers.forEach((cb) => {
129
+ if (typeof cb === 'function')
130
+ cb();
131
+ });
132
+ }
122
133
  logEvent(event) {
123
134
  if (this.props.log)
124
135
  this.props.log(event);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-devices",
3
- "version": "2.3.0-beta.7",
3
+ "version": "2.3.0-beta.8",
4
4
  "dependencies": {
5
5
  "@serialport/bindings-interface": "^1.2.2",
6
6
  "@serialport/parser-byte-length": "^9.0.1",