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
@@ -1,10 +1,12 @@
1
1
  import EventEmitter from "events";
2
2
  import { DeviceSettings, InterfaceProps } from "../../types";
3
3
  import { EventLogger } from "gd-eventlog";
4
- import { BleBinding, 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";
8
+ import { BleAdapterFactory } from "../factories";
9
+ import { TBleSensor } from "./sensor";
8
10
  interface Announcement {
9
11
  service: BlePeripheralAnnouncement;
10
12
  ts: number;
@@ -27,11 +29,13 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
27
29
  protected connectTask: InteruptableTask<TaskState, boolean>;
28
30
  protected scanTask: InteruptableTask<TaskState, void>;
29
31
  protected discoverTask: InteruptableTask<TaskState, void>;
30
- protected onDiscovered: (peripheral: BlePeripheralInfo) => void;
32
+ protected onDiscovered: (peripheral: BleRawPeripheral) => void;
31
33
  protected instanceId: number;
32
34
  protected connectedPeripherals: IBlePeripheral[];
35
+ protected connectAttemptCnt: number;
33
36
  static getInstance(props?: InterfaceProps): BleInterface;
34
37
  protected constructor(props: InterfaceProps);
38
+ setProps(props: InterfaceProps): void;
35
39
  getLogger(): EventLogger;
36
40
  setLogger(logger: EventLogger): void;
37
41
  getName(): string;
@@ -39,7 +43,7 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
39
43
  getBinding(): BleBinding;
40
44
  protected autoConnect(): void;
41
45
  connect(reconnect?: boolean): Promise<boolean>;
42
- disconnect(): Promise<boolean>;
46
+ disconnect(connectionLost?: boolean): Promise<boolean>;
43
47
  isConnected(): boolean;
44
48
  registerConnected(peripheral: IBlePeripheral): void;
45
49
  protected isConnecting(): boolean;
@@ -52,15 +56,17 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
52
56
  createPeripheral(announcement: BlePeripheralAnnouncement): IBlePeripheral;
53
57
  createPeripheralFromSettings(settings: DeviceSettings): IBlePeripheral;
54
58
  waitForPeripheral(settings: DeviceSettings): Promise<IBlePeripheral>;
55
- createDeviceSetting(service: BlePeripheralAnnouncement): DeviceSettings;
59
+ createDeviceSetting(service: BlePeripheralAnnouncement): BleDeviceSettings;
56
60
  protected reconnect(): Promise<void>;
57
61
  protected startPeripheralScan(retry?: boolean): Promise<void>;
58
62
  protected stopPeripheralScan(): Promise<void>;
63
+ protected emitDisconnectAllPeripherals(): void;
64
+ protected disconnectAllPeripherals(): Promise<void>;
59
65
  protected isDiscovering(): boolean;
60
66
  protected discoverPeripherals(): Promise<void>;
61
- pauseDiscovery(): Promise<void>;
62
- resumeDiscovery(): Promise<void>;
63
67
  protected onPeripheralFound(peripheral: BleRawPeripheral): void;
68
+ protected checkForWahooEnhancement(announcement: BlePeripheralAnnouncement): boolean;
69
+ protected processWahooAnnouncement(announcement: BlePeripheralAnnouncement): void;
64
70
  protected buildAnnouncement(peripheral: BleRawPeripheral): BlePeripheralAnnouncement;
65
71
  protected updateWithServices(announcement: BlePeripheralAnnouncement): Promise<BlePeripheralAnnouncement>;
66
72
  protected discoverServices(announcement: BlePeripheralAnnouncement): Promise<string[]>;
@@ -68,10 +74,7 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
68
74
  protected startScan(): Promise<unknown>;
69
75
  private emitCachedDevices;
70
76
  protected emitDevice(service: BlePeripheralAnnouncement): void;
71
- protected buildDeviceSettings(matching?: string[]): {
72
- interface: string;
73
- name: string;
74
- }[];
77
+ protected buildDeviceSettings(matching?: string[]): BleDeviceSettings[];
75
78
  protected addCompleting(service: BlePeripheralAnnouncement): void;
76
79
  protected addUnsupported(service: BlePeripheralAnnouncement): void;
77
80
  protected isKnownUnsupported(service: BlePeripheralAnnouncement): boolean;
@@ -84,7 +87,13 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
84
87
  setDebug(enabled: boolean): void;
85
88
  protected connectBle(): Promise<boolean>;
86
89
  protected waitForBleConnected(): Promise<boolean>;
90
+ protected onError(err: Error): void;
91
+ protected onConnected(): void;
92
+ protected onDisconnected(): Promise<void>;
87
93
  protected onBleStateChange(state: BleInterfaceState): void;
94
+ protected getAdapterFactory(): BleAdapterFactory<TBleSensor>;
95
+ protected getConnectTimeout(): number;
96
+ protected getExpectedServices(): string[];
88
97
  logEvent(event: any): void;
89
98
  logError(err: Error, fn: string, args?: any): void;
90
99
  }
@@ -20,7 +20,6 @@ const peripheral_1 = require("./peripheral");
20
20
  const utils_1 = require("../utils");
21
21
  const types_1 = require("./types");
22
22
  const factories_1 = require("../factories");
23
- const BLE_DEFAULT_SCAN_TIMEOUT = 30 * 1000;
24
23
  const BLE_EXPIRATION_TIMEOUT = 10 * 1000 * 60;
25
24
  const BLE_DEFAULT_CONNECT_TIMEOUT = 30 * 1000;
26
25
  let instanceCount = 0;
@@ -29,6 +28,7 @@ class BleInterface extends events_1.default {
29
28
  if (BleInterface._instance === undefined)
30
29
  BleInterface._instance = new BleInterface(props);
31
30
  else {
31
+ BleInterface._instance.setProps(props);
32
32
  if (props.binding) {
33
33
  BleInterface._instance.setBinding(props.binding);
34
34
  }
@@ -50,6 +50,7 @@ class BleInterface extends events_1.default {
50
50
  this.expectedServices = ['180d', '1818', '1826', '6e40fec1'];
51
51
  this.matching = [];
52
52
  this.connectedPeripherals = [];
53
+ this.connectAttemptCnt = 0;
53
54
  this.instanceId = ++instanceCount;
54
55
  this.props = props;
55
56
  this.logEnabled = props.log || true;
@@ -60,9 +61,13 @@ class BleInterface extends events_1.default {
60
61
  }
61
62
  this.internalEvents = new events_1.default();
62
63
  this.onDiscovered = this.onPeripheralFound.bind(this);
63
- if (this.binding)
64
+ const { enabled = true } = props;
65
+ if (this.binding && enabled)
64
66
  this.autoConnect();
65
67
  }
68
+ setProps(props) {
69
+ this.props = props;
70
+ }
66
71
  getLogger() {
67
72
  return this.logger;
68
73
  }
@@ -73,7 +78,11 @@ class BleInterface extends events_1.default {
73
78
  return BleInterface.INTERFACE_NAME;
74
79
  }
75
80
  setBinding(binding) {
81
+ const prev = this.binding;
76
82
  this.binding = binding;
83
+ if (!prev && !this.isConnected() && this.props.enabled) {
84
+ this.autoConnect();
85
+ }
77
86
  }
78
87
  getBinding() {
79
88
  return this.binding;
@@ -88,46 +97,54 @@ class BleInterface extends events_1.default {
88
97
  return false;
89
98
  }
90
99
  if (this.isConnecting()) {
91
- this.logEvent({ message: 'connect - already connecting' });
100
+ this.logEvent({ message: 'BLE connect - already connecting' });
92
101
  return this.connectTask.getPromise();
93
102
  }
94
103
  if (this.isConnected())
95
104
  return true;
96
- this.logEvent({ message: 'Ble connect request' });
105
+ this.logEvent({ message: 'BLE connect request' });
97
106
  this.connectTask = new task_1.InteruptableTask(this.connectBle(), {
98
- timeout: BLE_DEFAULT_CONNECT_TIMEOUT,
99
- name: 'connect',
107
+ timeout: this.getConnectTimeout(),
108
+ name: 'BLE connect',
100
109
  errorOnTimeout: false,
101
110
  log: this.logEvent.bind(this),
102
111
  });
103
- const success = yield this.connectTask.run();
112
+ const success = yield this.connectTask.run().catch(() => false);
104
113
  if (success) {
105
114
  this.startPeripheralScan();
106
115
  }
107
- this.expectedServices = factories_1.BleAdapterFactory.getInstance('ble').getAllSupportedServices();
108
116
  return success;
109
117
  });
110
118
  }
111
- disconnect() {
119
+ disconnect(connectionLost) {
112
120
  return __awaiter(this, void 0, void 0, function* () {
121
+ var _a;
113
122
  if (!this.getBinding()) {
114
123
  return false;
115
124
  }
116
- if (!this.isConnected())
125
+ if (!this.isConnected() && !connectionLost)
117
126
  return true;
118
- this.logEvent({ message: 'disconnect request' });
127
+ if (!connectionLost)
128
+ this.logEvent({ message: 'disconnect request' });
129
+ this.emit('disconnect-request');
119
130
  yield this.stopPeripheralScan();
120
- const promises = this.connectedPeripherals.map(p => p.disconnect());
121
- yield Promise.allSettled(promises);
122
- this.connectedPeripherals = [];
123
- yield this.connectTask.stop();
131
+ if (connectionLost) {
132
+ this.emitDisconnectAllPeripherals();
133
+ }
134
+ else {
135
+ yield this.disconnectAllPeripherals();
136
+ }
137
+ if (this.isConnecting())
138
+ yield ((_a = this.connectTask) === null || _a === void 0 ? void 0 : _a.stop());
124
139
  this.getBinding().removeAllListeners();
140
+ this.connectAttemptCnt = 0;
141
+ this.emit('disconnect-done');
125
142
  return true;
126
143
  });
127
144
  }
128
145
  isConnected() {
129
146
  var _a;
130
- return ((_a = this.getBinding()) === null || _a === void 0 ? void 0 : _a.state) === 'poweredOn';
147
+ return this.connectAttemptCnt > 0 && ((_a = this.getBinding()) === null || _a === void 0 ? void 0 : _a.state) === 'poweredOn';
131
148
  }
132
149
  registerConnected(peripheral) {
133
150
  this.connectedPeripherals.push(peripheral);
@@ -145,7 +162,7 @@ class BleInterface extends events_1.default {
145
162
  .then(() => { return this.onScanDone(); })
146
163
  .catch(() => []);
147
164
  }
148
- this.logEvent({ message: 'starting scan ..' });
165
+ this.logEvent({ message: 'starting scan ..', interface: 'ble' });
149
166
  this.scanTask = new task_1.InteruptableTask(this.startScan(), {
150
167
  timeout: props.timeout,
151
168
  name: 'scan',
@@ -162,10 +179,13 @@ class BleInterface extends events_1.default {
162
179
  });
163
180
  }
164
181
  stopScan() {
165
- if (!this.isScanning())
166
- return Promise.resolve(true);
167
- this.logEvent({ message: 'stopping scan ...' });
168
- this.scanTask.stop();
182
+ return __awaiter(this, void 0, void 0, function* () {
183
+ if (!this.isScanning())
184
+ return true;
185
+ this.logEvent({ message: 'stopping scan ...', interface: 'ble' });
186
+ const res = yield this.scanTask.stop();
187
+ return (res === true);
188
+ });
169
189
  }
170
190
  onScanDone() {
171
191
  this.logEvent({ message: 'scan stopped' });
@@ -173,10 +193,14 @@ class BleInterface extends events_1.default {
173
193
  return this.buildDeviceSettings(this.matching);
174
194
  }
175
195
  pauseLogging() {
196
+ this.logEvent({ message: 'pausing logging' });
176
197
  this.logDisabled = true;
198
+ this.getBinding().pauseLogging();
177
199
  }
178
200
  resumeLogging() {
201
+ this.getBinding().resumeLogging();
179
202
  this.logDisabled = false;
203
+ this.logEvent({ message: 'resuming logging' });
180
204
  }
181
205
  isLoggingPaused() {
182
206
  return this.logDisabled;
@@ -195,11 +219,16 @@ class BleInterface extends events_1.default {
195
219
  if (peripheral)
196
220
  return Promise.resolve(peripheral);
197
221
  return new Promise((done) => {
222
+ const wasDiscovering = this.isDiscovering();
223
+ if (!wasDiscovering)
224
+ this.startPeripheralScan();
198
225
  const onDevice = (device) => {
199
226
  if (device.name === settings.name) {
200
227
  const peripheral = this.createPeripheralFromSettings(settings);
201
228
  if (peripheral) {
202
229
  this.off('device', onDevice);
230
+ if (!wasDiscovering)
231
+ this.stopPeripheralScan();
203
232
  done(peripheral);
204
233
  }
205
234
  }
@@ -208,8 +237,12 @@ class BleInterface extends events_1.default {
208
237
  });
209
238
  }
210
239
  createDeviceSetting(service) {
211
- const name = service.name;
212
- return { interface: BleInterface.INTERFACE_NAME, name };
240
+ const { peripheral } = service;
241
+ if (peripheral.address === undefined || peripheral.address === '')
242
+ peripheral.address = peripheral.id || peripheral.name;
243
+ const protocol = this.getAdapterFactory().getProtocol(service.serviceUUIDs);
244
+ const { id, name, address } = (0, utils_1.getPeripheralInfo)(peripheral);
245
+ return { interface: BleInterface.INTERFACE_NAME, protocol, id, name, address };
213
246
  }
214
247
  reconnect() {
215
248
  return __awaiter(this, void 0, void 0, function* () {
@@ -219,6 +252,7 @@ class BleInterface extends events_1.default {
219
252
  }
220
253
  startPeripheralScan() {
221
254
  return __awaiter(this, arguments, void 0, function* (retry = false) {
255
+ this.expectedServices = this.getExpectedServices();
222
256
  if (!retry)
223
257
  this.logEvent({ message: 'starting peripheral discovery ...' });
224
258
  if (!this.isConnected() || this.isDiscovering()) {
@@ -245,13 +279,28 @@ class BleInterface extends events_1.default {
245
279
  return;
246
280
  this.logEvent({ message: 'stopping peripheral discovery ...' });
247
281
  this.discoverTask.stop();
248
- this.getBinding().off('discover', this.onDiscovered);
282
+ const ble = this.getBinding();
283
+ ble.off('discover', this.onDiscovered);
249
284
  return new Promise(done => {
250
- this.getBinding().stopScanning(() => {
285
+ ble.stopScanning(() => {
251
286
  done();
252
287
  });
253
288
  });
254
289
  }
290
+ emitDisconnectAllPeripherals() {
291
+ this.connectedPeripherals.forEach(p => {
292
+ const peripheral = p.getPeripheral();
293
+ peripheral.emit('disconnect');
294
+ });
295
+ this.connectedPeripherals = [];
296
+ }
297
+ disconnectAllPeripherals() {
298
+ return __awaiter(this, void 0, void 0, function* () {
299
+ const promises = this.connectedPeripherals.map(p => p.disconnect());
300
+ yield Promise.allSettled(promises);
301
+ this.connectedPeripherals = [];
302
+ });
303
+ }
255
304
  isDiscovering() {
256
305
  var _a;
257
306
  return ((_a = this.discoverTask) === null || _a === void 0 ? void 0 : _a.isRunning()) === true;
@@ -275,21 +324,6 @@ class BleInterface extends events_1.default {
275
324
  });
276
325
  });
277
326
  }
278
- pauseDiscovery() {
279
- this.getBinding().off('discover', this.onDiscovered);
280
- return new Promise(done => {
281
- try {
282
- this.getBinding().stopScanning();
283
- done();
284
- }
285
- catch (err) {
286
- done();
287
- }
288
- });
289
- }
290
- resumeDiscovery() {
291
- return this.discoverPeripherals();
292
- }
293
327
  onPeripheralFound(peripheral) {
294
328
  if (!this.isConnected() || !this.isDiscovering())
295
329
  return;
@@ -303,24 +337,33 @@ class BleInterface extends events_1.default {
303
337
  return;
304
338
  }
305
339
  if (announcement.serviceUUIDs.length === 0) {
306
- if (this.isCompleting(announcement)) {
307
- return;
308
- }
309
- this.addCompleting(announcement);
310
- setTimeout(() => {
311
- if (this.find(announcement)) {
312
- this.removeCompleting(announcement);
313
- return;
314
- }
315
- this.updateWithServices(announcement)
316
- .then(() => {
317
- if (this.isSupportedPeripheral(announcement))
318
- this.addService(announcement);
319
- });
320
- }, 1000);
340
+ return;
341
+ }
342
+ const isWahoo = this.checkForWahooEnhancement(announcement);
343
+ if (isWahoo) {
344
+ this.processWahooAnnouncement(announcement);
345
+ return;
321
346
  }
322
347
  this.addService(announcement);
323
348
  }
349
+ checkForWahooEnhancement(announcement) {
350
+ if (announcement.name.includes('KICKR')) {
351
+ const supported = announcement.serviceUUIDs.map(s => (0, utils_1.beautifyUUID)(s));
352
+ if (supported.length === 1 && supported[0] === '1818')
353
+ return true;
354
+ }
355
+ return false;
356
+ }
357
+ processWahooAnnouncement(announcement) {
358
+ if (this.isCompleting(announcement)) {
359
+ return;
360
+ }
361
+ this.updateWithServices(announcement)
362
+ .then(() => {
363
+ if (this.isSupportedPeripheral(announcement))
364
+ this.addService(announcement);
365
+ });
366
+ }
324
367
  buildAnnouncement(peripheral) {
325
368
  var _a;
326
369
  return {
@@ -335,9 +378,10 @@ class BleInterface extends events_1.default {
335
378
  return __awaiter(this, void 0, void 0, function* () {
336
379
  if (!this.isConnected() || !this.isDiscovering())
337
380
  return;
381
+ this.addCompleting(announcement);
382
+ this.logEvent({ message: 'updateWithServices', peripheral: announcement.name });
338
383
  try {
339
- yield this.discoverServices(announcement);
340
- return announcement;
384
+ announcement.serviceUUIDs = yield this.discoverServices(announcement);
341
385
  }
342
386
  catch (err) {
343
387
  this.logError(err, 'updateWithServices');
@@ -350,15 +394,14 @@ class BleInterface extends events_1.default {
350
394
  const device = Object.assign({}, announcement);
351
395
  delete device.peripheral;
352
396
  const { peripheral } = announcement;
353
- let paused = false;
354
397
  try {
355
398
  peripheral.on('error', (err) => {
356
399
  peripheral.removeAllListeners();
357
- this.logEvent({ message: 'Device error', error: err.message });
400
+ this.logEvent({ message: 'peripheral error', error: err.message });
358
401
  });
359
402
  peripheral.on('disconnect', () => {
360
403
  peripheral.removeAllListeners();
361
- this.logEvent({ message: 'Device disconnected' });
404
+ this.logEvent({ message: 'peripheral disconnected' });
362
405
  });
363
406
  yield peripheral.connectAsync();
364
407
  if (peripheral.discoverServicesAsync !== undefined) {
@@ -369,15 +412,12 @@ class BleInterface extends events_1.default {
369
412
  const res = yield peripheral.discoverSomeServicesAndCharacteristicsAsync([], []);
370
413
  announcement.serviceUUIDs = res.services.map(s => s.uuid);
371
414
  }
372
- peripheral.removeAllListeners();
373
415
  }
374
416
  catch (err) {
375
417
  this.logEvent({ message: 'discover services failed', reason: err.message, device });
376
418
  }
377
- if (paused) {
378
- yield this.resumeDiscovery();
379
- }
380
- return device.serviceUUIDs;
419
+ peripheral === null || peripheral === void 0 ? void 0 : peripheral.removeAllListeners();
420
+ return announcement.serviceUUIDs;
381
421
  });
382
422
  }
383
423
  isScanning() {
@@ -399,10 +439,14 @@ class BleInterface extends events_1.default {
399
439
  }
400
440
  emitDevice(service) {
401
441
  const settings = this.createDeviceSetting(service);
442
+ this.logEvent({ message: 'device found', settings });
402
443
  this.emit('device', settings, service);
403
444
  }
404
445
  buildDeviceSettings(matching = []) {
405
- return matching.map((name) => ({ interface: BleInterface.INTERFACE_NAME, name }));
446
+ return matching.map((name) => {
447
+ const announcement = this.services.find(s => s.service.name === name);
448
+ return this.createDeviceSetting(announcement.service);
449
+ });
406
450
  }
407
451
  addCompleting(service) {
408
452
  const existing = this.incompleteServices.find(s => s.name === service.name);
@@ -468,7 +512,7 @@ class BleInterface extends events_1.default {
468
512
  const expected = this.expectedServices.map(utils_1.parseUUID);
469
513
  const supported = (_b = found.filter(uuid => expected.includes(uuid))) !== null && _b !== void 0 ? _b : [];
470
514
  if (!supported.length) {
471
- this.logEvent({ message: 'service not supported', name: service.name, uuids: service.serviceUUIDs });
515
+ this.logEvent({ message: 'peripheral not supported', name: service.name, uuids: service.serviceUUIDs });
472
516
  this.addUnsupported(service);
473
517
  }
474
518
  return supported.length > 0;
@@ -484,8 +528,10 @@ class BleInterface extends events_1.default {
484
528
  }
485
529
  connectBle() {
486
530
  return __awaiter(this, void 0, void 0, function* () {
531
+ this.connectAttemptCnt++;
487
532
  const state = this.getBinding().state;
488
533
  if (state === 'poweredOn') {
534
+ this.logEvent({ message: 'BLE connected' });
489
535
  return true;
490
536
  }
491
537
  const res = yield this.waitForBleConnected();
@@ -500,10 +546,7 @@ class BleInterface extends events_1.default {
500
546
  });
501
547
  this.getBinding().on('stateChange', (state) => {
502
548
  if (state === 'poweredOn') {
503
- this.logEvent({ message: 'Ble connect result: success' });
504
- this.getBinding().removeAllListeners('stateChange');
505
- this.getBinding().on('stateChange', this.onBleStateChange.bind(this));
506
- this.getBinding().on('error', console.log);
549
+ this.onConnected();
507
550
  return done(true);
508
551
  }
509
552
  else {
@@ -512,18 +555,50 @@ class BleInterface extends events_1.default {
512
555
  });
513
556
  });
514
557
  }
558
+ onError(err) {
559
+ this.logError(err, 'BLE connect');
560
+ }
561
+ onConnected() {
562
+ this.logEvent({ message: 'BLE connected' });
563
+ this.getBinding().removeAllListeners('error');
564
+ this.getBinding().removeAllListeners('stateChange');
565
+ this.getBinding().on('stateChange', this.onBleStateChange.bind(this));
566
+ this.getBinding().on('error', this.onError.bind(this));
567
+ }
568
+ onDisconnected() {
569
+ return __awaiter(this, void 0, void 0, function* () {
570
+ this.logEvent({ message: 'BLE Disconnected' });
571
+ yield this.disconnect(true);
572
+ this.getBinding().on('stateChange', this.onBleStateChange.bind(this));
573
+ this.getBinding().on('error', this.onError.bind(this));
574
+ });
575
+ }
515
576
  onBleStateChange(state) {
577
+ if (state !== 'poweredOn') {
578
+ this.onDisconnected();
579
+ }
580
+ else
581
+ this.onConnected();
582
+ }
583
+ getAdapterFactory() {
584
+ return factories_1.BleAdapterFactory.getInstance('ble');
585
+ }
586
+ getConnectTimeout() {
587
+ return BLE_DEFAULT_CONNECT_TIMEOUT;
588
+ }
589
+ getExpectedServices() {
590
+ return this.getAdapterFactory().getAllSupportedServices();
516
591
  }
517
592
  logEvent(event) {
518
593
  if (this.logDisabled && event.message !== 'Error')
519
594
  return;
520
- this.getLogger().logEvent(event);
595
+ this.getLogger().logEvent(Object.assign(Object.assign({}, event), { interface: 'ble' }));
521
596
  const emitPayload = Object.assign({}, event);
522
597
  delete emitPayload.ts;
523
598
  this.emit('log', emitPayload);
524
599
  const w = global.window;
525
600
  if (this.debug || (w === null || w === void 0 ? void 0 : w.SERVICE_DEBUG) || process.env.DEBUG)
526
- console.log(`~~~ ${this.logger.getName().toUpperCase()}-SVC`, event);
601
+ console.log(`~~~ ${this.logger.getName().toUpperCase()}-SVC`, Object.assign(Object.assign({}, event), { interface: 'ble' }));
527
602
  }
528
603
  logError(err, fn, args) {
529
604
  const logInfo = args || {};
@@ -11,22 +11,26 @@ export declare class BlePeripheral implements IBlePeripheral {
11
11
  callback: (data: Buffer) => void;
12
12
  }>;
13
13
  protected disconnecting: boolean;
14
+ protected onErrorHandler: any;
14
15
  constructor(announcement: BlePeripheralAnnouncement);
15
16
  get services(): BleService[];
16
- protected getPeripheral(): BleRawPeripheral;
17
+ getPeripheral(): BleRawPeripheral;
17
18
  connect(): Promise<boolean>;
18
- disconnect(): Promise<boolean>;
19
+ disconnect(connectionLost?: boolean): Promise<boolean>;
19
20
  isConnected(): boolean;
20
21
  isConnecting(): boolean;
21
22
  onDisconnect(callback: () => void): void;
23
+ protected onPeripheralDisconnect(): Promise<void>;
24
+ protected onPeripheralError(err: Error): void;
22
25
  discoverServices(): Promise<string[]>;
23
26
  discoverCharacteristics(serviceUUID: string): Promise<BleCharacteristic[]>;
24
27
  subscribe(characteristicUUID: string, callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
25
28
  unsubscribe(characteristicUUID: string): Promise<boolean>;
26
29
  subscribeSelected(characteristics: string[], callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
27
30
  discoverAllCharacteristics(): Promise<string[]>;
31
+ discoverSomeCharacteristics(characteristics: string[]): Promise<string[]>;
28
32
  subscribeAll(callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
29
- unsubscribeAll(): Promise<boolean>;
33
+ unsubscribeAll(connectionLost?: boolean): Promise<void>;
30
34
  read(characteristicUUID: string): Promise<Buffer>;
31
35
  write(characteristicUUID: string, data: Buffer, options?: BleWriteProps): Promise<Buffer>;
32
36
  protected getRawCharacteristic(uuid: string): BleRawCharacteristic;