incyclist-devices 2.3.0-beta.1 → 2.3.0-beta.10

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.
@@ -11,6 +11,7 @@ export default class IncyclistDevice<P extends DeviceProperties> extends EventEm
11
11
  started: boolean;
12
12
  stopped: boolean;
13
13
  paused: boolean;
14
+ scanning: boolean;
14
15
  protected props: P;
15
16
  protected cyclingMode: ICyclingMode;
16
17
  protected logger: EventLogger;
@@ -37,6 +38,7 @@ export default class IncyclistDevice<P extends DeviceProperties> extends EventEm
37
38
  resume(): Promise<boolean>;
38
39
  connect(): Promise<boolean>;
39
40
  close(): Promise<boolean>;
41
+ resetData(): void;
40
42
  getControllerInfo(): ControllerConfig | undefined;
41
43
  isControllable(): boolean;
42
44
  getCapabilities(): IncyclistCapability[];
@@ -65,5 +67,7 @@ export default class IncyclistDevice<P extends DeviceProperties> extends EventEm
65
67
  getStartProps(startProps?: P): P;
66
68
  hasDataListeners(): boolean | OnDeviceDataCallback;
67
69
  onData(callback: OnDeviceDataCallback): void;
70
+ onScanStart(): void;
71
+ onScanStop(): void;
68
72
  }
69
73
  export type IncyclistDeviceAdapter = IncyclistDevice<DeviceProperties>;
@@ -26,6 +26,7 @@ class IncyclistDevice extends events_1.default {
26
26
  this.started = false;
27
27
  this.stopped = false;
28
28
  this.paused = false;
29
+ this.scanning = false;
29
30
  this.user = {};
30
31
  this.data = {};
31
32
  this.cyclingMode = this.getDefaultCyclingMode();
@@ -100,6 +101,9 @@ class IncyclistDevice extends events_1.default {
100
101
  }
101
102
  connect() { throw new Error('not implemented'); }
102
103
  close() { throw new Error('not implemented'); }
104
+ resetData() {
105
+ delete this.lastUpdate;
106
+ }
103
107
  getControllerInfo() {
104
108
  const a = this.constructor;
105
109
  const config = a.controllers;
@@ -223,11 +227,15 @@ class IncyclistDevice extends events_1.default {
223
227
  const updateFrequency = this.getMaxUpdateFrequency();
224
228
  if (updateFrequency === -1 || updateFrequency === undefined)
225
229
  return true;
226
- return (!this.lastUpdate || (Date.now() - this.lastUpdate) > updateFrequency);
230
+ const ok = (!this.lastUpdate || (Date.now() - this.lastUpdate) > updateFrequency);
231
+ return ok;
227
232
  }
228
233
  canEmitData() {
229
- if (this.paused || this.stopped)
234
+ if (this.scanning)
235
+ return this.isUpdateWithinFrequency();
236
+ if (this.paused || this.stopped) {
230
237
  return false;
238
+ }
231
239
  return this.isUpdateWithinFrequency();
232
240
  }
233
241
  emitData(data) {
@@ -261,6 +269,12 @@ class IncyclistDevice extends events_1.default {
261
269
  onData(callback) {
262
270
  this.onDataFn = callback;
263
271
  }
272
+ onScanStart() {
273
+ this.scanning = true;
274
+ }
275
+ onScanStop() {
276
+ this.scanning = false;
277
+ }
264
278
  }
265
279
  IncyclistDevice.controllers = {};
266
280
  exports.default = IncyclistDevice;
@@ -1,5 +1,5 @@
1
1
  import IncyclistDevice from "../../base/adpater";
2
- import { BleDeviceProperties, BleDeviceSettings, BleStartProperties, IBlePeripheral } from "../types";
2
+ import { BleDeviceProperties, BleDeviceSettings, BleStartProperties, IBleInterface, IBlePeripheral } from "../types";
3
3
  import { IAdapter, IncyclistBikeData, IncyclistAdapterData, DeviceProperties } from "../../types";
4
4
  import { BleDeviceData } from "./types";
5
5
  import { LegacyProfile } from "../../antv2/types";
@@ -48,9 +48,12 @@ export default class BleAdapter<TDeviceData extends BleDeviceData, TDevice exten
48
48
  protected initControl(_props?: BleStartProperties): Promise<void>;
49
49
  protected startAdapter(startProps?: BleStartProperties): Promise<boolean>;
50
50
  startSensor(): Promise<boolean>;
51
+ protected onDisconnectDone(): Promise<void>;
51
52
  stop(): Promise<boolean>;
52
53
  pause(): Promise<boolean>;
53
54
  resume(): Promise<boolean>;
55
+ protected getBle(): IBleInterface<any>;
54
56
  update(): void;
55
57
  setCyclingMode(mode: string | ICyclingMode, settings?: any, sendInitCommands?: boolean): void;
58
+ onScanStart(): void;
56
59
  }
@@ -38,20 +38,20 @@ class BleAdapter extends adpater_1.default {
38
38
  }
39
39
  connect() {
40
40
  return __awaiter(this, void 0, void 0, function* () {
41
- const iface = interface_factory_1.BleMultiTransportInterfaceFactory.createInstance(this.getInterface());
42
- return yield iface.connect();
41
+ const ble = this.getBle();
42
+ return yield ble.connect();
43
43
  });
44
44
  }
45
45
  getPeripheral() {
46
- const iface = interface_factory_1.BleMultiTransportInterfaceFactory.createInstance(this.getInterface());
47
- const p = iface === null || iface === void 0 ? void 0 : iface.createPeripheralFromSettings(this.settings);
46
+ const ble = this.getBle();
47
+ const p = ble === null || ble === void 0 ? void 0 : ble.createPeripheralFromSettings(this.settings);
48
48
  return p;
49
49
  }
50
50
  waitForPeripheral() {
51
51
  return __awaiter(this, void 0, void 0, function* () {
52
- this.logEvent({ message: 'waiting for sensor ...' });
53
- const iface = interface_factory_1.BleMultiTransportInterfaceFactory.createInstance(this.getInterface());
54
- const peripheral = yield iface.waitForPeripheral(this.settings);
52
+ this.logEvent({ message: 'waiting for sensor ...', device: this.getName(), interface: this.getInterface() });
53
+ const ble = this.getBle();
54
+ const peripheral = yield ble.waitForPeripheral(this.settings);
55
55
  this.updateSensor(peripheral);
56
56
  });
57
57
  }
@@ -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 = {};
@@ -121,7 +122,7 @@ class BleAdapter extends adpater_1.default {
121
122
  if (this.isStopped() || this.isPaused())
122
123
  return;
123
124
  try {
124
- this.logEvent({ message: 'refreshDeviceData', data: this.deviceData, isControllable: this.isControllable() });
125
+ this.logEvent({ message: 'refreshDeviceData', device: this.getName(), interface: this.getInterface(), data: this.deviceData, isControllable: this.isControllable() });
125
126
  if (this.isControllable()) {
126
127
  const mappedData = this.mapData(this.deviceData);
127
128
  const incyclistData = this.getCyclingMode().updateData(mappedData);
@@ -133,7 +134,7 @@ class BleAdapter extends adpater_1.default {
133
134
  this.emitData(this.data);
134
135
  }
135
136
  catch (err) {
136
- this.logEvent({ message: 'error', fn: 'refreshDeviceData', error: err.message, stack: err.stack });
137
+ this.logEvent({ message: 'error', fn: 'refreshDeviceData', device: this.getName(), interface: this.getInterface(), error: err.message, stack: err.stack });
137
138
  }
138
139
  }
139
140
  onDeviceData(deviceData) {
@@ -141,9 +142,10 @@ class BleAdapter extends adpater_1.default {
141
142
  this.dataMsgCount++;
142
143
  this.lastDataTS = Date.now();
143
144
  this.deviceData = Object.assign({}, deviceData);
144
- if (!this.canEmitData())
145
+ if (!this.canEmitData()) {
145
146
  return;
146
- this.logEvent({ message: 'onDeviceData', data: deviceData, isControllable: this.isControllable() });
147
+ }
148
+ this.logEvent({ message: 'onDeviceData', device: this.getName(), interface: this.getInterface(), data: deviceData, isControllable: this.isControllable() });
147
149
  if (this.isControllable()) {
148
150
  const mappedData = this.mapData(deviceData);
149
151
  const incyclistData = this.getCyclingMode().updateData(mappedData);
@@ -155,7 +157,7 @@ class BleAdapter extends adpater_1.default {
155
157
  this.emitData(this.data);
156
158
  }
157
159
  catch (err) {
158
- this.logEvent({ message: 'Error', fn: 'onDeviceData', error: err.message, stack: err.stack });
160
+ this.logEvent({ message: 'Error', fn: 'onDeviceData', device: this.getName(), interface: this.getInterface(), error: err.message, stack: err.stack });
159
161
  }
160
162
  }
161
163
  mapData(deviceData) {
@@ -183,10 +185,7 @@ class BleAdapter extends adpater_1.default {
183
185
  this.stopped = false;
184
186
  if (wasPaused)
185
187
  this.resume();
186
- if (this.started && !wasPaused && !wasStopped) {
187
- return 'done';
188
- }
189
- if (this.started && wasPaused) {
188
+ if (this.started && !wasStopped) {
190
189
  return 'done';
191
190
  }
192
191
  const connected = yield this.connect();
@@ -200,6 +199,8 @@ class BleAdapter extends adpater_1.default {
200
199
  if (this.isStarting()) {
201
200
  yield this.stop();
202
201
  }
202
+ const ble = this.getBle();
203
+ ble.once('disconnect-done', this.onDisconnectDone.bind(this));
203
204
  this.startTask = new task_1.InteruptableTask(this.startAdapter(startProps), {
204
205
  timeout: startProps === null || startProps === void 0 ? void 0 : startProps.timeout,
205
206
  name: 'start',
@@ -240,11 +241,11 @@ class BleAdapter extends adpater_1.default {
240
241
  errorOnTimeout: false,
241
242
  timeout: startupTimeout
242
243
  });
243
- this.logEvent({ message: 'wait for sensor data', device: this.getName() });
244
+ this.logEvent({ message: 'wait for sensor data', device: this.getName(), interface: this.getInterface() });
244
245
  const hasData = yield waitTask.run();
245
246
  clearInterval(iv);
246
247
  if (hasData)
247
- this.logEvent({ message: 'sensor data received', device: this.getName() });
248
+ this.logEvent({ message: 'sensor data received', device: this.getName(), interface: this.getInterface() });
248
249
  });
249
250
  }
250
251
  checkCapabilities() {
@@ -256,41 +257,52 @@ class BleAdapter extends adpater_1.default {
256
257
  startAdapter(startProps) {
257
258
  return __awaiter(this, void 0, void 0, function* () {
258
259
  const props = this.getStartProps(startProps);
259
- const { timeout = this.getDefaultStartupTimeout() } = startProps;
260
+ const { timeout = this.getDefaultStartupTimeout() } = startProps !== null && startProps !== void 0 ? startProps : {};
260
261
  const wasPaused = this.paused;
261
262
  const preCheckResult = yield this.startPreChecks(props);
262
263
  if (preCheckResult === 'done') {
263
264
  yield (0, utils_1.resolveNextTick)();
265
+ this.logEvent({ message: `start result: ${this.started ? 'success' : 'failed'}`, preCheckResult, device: this.getName(), interface: this.getInterface(), protocol: this.getProtocolName() });
264
266
  return this.started;
265
267
  }
266
268
  if (preCheckResult === 'connection-failed') {
267
- this.logEvent({ message: 'start result: error', error: 'could not start device, reason:could not connect', protocol: this.getProtocolName() });
269
+ this.logEvent({ message: 'start result: error', error: 'could not start device, reason:could not connect', device: this.getName(), interface: this.getInterface(), protocol: this.getProtocolName() });
268
270
  yield (0, utils_1.resolveNextTick)();
269
271
  return false;
270
272
  }
271
- this.logEvent({ message: 'starting device', device: this.getName(), props, isStarted: this.started });
273
+ this.logEvent({ message: 'starting device', device: this.getName(), interface: this.getInterface(), props, isStarted: this.started });
272
274
  try {
275
+ this.resetData();
276
+ this.stopped = false;
273
277
  const connected = yield this.startSensor();
274
278
  if (connected) {
275
- this.logEvent({ message: 'peripheral connected', device: this.getName(), props });
279
+ this.logEvent({ message: 'peripheral connected', device: this.getName(), interface: this.getInterface(), props });
276
280
  }
277
281
  else {
278
- this.logEvent({ message: 'peripheral connection failed', device: this.getName(), reason: 'unknown', props });
282
+ this.logEvent({ message: 'peripheral connection failed', device: this.getName(), interface: this.getInterface(), reason: 'unknown', props });
283
+ this.stopped = true;
279
284
  return false;
280
285
  }
281
286
  yield this.waitForInitialData(timeout);
282
- yield this.checkCapabilities();
287
+ this.checkCapabilities();
283
288
  if (this.hasCapability(types_1.IncyclistCapability.Control))
284
289
  yield this.initControl(startProps);
285
- this.resetData();
286
290
  this.stopped = false;
287
291
  this.started = true;
288
292
  if (wasPaused)
289
293
  this.resume();
294
+ if (!this.isStarting()) {
295
+ this.started = false;
296
+ this.stopped = true;
297
+ return false;
298
+ }
299
+ this.logEvent({ message: 'start result: success', device: this.getName(), interface: this.getInterface(), protocol: this.getProtocolName() });
290
300
  return true;
291
301
  }
292
302
  catch (err) {
293
- this.logEvent({ message: 'start result: error', error: err.message, protocol: this.getProtocolName() });
303
+ this.logEvent({ message: 'start result: error', error: err.message, device: this.getName(), interface: this.getInterface(), protocol: this.getProtocolName() });
304
+ this.started = false;
305
+ this.stopped = true;
294
306
  return false;
295
307
  }
296
308
  });
@@ -304,43 +316,56 @@ class BleAdapter extends adpater_1.default {
304
316
  if (!this.getComms()) {
305
317
  return false;
306
318
  }
307
- const connected = yield this.getComms().startSensor();
319
+ const sensor = this.getComms();
320
+ const connected = yield sensor.startSensor();
321
+ yield sensor.subscribe();
308
322
  if (connected) {
309
- this.getComms().on('data', this.onDeviceDataHandler);
310
- this.getComms().on('disconnected', this.emit.bind(this));
311
- this.getComms().on('error', console.log);
323
+ sensor.on('data', this.onDeviceDataHandler);
324
+ sensor.on('disconnected', this.emit.bind(this));
325
+ sensor.on('error', console.log);
312
326
  }
313
327
  return connected;
314
328
  });
315
329
  }
316
- stop() {
330
+ onDisconnectDone() {
317
331
  return __awaiter(this, void 0, void 0, function* () {
318
- this.logEvent({ message: 'stopping device', device: this.getName() });
332
+ this.logEvent({ message: 'disconnecting device', device: this.getName(), interface: this.getInterface() });
319
333
  if (this.isStarting()) {
320
334
  yield this.startTask.stop();
321
335
  }
322
336
  let reason = 'unknown';
323
337
  let stopped = false;
324
- if (!this.getComms()) {
325
- this.logEvent({ message: 'device stopped - not started yet', device: this.getName() });
326
- return true;
327
- }
328
- this.getComms().reset();
338
+ const sensor = this.getComms();
329
339
  try {
330
- stopped = yield this.getComms().stopSensor();
340
+ stopped = yield sensor.stopSensor();
331
341
  }
332
342
  catch (err) {
333
343
  reason = err.message;
334
344
  }
335
- if (stopped) {
336
- this.logEvent({ message: 'device stopped', device: this.getName() });
345
+ if (!stopped) {
346
+ this.logEvent({ message: 'disconnecting device failed', device: this.getName(), interface: this.getInterface(), reason });
337
347
  }
338
- else {
339
- this.logEvent({ message: 'stopping device failed', device: this.getName(), reason });
348
+ });
349
+ }
350
+ stop() {
351
+ return __awaiter(this, void 0, void 0, function* () {
352
+ this.logEvent({ message: 'stopping device', device: this.getName(), interface: this.getInterface() });
353
+ if (this.isStarting()) {
354
+ yield this.startTask.stop();
340
355
  }
341
356
  this.started = false;
357
+ this.resetData();
358
+ if (!this.getComms()) {
359
+ this.logEvent({ message: 'device stopped - not started yet', device: this.getName(), interface: this.getInterface() });
360
+ return true;
361
+ }
362
+ const sensor = this.getComms();
363
+ sensor.reset();
364
+ this.resetData();
342
365
  this.stopped = true;
343
- return stopped;
366
+ this.started = false;
367
+ this.logEvent({ message: 'device stopped', device: this.getName(), interface: this.getInterface() });
368
+ return this.stopped;
344
369
  });
345
370
  }
346
371
  pause() {
@@ -349,8 +374,8 @@ class BleAdapter extends adpater_1.default {
349
374
  });
350
375
  return __awaiter(this, void 0, void 0, function* () {
351
376
  const res = yield _super.pause.call(this);
352
- const iface = interface_factory_1.BleMultiTransportInterfaceFactory.createInstance(this.getInterface());
353
- iface.pauseLogging();
377
+ const ble = this.getBle();
378
+ ble.pauseLogging();
354
379
  return res;
355
380
  });
356
381
  }
@@ -359,17 +384,24 @@ class BleAdapter extends adpater_1.default {
359
384
  resume: { get: () => super.resume }
360
385
  });
361
386
  return __awaiter(this, void 0, void 0, function* () {
362
- const iface = interface_factory_1.BleMultiTransportInterfaceFactory.createInstance(this.getInterface());
363
- iface.resumeLogging();
387
+ const ble = this.getBle();
388
+ ble.resumeLogging();
364
389
  const res = yield _super.resume.call(this);
365
390
  return res;
366
391
  });
367
392
  }
393
+ getBle() {
394
+ return interface_factory_1.BleMultiTransportInterfaceFactory.createInstance(this.getInterface());
395
+ }
368
396
  update() {
369
397
  }
370
398
  setCyclingMode(mode, settings, sendInitCommands) {
371
399
  super.setCyclingMode(mode, settings, sendInitCommands);
372
400
  this.refreshDeviceData();
373
401
  }
402
+ onScanStart() {
403
+ if (!this.isStarted())
404
+ this.start();
405
+ }
374
406
  }
375
407
  exports.default = BleAdapter;
@@ -1,7 +1,7 @@
1
1
  import EventEmitter from "events";
2
2
  import { DeviceSettings, InterfaceProps } from "../../types";
3
3
  import { EventLogger } from "gd-eventlog";
4
- import { BleBinding, BleDeviceSettings, BleInterfaceState, BlePeripheralAnnouncement, BlePeripheralInfo, BleRawPeripheral, BleScanProps, IBlePeripheral } from "../types";
4
+ import { BleBinding, BleDeviceSettings, BleInterfaceState, BlePeripheralAnnouncement, BleRawPeripheral, BleScanProps, IBlePeripheral } from "../types";
5
5
  import { IBleInterface } from '../../ble/types';
6
6
  import { InteruptableTask, TaskState } from "../../utils/task";
7
7
  import { InterfaceFactory } from "./types";
@@ -29,9 +29,10 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
29
29
  protected connectTask: InteruptableTask<TaskState, boolean>;
30
30
  protected scanTask: InteruptableTask<TaskState, void>;
31
31
  protected discoverTask: InteruptableTask<TaskState, void>;
32
- protected onDiscovered: (peripheral: BlePeripheralInfo) => void;
32
+ protected onDiscovered: (peripheral: BleRawPeripheral) => void;
33
33
  protected instanceId: number;
34
34
  protected connectedPeripherals: IBlePeripheral[];
35
+ protected connectAttemptCnt: number;
35
36
  static getInstance(props?: InterfaceProps): BleInterface;
36
37
  protected constructor(props: InterfaceProps);
37
38
  getLogger(): EventLogger;
@@ -41,7 +42,7 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
41
42
  getBinding(): BleBinding;
42
43
  protected autoConnect(): void;
43
44
  connect(reconnect?: boolean): Promise<boolean>;
44
- disconnect(): Promise<boolean>;
45
+ disconnect(cleanup?: boolean): Promise<boolean>;
45
46
  isConnected(): boolean;
46
47
  registerConnected(peripheral: IBlePeripheral): void;
47
48
  protected isConnecting(): boolean;
@@ -60,9 +61,9 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
60
61
  protected stopPeripheralScan(): Promise<void>;
61
62
  protected isDiscovering(): boolean;
62
63
  protected discoverPeripherals(): Promise<void>;
63
- pauseDiscovery(): Promise<void>;
64
- resumeDiscovery(): Promise<void>;
65
64
  protected onPeripheralFound(peripheral: BleRawPeripheral): void;
65
+ protected checkForWahooEnhancement(announcement: BlePeripheralAnnouncement): boolean;
66
+ protected processWahooAnnouncement(announcement: BlePeripheralAnnouncement): void;
66
67
  protected buildAnnouncement(peripheral: BleRawPeripheral): BlePeripheralAnnouncement;
67
68
  protected updateWithServices(announcement: BlePeripheralAnnouncement): Promise<BlePeripheralAnnouncement>;
68
69
  protected discoverServices(announcement: BlePeripheralAnnouncement): Promise<string[]>;
@@ -83,8 +84,13 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
83
84
  setDebug(enabled: boolean): void;
84
85
  protected connectBle(): Promise<boolean>;
85
86
  protected waitForBleConnected(): Promise<boolean>;
87
+ protected onError(err: Error): void;
88
+ protected onConnected(): void;
89
+ protected onDisconnected(): Promise<void>;
86
90
  protected onBleStateChange(state: BleInterfaceState): void;
87
91
  protected getAdapterFactory(): BleAdapterFactory<TBleSensor>;
92
+ protected getConnectTimeout(): number;
93
+ protected getExpectedServices(): string[];
88
94
  logEvent(event: any): void;
89
95
  logError(err: Error, fn: string, args?: any): void;
90
96
  }