incyclist-devices 2.3.0 → 2.3.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 (81) hide show
  1. package/README.MD +55 -0
  2. package/lib/antv2/base/adapter.d.ts +2 -2
  3. package/lib/base/adpater.d.ts +4 -0
  4. package/lib/base/adpater.js +16 -2
  5. package/lib/ble/adapter-factory.d.ts +24 -20
  6. package/lib/ble/adapter-factory.js +36 -13
  7. package/lib/ble/base/adapter.d.ts +6 -3
  8. package/lib/ble/base/adapter.js +83 -49
  9. package/lib/ble/base/comms.d.ts +74 -2
  10. package/lib/ble/base/comms.js +596 -3
  11. package/lib/ble/base/interface.d.ts +19 -10
  12. package/lib/ble/base/interface.js +148 -73
  13. package/lib/ble/base/peripheral.d.ts +7 -3
  14. package/lib/ble/base/peripheral.js +76 -22
  15. package/lib/ble/base/sensor.d.ts +2 -1
  16. package/lib/ble/base/sensor.js +22 -3
  17. package/lib/ble/ble-interface.d.ts +4 -7
  18. package/lib/ble/ble-interface.js +2 -16
  19. package/lib/ble/ble-peripheral.d.ts +0 -1
  20. package/lib/ble/ble-peripheral.js +11 -7
  21. package/lib/ble/characteristics/csc/features.d.ts +10 -0
  22. package/lib/ble/characteristics/csc/features.js +19 -0
  23. package/lib/ble/characteristics/csc/measurement.d.ts +33 -0
  24. package/lib/ble/characteristics/csc/measurement.js +109 -0
  25. package/lib/ble/characteristics/types.d.ts +6 -0
  26. package/lib/ble/characteristics/types.js +2 -0
  27. package/lib/ble/consts.d.ts +1 -0
  28. package/lib/ble/consts.js +2 -1
  29. package/lib/ble/cp/comm.d.ts +1 -1
  30. package/lib/ble/cp/comm.js +2 -2
  31. package/lib/ble/csc/adapter.d.ts +17 -0
  32. package/lib/ble/csc/adapter.js +66 -0
  33. package/lib/ble/csc/index.d.ts +3 -0
  34. package/lib/ble/csc/index.js +19 -0
  35. package/lib/ble/csc/sensor.d.ts +21 -0
  36. package/lib/ble/csc/sensor.js +64 -0
  37. package/lib/ble/csc/types.d.ts +6 -0
  38. package/lib/ble/csc/types.js +2 -0
  39. package/lib/ble/elite/comms.d.ts +1 -1
  40. package/lib/ble/elite/comms.js +2 -2
  41. package/lib/ble/factories/adapter-factory.d.ts +8 -6
  42. package/lib/ble/factories/adapter-factory.js +33 -0
  43. package/lib/ble/factories/types.d.ts +18 -0
  44. package/lib/ble/factories/types.js +2 -0
  45. package/lib/ble/fm/adapter.d.ts +4 -3
  46. package/lib/ble/fm/adapter.js +53 -48
  47. package/lib/ble/fm/comms.d.ts +1 -1
  48. package/lib/ble/fm/comms.js +3 -3
  49. package/lib/ble/fm/sensor.d.ts +1 -1
  50. package/lib/ble/fm/sensor.js +6 -5
  51. package/lib/ble/hr/comm.d.ts +1 -1
  52. package/lib/ble/hr/comm.js +2 -2
  53. package/lib/ble/index.js +2 -0
  54. package/lib/ble/tacx/adapter.d.ts +1 -1
  55. package/lib/ble/tacx/adapter.js +12 -10
  56. package/lib/ble/tacx/comms.d.ts +1 -1
  57. package/lib/ble/tacx/comms.js +2 -2
  58. package/lib/ble/tacx/sensor.js +9 -3
  59. package/lib/ble/types.d.ts +8 -2
  60. package/lib/ble/utils.d.ts +1 -0
  61. package/lib/ble/utils.js +15 -2
  62. package/lib/ble/wahoo/adapter.d.ts +1 -0
  63. package/lib/ble/wahoo/adapter.js +14 -0
  64. package/lib/ble/wahoo/comms.d.ts +1 -1
  65. package/lib/ble/wahoo/comms.js +2 -2
  66. package/lib/ble/wahoo/sensor.js +3 -6
  67. package/lib/direct-connect/base/interface.d.ts +2 -1
  68. package/lib/direct-connect/base/interface.js +20 -10
  69. package/lib/direct-connect/base/peripheral.d.ts +4 -4
  70. package/lib/direct-connect/base/peripheral.js +181 -68
  71. package/lib/direct-connect/bindings/types.d.ts +2 -1
  72. package/lib/direct-connect/messages/message.d.ts +1 -0
  73. package/lib/direct-connect/messages/message.js +16 -1
  74. package/lib/factories/adapters.js +0 -2
  75. package/lib/modes/ant-fe-adv-st-mode.d.ts +7 -1
  76. package/lib/modes/ant-fe-adv-st-mode.js +4 -3
  77. package/lib/types/adapter.d.ts +3 -0
  78. package/lib/types/interface.d.ts +1 -0
  79. package/lib/utils/task.d.ts +3 -0
  80. package/lib/utils/task.js +12 -0
  81. package/package.json +1 -1
package/README.MD CHANGED
@@ -19,6 +19,11 @@ __BLE__
19
19
  - Wahoo Smart Trainers (Wahoo specific service)
20
20
  - Tacx FE-C over BLE
21
21
 
22
+ __Direct Connect (Wifi)__
23
+ - Smart Trainers (FTMS)
24
+ - Power Meters (CP)
25
+ - Heartrate Monitors (HR)
26
+
22
27
  __Serial__
23
28
  - Daum Classic Ergo Bikes
24
29
  - Daum Premium Ergo Bikes (also over TCP/IP)
@@ -41,6 +46,7 @@ As this library supports various OS( Linux, Windows, Mac) and Incyclist is based
41
46
  - Ant: specified by the [incyclist-ant-plus](https://github.com/incyclist/ant-plus) library
42
47
  - Serial: specified by the [serialport](https://serialport.io/) library
43
48
  - BLE: specified by the [noble](https://github.com/noble/noble) library
49
+ - Wifi: a combination of Multicast DNS as provided by the [Bonjour](https://github.com/onlxltd/bonjour-service) library and createSocket() wich creates a Socket class from NodeJS net module
44
50
 
45
51
  __Ant Example__
46
52
 
@@ -76,6 +82,55 @@ const logger = new EventLogger('BLESample')
76
82
  const ble = InterfaceFactory.create('ble',{logger, log:true, binding:noble})
77
83
  ```
78
84
 
85
+ __Direct Connect Example__
86
+ ```
87
+ const { Bonjour } = require('bonjour-service')
88
+ const net = require('net');
89
+
90
+ const createBinding = ()=>{
91
+ return {
92
+ mdns: new MDNSBinding(),
93
+ net: {
94
+ createSocket: ()=>new net.Socket()
95
+ }
96
+ }
97
+ }
98
+
99
+ class MDNSBinding {
100
+
101
+ connect() {
102
+ this.bonjour = new Bonjour()
103
+
104
+ }
105
+
106
+ disconnect() {
107
+ if (this.bonjour) {
108
+ this.bonjour.destroy()
109
+ this.bonjour = null
110
+ }
111
+ }
112
+
113
+ find(opts , onUp) {
114
+ this.bonjour.find(opts, (s)=>{
115
+ this.handleAnnouncement(s,onUp)
116
+ })
117
+ }
118
+
119
+ handleAnnouncement(service,callback) {
120
+ const {name,txt,port,referer,protocol} = service
121
+ const announcement = {
122
+ name,address:referer?.address,protocol,port,
123
+ serialNo:txt?.['serial-number'],
124
+ serviceUUIDs:txt?.['ble-service-uuids']?.split(',')
125
+ }
126
+ if (callback)
127
+ callback(announcement)
128
+ }
129
+
130
+ }
131
+ ```
132
+
133
+
79
134
  ### Check availability of interface
80
135
 
81
136
  For some interfaces (ANT and BLE) it cannot be guaranteed that the underlying hardware supports the interface ( e.g. a USB stick might be required). Therefore this library offers a `connect` method, that allows to check if the interface is availabe
@@ -56,8 +56,8 @@ export default class AntAdapter<TDeviceData extends BaseDeviceData> extends Incy
56
56
  getProfile(): Profile;
57
57
  getLogData(data: any, excludeList: any): any;
58
58
  check(): Promise<boolean>;
59
- checkCapabilities(): Promise<void>;
60
- initControl(): Promise<void>;
59
+ protected checkCapabilities(): Promise<void>;
60
+ protected initControl(): Promise<void>;
61
61
  getDefaultStartupTimeout(): number;
62
62
  startPreChecks(props: AntDeviceProperties): Promise<'done' | 'connected' | 'connection-failed'>;
63
63
  resetStartStatus(): void;
@@ -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,30 +1,34 @@
1
1
  import BleAdapter from "./base/adapter";
2
- import { BleDeviceSettings, BleProtocol, TBleSensor } from "./types";
2
+ import { BleDeviceSettings, BleProtocol } from "./types";
3
3
  import { DeviceProperties } from "../types";
4
+ import { BleComms } from "./base/comms";
4
5
  import { BleDeviceData } from "./base/types";
5
- export interface BleAdapterInfo<T extends TBleSensor> {
6
+ export interface BleAdapterInfo {
6
7
  protocol: BleProtocol;
7
- Adapter: typeof BleAdapter<BleDeviceData, T>;
8
- Comm: typeof TBleSensor;
8
+ Adapter: typeof BleAdapter<BleDeviceData, BleComms>;
9
+ Comm: typeof BleComms;
9
10
  }
10
- export default class BleAdapterFactory<T extends TBleSensor> {
11
- transport: string;
12
- static readonly _instances: Record<string, BleAdapterFactory<any>>;
13
- implementations: BleAdapterInfo<any>[];
14
- instances: Array<BleAdapter<BleDeviceData, T>>;
15
- static getInstance(transport: string): BleAdapterFactory<any>;
16
- constructor(transport: string);
17
- getAdapterInfo(protocol: BleProtocol): BleAdapterInfo<T>;
18
- getAll(): BleAdapterInfo<T>[];
19
- createInstance(settings: BleDeviceSettings, props?: DeviceProperties): BleAdapter<BleDeviceData, T>;
11
+ export default class BleAdapterFactory {
12
+ static _instance: BleAdapterFactory;
13
+ implementations: BleAdapterInfo[];
14
+ instances: Array<BleAdapter<BleDeviceData, BleComms>>;
15
+ static getInstance(): BleAdapterFactory;
16
+ constructor();
17
+ getAdapterInfo(protocol: BleProtocol): BleAdapterInfo;
18
+ getAll(): BleAdapterInfo[];
19
+ createInstance(settings: BleDeviceSettings, props?: DeviceProperties): BleAdapter<BleDeviceData, BleComms>;
20
20
  removeInstance(query: {
21
21
  settings?: BleDeviceSettings;
22
- adapter?: BleAdapter<BleDeviceData, T>;
22
+ adapter?: BleAdapter<BleDeviceData, BleComms>;
23
23
  }): void;
24
- find(settings?: BleDeviceSettings): BleAdapter<BleDeviceData, T>;
25
- register(protocol: BleProtocol, Adapter: typeof BleAdapter<BleDeviceData, T>, Comm: typeof TBleSensor): void;
26
- getAllInstances(): Array<BleAdapter<BleDeviceData, T>>;
27
- getAllSupportedComms(): (typeof TBleSensor)[];
28
- getAllSupportedAdapters(): Array<(typeof BleAdapter<BleDeviceData, T>)>;
24
+ find(settings?: BleDeviceSettings): BleAdapter<BleDeviceData, BleComms>;
25
+ register(protocol: BleProtocol, Adapter: typeof BleAdapter<BleDeviceData, BleComms>, Comm: typeof BleComms): void;
26
+ getAllInstances(): Array<BleAdapter<BleDeviceData, BleComms>>;
27
+ getAllSupportedComms(): (typeof BleComms)[];
28
+ getAllSupportedAdapters(): Array<(typeof BleAdapter<BleDeviceData, BleComms>)>;
29
29
  getAllSupportedServices(): string[];
30
+ getDeviceClasses(peripheral: any, props?: {
31
+ protocol?: BleProtocol;
32
+ services?: string[];
33
+ }): (typeof BleComms)[];
30
34
  }
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const comms_utils_1 = require("./base/comms-utils");
3
4
  const utils_1 = require("./utils");
4
5
  class BleAdapterFactory {
5
- static getInstance(transport) {
6
- if (!BleAdapterFactory._instances[transport])
7
- BleAdapterFactory._instances[transport] = new BleAdapterFactory(transport);
8
- return BleAdapterFactory._instances[transport];
6
+ static getInstance() {
7
+ if (!BleAdapterFactory._instance)
8
+ BleAdapterFactory._instance = new BleAdapterFactory();
9
+ return BleAdapterFactory._instance;
9
10
  }
10
- constructor(transport) {
11
- this.transport = transport;
11
+ constructor() {
12
12
  this.implementations = [];
13
13
  this.instances = [];
14
14
  }
@@ -37,8 +37,7 @@ class BleAdapterFactory {
37
37
  return existing;
38
38
  }
39
39
  const info = this.getAdapterInfo(protocol);
40
- console.log('~~~~ INFO:', info);
41
- if (!(info === null || info === void 0 ? void 0 : info.Adapter))
40
+ if (!info || !info.Adapter)
42
41
  return;
43
42
  const adapter = new info.Adapter(adapterSettings, props);
44
43
  this.instances.push(adapter);
@@ -70,18 +69,42 @@ class BleAdapterFactory {
70
69
  return this.instances;
71
70
  }
72
71
  getAllSupportedComms() {
73
- const supported = this.getAll();
72
+ const supported = BleAdapterFactory.getInstance().getAll();
74
73
  return supported.map(info => info.Comm);
75
74
  }
76
75
  getAllSupportedAdapters() {
77
- const supported = this.getAll();
76
+ const supported = BleAdapterFactory.getInstance().getAll();
78
77
  return supported.map(info => info.Adapter);
79
78
  }
80
79
  getAllSupportedServices() {
81
- const supported = this.getAll();
82
- const res = ['180d', '1818', '1826', '6e40fec1'];
80
+ const supported = BleAdapterFactory.getInstance().getAll();
81
+ const res = [];
82
+ if (supported && supported.length > 0) {
83
+ supported.forEach(info => {
84
+ if (info && info.Comm && info.Comm.services) {
85
+ info.Comm.services.forEach(s => {
86
+ if (!res.includes(s))
87
+ res.push(s);
88
+ });
89
+ }
90
+ });
91
+ }
83
92
  return res;
84
93
  }
94
+ getDeviceClasses(peripheral, props = {}) {
95
+ let DeviceClasses;
96
+ const { protocol, services = peripheral.advertisement.serviceUuids } = props;
97
+ const classes = this.getAllSupportedComms();
98
+ DeviceClasses = (0, comms_utils_1.getDevicesFromServices)(classes, services);
99
+ if (protocol && DeviceClasses && DeviceClasses.length > 0) {
100
+ DeviceClasses = DeviceClasses.filter((C) => {
101
+ const device = new C({ peripheral });
102
+ if (device.getProtocol() !== protocol)
103
+ return false;
104
+ return true;
105
+ });
106
+ }
107
+ return DeviceClasses;
108
+ }
85
109
  }
86
- BleAdapterFactory._instances = {};
87
110
  exports.default = BleAdapterFactory;
@@ -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";
@@ -21,7 +21,7 @@ export default class BleAdapter<TDeviceData extends BleDeviceData, TDevice exten
21
21
  waitForPeripheral(): Promise<void>;
22
22
  updateSensor(peripheral: IBlePeripheral): void;
23
23
  close(): Promise<boolean>;
24
- getComms(): TDevice;
24
+ getSensor(): TDevice;
25
25
  isEqual(settings: BleDeviceSettings): boolean;
26
26
  isSame(adapter: IAdapter): boolean;
27
27
  isConnected(): boolean;
@@ -44,13 +44,16 @@ export default class BleAdapter<TDeviceData extends BleDeviceData, TDevice exten
44
44
  protected isStarting(): boolean;
45
45
  protected hasData(): boolean;
46
46
  protected waitForInitialData(startupTimeout: any): Promise<void>;
47
- protected checkCapabilities(): void;
47
+ protected checkCapabilities(): Promise<void>;
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
  }
@@ -63,7 +63,7 @@ class BleAdapter extends adpater_1.default {
63
63
  return true;
64
64
  });
65
65
  }
66
- getComms() {
66
+ getSensor() {
67
67
  return this.device;
68
68
  }
69
69
  isEqual(settings) {
@@ -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,14 +241,16 @@ 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() {
252
+ return __awaiter(this, void 0, void 0, function* () {
253
+ });
251
254
  }
252
255
  initControl(_props) {
253
256
  return __awaiter(this, void 0, void 0, function* () {
@@ -256,41 +259,52 @@ class BleAdapter extends adpater_1.default {
256
259
  startAdapter(startProps) {
257
260
  return __awaiter(this, void 0, void 0, function* () {
258
261
  const props = this.getStartProps(startProps);
259
- const { timeout = this.getDefaultStartupTimeout() } = startProps;
262
+ const { timeout = this.getDefaultStartupTimeout() } = startProps !== null && startProps !== void 0 ? startProps : {};
260
263
  const wasPaused = this.paused;
261
264
  const preCheckResult = yield this.startPreChecks(props);
262
265
  if (preCheckResult === 'done') {
263
266
  yield (0, utils_1.resolveNextTick)();
267
+ this.logEvent({ message: `start result: ${this.started ? 'success' : 'failed'}`, preCheckResult, device: this.getName(), interface: this.getInterface(), protocol: this.getProtocolName() });
264
268
  return this.started;
265
269
  }
266
270
  if (preCheckResult === 'connection-failed') {
267
- this.logEvent({ message: 'start result: error', error: 'could not start device, reason:could not connect', protocol: this.getProtocolName() });
271
+ 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
272
  yield (0, utils_1.resolveNextTick)();
269
273
  return false;
270
274
  }
271
- this.logEvent({ message: 'starting device', device: this.getName(), props, isStarted: this.started });
275
+ this.logEvent({ message: 'starting device', device: this.getName(), interface: this.getInterface(), props, isStarted: this.started });
272
276
  try {
277
+ this.resetData();
278
+ this.stopped = false;
273
279
  const connected = yield this.startSensor();
274
280
  if (connected) {
275
- this.logEvent({ message: 'peripheral connected', device: this.getName(), props });
281
+ this.logEvent({ message: 'peripheral connected', device: this.getName(), interface: this.getInterface(), props });
276
282
  }
277
283
  else {
278
- this.logEvent({ message: 'peripheral connection failed', device: this.getName(), reason: 'unknown', props });
284
+ this.logEvent({ message: 'peripheral connection failed', device: this.getName(), interface: this.getInterface(), reason: 'unknown', props });
285
+ this.stopped = true;
279
286
  return false;
280
287
  }
281
288
  yield this.waitForInitialData(timeout);
282
289
  yield this.checkCapabilities();
283
290
  if (this.hasCapability(types_1.IncyclistCapability.Control))
284
291
  yield this.initControl(startProps);
285
- this.resetData();
286
292
  this.stopped = false;
287
293
  this.started = true;
288
294
  if (wasPaused)
289
295
  this.resume();
296
+ if (!this.isStarting()) {
297
+ this.started = false;
298
+ this.stopped = true;
299
+ return false;
300
+ }
301
+ this.logEvent({ message: 'start result: success', device: this.getName(), interface: this.getInterface(), protocol: this.getProtocolName() });
290
302
  return true;
291
303
  }
292
304
  catch (err) {
293
- this.logEvent({ message: 'start result: error', error: err.message, protocol: this.getProtocolName() });
305
+ this.logEvent({ message: 'start result: error', error: err.message, device: this.getName(), interface: this.getInterface(), protocol: this.getProtocolName() });
306
+ this.started = false;
307
+ this.stopped = true;
294
308
  return false;
295
309
  }
296
310
  });
@@ -298,49 +312,62 @@ class BleAdapter extends adpater_1.default {
298
312
  startSensor() {
299
313
  return __awaiter(this, void 0, void 0, function* () {
300
314
  var _a;
301
- if (!((_a = this.getComms()) === null || _a === void 0 ? void 0 : _a.hasPeripheral())) {
315
+ if (!((_a = this.getSensor()) === null || _a === void 0 ? void 0 : _a.hasPeripheral())) {
302
316
  yield this.waitForPeripheral();
303
317
  }
304
- if (!this.getComms()) {
318
+ if (!this.getSensor()) {
305
319
  return false;
306
320
  }
307
- const connected = yield this.getComms().startSensor();
321
+ const sensor = this.getSensor();
322
+ const connected = yield sensor.startSensor();
323
+ yield sensor.subscribe();
308
324
  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);
325
+ sensor.on('data', this.onDeviceDataHandler);
326
+ sensor.on('disconnected', this.emit.bind(this));
327
+ sensor.on('error', console.log);
312
328
  }
313
329
  return connected;
314
330
  });
315
331
  }
316
- stop() {
332
+ onDisconnectDone() {
317
333
  return __awaiter(this, void 0, void 0, function* () {
318
- this.logEvent({ message: 'stopping device', device: this.getName() });
334
+ this.logEvent({ message: 'disconnecting device', device: this.getName(), interface: this.getInterface() });
319
335
  if (this.isStarting()) {
320
336
  yield this.startTask.stop();
321
337
  }
322
338
  let reason = 'unknown';
323
339
  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();
340
+ const sensor = this.getSensor();
329
341
  try {
330
- stopped = yield this.getComms().stopSensor();
342
+ stopped = yield sensor.stopSensor();
331
343
  }
332
344
  catch (err) {
333
345
  reason = err.message;
334
346
  }
335
- if (stopped) {
336
- this.logEvent({ message: 'device stopped', device: this.getName() });
347
+ if (!stopped) {
348
+ this.logEvent({ message: 'disconnecting device failed', device: this.getName(), interface: this.getInterface(), reason });
337
349
  }
338
- else {
339
- this.logEvent({ message: 'stopping device failed', device: this.getName(), reason });
350
+ });
351
+ }
352
+ stop() {
353
+ return __awaiter(this, void 0, void 0, function* () {
354
+ this.logEvent({ message: 'stopping device', device: this.getName(), interface: this.getInterface() });
355
+ if (this.isStarting()) {
356
+ yield this.startTask.stop();
340
357
  }
341
358
  this.started = false;
359
+ this.resetData();
360
+ if (!this.getSensor()) {
361
+ this.logEvent({ message: 'device stopped - not started yet', device: this.getName(), interface: this.getInterface() });
362
+ return true;
363
+ }
364
+ const sensor = this.getSensor();
365
+ sensor.reset();
366
+ this.resetData();
342
367
  this.stopped = true;
343
- return stopped;
368
+ this.started = false;
369
+ this.logEvent({ message: 'device stopped', device: this.getName(), interface: this.getInterface() });
370
+ return this.stopped;
344
371
  });
345
372
  }
346
373
  pause() {
@@ -349,8 +376,8 @@ class BleAdapter extends adpater_1.default {
349
376
  });
350
377
  return __awaiter(this, void 0, void 0, function* () {
351
378
  const res = yield _super.pause.call(this);
352
- const iface = interface_factory_1.BleMultiTransportInterfaceFactory.createInstance(this.getInterface());
353
- iface.pauseLogging();
379
+ const ble = this.getBle();
380
+ ble.pauseLogging();
354
381
  return res;
355
382
  });
356
383
  }
@@ -359,17 +386,24 @@ class BleAdapter extends adpater_1.default {
359
386
  resume: { get: () => super.resume }
360
387
  });
361
388
  return __awaiter(this, void 0, void 0, function* () {
362
- const iface = interface_factory_1.BleMultiTransportInterfaceFactory.createInstance(this.getInterface());
363
- iface.resumeLogging();
389
+ const ble = this.getBle();
390
+ ble.resumeLogging();
364
391
  const res = yield _super.resume.call(this);
365
392
  return res;
366
393
  });
367
394
  }
395
+ getBle() {
396
+ return interface_factory_1.BleMultiTransportInterfaceFactory.createInstance(this.getInterface());
397
+ }
368
398
  update() {
369
399
  }
370
400
  setCyclingMode(mode, settings, sendInitCommands) {
371
401
  super.setCyclingMode(mode, settings, sendInitCommands);
372
402
  this.refreshDeviceData();
373
403
  }
404
+ onScanStart() {
405
+ if (!this.isStarted())
406
+ this.start();
407
+ }
374
408
  }
375
409
  exports.default = BleAdapter;