incyclist-devices 2.0.6 → 2.0.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.
@@ -65,8 +65,9 @@ class IncyclistDevice extends events_1.default {
65
65
  if (!this.logger || this.paused)
66
66
  return;
67
67
  this.logger.logEvent(event);
68
- if (process.env.BLE_DEBUG || process.env.ANT_DEBUG) {
69
- const logText = '~~~' + this.getInterface().toUpperCase();
68
+ const w = global.window;
69
+ if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG || process.env.ANT_DEBUG) {
70
+ const logText = '~~~ ' + this.getInterface().toUpperCase();
70
71
  console.log(logText, event);
71
72
  }
72
73
  }
@@ -88,8 +88,9 @@ class BleComms extends events_1.default {
88
88
  if (this.logger) {
89
89
  this.logger.logEvent(event);
90
90
  }
91
- if (process.env.BLE_DEBUG) {
92
- console.log('~~~BLE:', event);
91
+ const w = global.window;
92
+ if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG) {
93
+ console.log('~~~ BLE', event);
93
94
  }
94
95
  }
95
96
  setLogger(logger) {
@@ -203,12 +204,12 @@ class BleComms extends events_1.default {
203
204
  yield connector.connect();
204
205
  if (disconnectSignalled)
205
206
  return;
206
- yield connector.initialize();
207
- if (disconnectSignalled)
208
- return;
207
+ const initialized = yield connector.initialize();
208
+ if (!initialized || disconnectSignalled)
209
+ return done(false);
209
210
  yield this.subscribeAll(connector);
210
211
  if (disconnectSignalled)
211
- return;
212
+ return done(false);
212
213
  this.connectState.isConnected = true;
213
214
  this.state = "connected";
214
215
  this.emit('connected');
@@ -229,6 +230,7 @@ class BleComms extends events_1.default {
229
230
  });
230
231
  }
231
232
  subscribeMultiple(characteristics, conn) {
233
+ this.logEvent({ message: 'subscribe', characteristics });
232
234
  return new Promise(resolve => {
233
235
  try {
234
236
  const connector = conn || this.ble.peripheralCache.getConnector(this.peripheral);
@@ -317,6 +319,9 @@ class BleComms extends events_1.default {
317
319
  const { id, name, address } = this;
318
320
  try {
319
321
  this.peripheral = this.ble.peripheralCache.getPeripheral({ id, name, address });
322
+ const connector = this.ble.peripheralCache.getConnector(this.peripheral);
323
+ if (!connector) {
324
+ }
320
325
  }
321
326
  catch (err) {
322
327
  this.logEvent({ message: 'error', fn: 'connect()', error: err.message, stack: err.stack });
@@ -342,7 +347,7 @@ class BleComms extends events_1.default {
342
347
  if (this.ble.isScanning()) {
343
348
  yield this.ble.stopScan();
344
349
  }
345
- const peripheral = yield this.ble.scanForDevice(this, {}).catch(() => null);
350
+ const peripheral = yield this.ble.scanForDevice(this, {});
346
351
  if (peripheral) {
347
352
  this.peripheral = peripheral;
348
353
  const connected = yield this.connectPeripheral(this.peripheral);
@@ -354,11 +359,10 @@ class BleComms extends events_1.default {
354
359
  }
355
360
  }
356
361
  catch (err) {
357
- console.log('~~~ ERROR', err);
358
362
  error = err;
359
363
  }
360
364
  }
361
- this.logEvent({ message: 'connect result: failure', mode: 'device', device: { id, name, address }, error: error.message, stack: error.stack });
365
+ this.logEvent({ message: 'connect result: failure', mode: 'device', device: { id, name, address }, error: error.message });
362
366
  this.connectState.isConnecting = false;
363
367
  this.connectState.isConnected = false;
364
368
  this.ble.stopConnectSensor();
@@ -368,7 +372,7 @@ class BleComms extends events_1.default {
368
372
  catch (err) {
369
373
  this.connectState.isConnecting = false;
370
374
  this.connectState.isConnected = false;
371
- this.logEvent({ message: 'connect result: error', error: err.message });
375
+ this.logEvent({ message: 'connect result: error', error: err.message, stack: err.stack });
372
376
  this.ble.stopConnectSensor();
373
377
  return false;
374
378
  }
@@ -15,6 +15,7 @@ export interface ScanState {
15
15
  isBackgroundScan: boolean;
16
16
  timeout?: NodeJS.Timeout;
17
17
  peripherals?: Map<string, BlePeripheral>;
18
+ detected?: string[];
18
19
  }
19
20
  export interface ConnectState {
20
21
  isConnecting: boolean;
@@ -80,13 +80,16 @@ class BleInterface extends events_1.default {
80
80
  if (this.logger) {
81
81
  this.logger.logEvent(event);
82
82
  }
83
- if (process.env.BLE_DEBUG) {
84
- console.log('~~BLE:', event);
83
+ const w = global.window;
84
+ if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG) {
85
+ console.log('~~~ BLE', event);
85
86
  }
86
87
  }
87
88
  onStateChange(state) {
88
89
  if (state !== 'poweredOn') {
90
+ this.logEvent({ message: 'Ble disconnected', });
89
91
  this.connectState.isConnected = false;
92
+ this.stopConnectSensor();
90
93
  }
91
94
  else {
92
95
  this.connectState.isConnected = true;
@@ -225,7 +228,9 @@ class BleInterface extends events_1.default {
225
228
  chachedPeripheralInfo.state = { isConfigured: false, isLoading: true, isInterrupted: false };
226
229
  yield connector.connect();
227
230
  peripheral.state = connector.getState();
228
- yield connector.initialize();
231
+ const initialized = yield connector.initialize();
232
+ if (!initialized)
233
+ return null;
229
234
  characteristics = connector.getCharachteristics();
230
235
  this.logEvent({ message: 'characteristic info (+):', address: peripheral.address, info: characteristics.map(utils_1.getCharachteristicsInfo) });
231
236
  chachedPeripheralInfo.characteristics = characteristics;
@@ -261,6 +266,7 @@ class BleInterface extends events_1.default {
261
266
  });
262
267
  }
263
268
  onPeripheralFound(p, callback, props = {}) {
269
+ var _a;
264
270
  return __awaiter(this, void 0, void 0, function* () {
265
271
  let peripheral = p;
266
272
  if (!peripheral || !peripheral.advertisement || !peripheral.advertisement.localName) {
@@ -279,18 +285,30 @@ class BleInterface extends events_1.default {
279
285
  if (isPeripheralProcessed) {
280
286
  return;
281
287
  }
288
+ if (scanForDevice) {
289
+ const alreadyDetected = ((_a = this.scanState.detected) === null || _a === void 0 ? void 0 : _a.find(p => p === peripheral.address)) !== undefined;
290
+ if (alreadyDetected)
291
+ return;
292
+ this.scanState.detected.push(peripheral.address);
293
+ }
282
294
  if (scanForDevice) {
283
295
  let found = false;
284
296
  found =
285
- (request.name && peripheral.advertisement && request.name === peripheral.advertisement.localName) ||
286
- (request.address && request.address === peripheral.address);
297
+ (request.name !== undefined && peripheral.advertisement && request.name === peripheral.advertisement.localName) ||
298
+ (request.address !== undefined && request.address === peripheral.address);
299
+ this.logEvent({ message: 'search device: found device', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), scanForDevice, matching: found });
287
300
  if (!found) {
288
301
  return;
289
302
  }
290
- this.logEvent({ message: 'search device: found device', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), scanForDevice, callback: callback !== undefined });
291
303
  this.scanState.peripherals.set(peripheral.address, peripheral);
292
304
  const characteristics = yield this.getCharacteristics(peripheral);
293
- callback(peripheral, characteristics);
305
+ if (characteristics) {
306
+ callback(peripheral, characteristics);
307
+ }
308
+ else {
309
+ callback(null);
310
+ }
311
+ this.stopScan();
294
312
  return;
295
313
  }
296
314
  else {
@@ -299,13 +317,16 @@ class BleInterface extends events_1.default {
299
317
  const { protocolFilter } = props;
300
318
  const connector = this.peripheralCache.getConnector(p);
301
319
  const characteristics = yield this.getCharacteristics(p);
320
+ if (!characteristics) {
321
+ return callback(null);
322
+ }
302
323
  const announcedServices = connector.getServices();
303
324
  const services = announcedServices ? announcedServices.map(utils_1.uuid) : undefined;
304
325
  peripheral = connector.getPeripheral();
305
326
  const DeviceClasses = this.getAdapterFactory().getDeviceClasses(peripheral, { services }) || [];
306
327
  const MatchingClasses = protocolFilter && DeviceClasses ? DeviceClasses.filter(C => protocolFilter.includes(C.protocol)) : DeviceClasses;
307
328
  const DeviceClass = (0, comms_utils_1.getBestDeviceMatch)(MatchingClasses.filter(C => C.isMatching(characteristics.map(c => c.uuid))));
308
- this.logEvent({ message: 'BLE scan: device connected', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), services, protocols: DeviceClasses.map(c => c.protocol) });
329
+ this.logEvent({ message: 'BLE scan: device connected', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), services, protocols: DeviceClasses.map(c => c.protocol), found: DeviceClass !== undefined });
309
330
  if (!DeviceClass)
310
331
  return callback(null);
311
332
  const { id, name, address } = (0, utils_1.getPeripheralInfo)(peripheral);
@@ -342,6 +363,7 @@ class BleInterface extends events_1.default {
342
363
  return new Promise((resolve, reject) => {
343
364
  this.scanState.isScanning = true;
344
365
  this.scanState.peripherals = new Map();
366
+ this.scanState.detected = [];
345
367
  const onTimeout = () => {
346
368
  if (!this.scanState.isScanning || !this.scanState.timeout)
347
369
  return;
@@ -360,7 +382,7 @@ class BleInterface extends events_1.default {
360
382
  if (protocol !== 'tacx') {
361
383
  services = (device.getComms().getServices()) || [];
362
384
  }
363
- ble.startScanning(services, false, (err) => {
385
+ ble.startScanning(services, true, (err) => {
364
386
  if (err) {
365
387
  this.logEvent({ message: `${opStr} result: error`, request, error: err.message });
366
388
  this.scanState.isScanning = false;
@@ -368,6 +390,8 @@ class BleInterface extends events_1.default {
368
390
  }
369
391
  ble.on('discover', (p) => {
370
392
  this.onPeripheralFound(p, (peripheral, characteristics) => {
393
+ if (!peripheral)
394
+ return reject(new Error('could not connect'));
371
395
  device.getComms().characteristics = characteristics;
372
396
  process.nextTick(() => {
373
397
  if (this.scanState.timeout) {
@@ -6,6 +6,7 @@ export type ConnectorState = {
6
6
  isInitializing: boolean;
7
7
  isSubscribing: boolean;
8
8
  subscribed?: string[];
9
+ connectPromise?: Promise<void>;
9
10
  };
10
11
  export default class BlePeripheralConnector implements IBlePeripheralConnector {
11
12
  private state;
@@ -20,7 +21,7 @@ export default class BlePeripheralConnector implements IBlePeripheralConnector {
20
21
  connect(): Promise<void>;
21
22
  reconnect(): Promise<void>;
22
23
  onDisconnect(): void;
23
- initialize(enforce?: boolean): Promise<void>;
24
+ initialize(enforce?: boolean): Promise<boolean>;
24
25
  isSubscribed(characteristicUuid: string): boolean;
25
26
  subscribeAll(callback: (characteristicUuid: string, data: any) => void): Promise<string[]>;
26
27
  subscribe(characteristicUuid: string, timeout?: number): Promise<boolean>;
@@ -32,8 +32,9 @@ class BlePeripheralConnector {
32
32
  if (this.logger) {
33
33
  this.logger.logEvent(event);
34
34
  }
35
- if (process.env.BLE_DEBUG) {
36
- console.log('~~~BLE:', event);
35
+ const w = global.window;
36
+ if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG) {
37
+ console.log('~~~ BLE', event);
37
38
  }
38
39
  }
39
40
  connect() {
@@ -41,18 +42,25 @@ class BlePeripheralConnector {
41
42
  if (this.state.isConnected)
42
43
  return;
43
44
  this.logEvent({ message: 'connect peripheral', peripheral: this.peripheral.address, state: this.state, peripheralState: this.peripheral.state });
45
+ const wasConnecting = this.state.isConnecting;
44
46
  this.state.isConnecting = true;
45
47
  try {
46
- this.peripheral.on('disconnect', () => { this.onDisconnect(); });
47
- if (!this.state.isConnected || (this.peripheral && this.peripheral.state !== 'connected')) {
48
- yield this.peripheral.connectAsync();
48
+ if (!wasConnecting) {
49
+ this.peripheral.once('disconnect', () => { this.onDisconnect(); });
50
+ if (!this.state.isConnected || (this.peripheral && this.peripheral.state !== 'connected')) {
51
+ this.state.connectPromise = this.peripheral.connectAsync();
52
+ }
49
53
  }
54
+ if (this.state.connectPromise)
55
+ yield this.state.connectPromise;
50
56
  this.state.isConnected = this.peripheral.state === 'connected';
57
+ this.state.connectPromise = undefined;
51
58
  return;
52
59
  }
53
60
  catch (err) {
54
61
  this.logEvent({ message: 'Error', fn: 'connect()', error: err.message });
55
62
  }
63
+ this.state.connectPromise = undefined;
56
64
  this.state.isConnecting = false;
57
65
  });
58
66
  }
@@ -69,43 +77,55 @@ class BlePeripheralConnector {
69
77
  this.state.isConnecting = false;
70
78
  this.state.isInitialized = false;
71
79
  this.state.isInitializing = false;
80
+ this.state.connectPromise = undefined;
81
+ this.state.isSubscribing = false;
82
+ this.state.subscribed = [];
72
83
  this.emitter.emit('disconnect');
73
84
  }
74
85
  initialize(enforce = false) {
75
86
  return __awaiter(this, void 0, void 0, function* () {
76
- if (this.state.isInitialized && !enforce)
77
- return;
78
87
  this.logEvent({ message: 'initialize', peripheral: this.peripheral.address, state: this.state, enforce });
88
+ if (this.state.isInitialized && !enforce)
89
+ return true;
79
90
  if (this.state.isInitialized && enforce) {
80
91
  this.state.isInitialized = false;
81
92
  }
82
- this.state.isInitializing = true;
83
- this.characteristics = undefined;
84
- this.services = undefined;
85
- try {
86
- const res = yield this.peripheral.discoverSomeServicesAndCharacteristicsAsync([], []);
87
- if (this.state.isInitializing) {
88
- this.characteristics = res.characteristics;
89
- this.services = res.services.map(s => typeof (s) === 'string' ? s : s.uuid);
90
- this.state.isInitializing = false;
91
- this.state.isInitialized = this.characteristics !== undefined && this.services !== undefined;
92
- this.logEvent({ message: 'initialize done', peripheral: this.peripheral.address, state: this.state });
93
+ return new Promise((done) => __awaiter(this, void 0, void 0, function* () {
94
+ this.state.isInitializing = true;
95
+ this.characteristics = undefined;
96
+ this.services = undefined;
97
+ try {
98
+ this.emitter.once('disconnect', () => {
99
+ done(false);
100
+ });
101
+ const res = yield this.peripheral.discoverSomeServicesAndCharacteristicsAsync([], []);
102
+ if (this.state.isInitializing) {
103
+ this.characteristics = res.characteristics;
104
+ this.services = res.services.map(s => typeof (s) === 'string' ? s : s.uuid);
105
+ this.state.isInitializing = false;
106
+ this.state.isInitialized = this.characteristics !== undefined && this.services !== undefined;
107
+ this.logEvent({ message: 'initialize done', peripheral: this.peripheral.address, state: this.state });
108
+ return done(true);
109
+ }
110
+ else {
111
+ this.logEvent({ message: 'initialize interrupted', peripheral: this.peripheral.address });
112
+ }
93
113
  }
94
- else {
95
- this.logEvent({ message: 'initialize interrupted', peripheral: this.peripheral.address });
114
+ catch (err) {
115
+ this.logEvent({ message: 'error', fn: 'initialize', error: err.message, stack: err.stack });
116
+ this.state.isInitializing = false;
117
+ this.state.isInitialized = false;
118
+ done(false);
96
119
  }
97
- }
98
- catch (err) {
99
- this.logEvent({ message: 'error', fn: 'initialize', error: err.message, stack: err.stack });
100
- this.state.isInitializing = false;
101
- this.state.isInitialized = false;
102
- }
120
+ }));
103
121
  });
104
122
  }
105
123
  isSubscribed(characteristicUuid) {
106
- return this.state.subscribed.find(c => c === characteristicUuid || (0, utils_1.uuid)(c) === characteristicUuid || c === (0, utils_1.uuid)(characteristicUuid)) !== undefined;
124
+ var _a;
125
+ return ((_a = this.state.subscribed) === null || _a === void 0 ? void 0 : _a.find(c => c === characteristicUuid || (0, utils_1.uuid)(c) === characteristicUuid || c === (0, utils_1.uuid)(characteristicUuid))) !== undefined;
107
126
  }
108
127
  subscribeAll(callback) {
128
+ var _a;
109
129
  return __awaiter(this, void 0, void 0, function* () {
110
130
  const cnt = this.characteristics.length;
111
131
  this.state.isSubscribing = true;
@@ -124,7 +144,7 @@ class BlePeripheralConnector {
124
144
  this.on((0, utils_1.uuid)(c.uuid), callback);
125
145
  }
126
146
  this.logEvent({ message: 'subscribe', peripheral: this.peripheral.address, characteristic: c.uuid, uuid: (0, utils_1.uuid)(c.uuid) });
127
- if (this.state.subscribed.find(uuid => uuid === c.uuid) === undefined) {
147
+ if (((_a = this.state.subscribed) === null || _a === void 0 ? void 0 : _a.find(uuid => uuid === c.uuid)) === undefined) {
128
148
  try {
129
149
  yield this.subscribe(c.uuid, 3000);
130
150
  subscribed.push(c.uuid);
@@ -117,7 +117,7 @@ class BleFmAdapter extends adapter_1.BleControllableAdapter {
117
117
  this.resume();
118
118
  if (this.started && !wasPaused)
119
119
  return true;
120
- this.logEvent(Object.assign(Object.assign({ message: 'starting device' }, this.getSettings()), { protocol: this.getProtocolName(), props, isStarted: this.started }));
120
+ this.logEvent(Object.assign(Object.assign({ message: 'starting device' }, this.getSettings()), { protocol: this.getProtocolName(), props, isStarted: this.started, isConnected: this.getComms().isConnected() }));
121
121
  const { restart = wasPaused } = props;
122
122
  if (!restart && this.ble.isScanning() && !this.getComms().isConnected()) {
123
123
  }
@@ -131,11 +131,11 @@ class BleFmAdapter extends adapter_1.BleControllableAdapter {
131
131
  this.connectPromise = this.connect();
132
132
  const res = yield Promise.race([
133
133
  this.connectPromise.then((connected) => {
134
- this.connectPromise = undefined;
135
134
  return { connected, reason: connected ? null : 'could not connect' };
136
135
  }),
137
136
  (0, utils_1.sleep)(timeout).then(() => ({ connected: false, reason: 'timeout' }))
138
137
  ]);
138
+ this.connectPromise = undefined;
139
139
  const connected = res.connected;
140
140
  if (!connected) {
141
141
  throw new Error(`could not start device, reason:${res.reason}`);
@@ -12,6 +12,8 @@ class BlePeripheralCache {
12
12
  return this.find(adapter.getSettings());
13
13
  }
14
14
  getConnector(peripheral) {
15
+ if (!peripheral)
16
+ return;
15
17
  const info = this.find({ address: peripheral.address });
16
18
  if (!info) {
17
19
  const item = this.add({ address: peripheral.address, ts: Date.now(), peripheral });
@@ -99,7 +101,7 @@ class BlePeripheralCache {
99
101
  const { address } = peripheral;
100
102
  cachedItemIdx = this._findIndex({ address });
101
103
  }
102
- if (cachedItemIdx == -1)
104
+ if (cachedItemIdx === -1)
103
105
  return;
104
106
  this.peripherals.splice(cachedItemIdx);
105
107
  }
@@ -66,7 +66,7 @@ export interface BlePeripheral extends EventEmitter, BlePeripheralIdentifier {
66
66
  export interface IBlePeripheralConnector {
67
67
  connect(): Promise<void>;
68
68
  reconnect(): Promise<void>;
69
- initialize(enforce: boolean): Promise<void>;
69
+ initialize(enforce: boolean): Promise<boolean>;
70
70
  isSubscribed(characteristicUuid: string): boolean;
71
71
  subscribeAll(callback: (characteristicUuid: string, data: any) => void): Promise<string[]>;
72
72
  subscribe(characteristicUuid: string, timeout?: number): Promise<boolean>;
@@ -21,8 +21,8 @@ export default class DaumClassicAdapter extends DaumAdapter {
21
21
  check(): Promise<boolean>;
22
22
  pause(): Promise<boolean>;
23
23
  resume(): Promise<boolean>;
24
- startRide(props: DaumClassicDeviceProperties): Promise<boolean>;
25
- start(props: DaumClassicDeviceProperties): Promise<boolean>;
24
+ startRide(props?: DaumClassicDeviceProperties): Promise<boolean>;
25
+ start(props?: DaumClassicDeviceProperties): Promise<boolean>;
26
26
  launch(props: DaumClassicDeviceProperties, isRelaunch?: boolean): Promise<boolean>;
27
27
  performStart(props?: DaumClassicDeviceProperties, isRelaunch?: boolean): Promise<unknown>;
28
28
  getCurrentBikeData(): any;
@@ -131,16 +131,30 @@ class DaumClassicAdapter extends DaumAdapter_1.default {
131
131
  return resumed;
132
132
  });
133
133
  }
134
- startRide(props) {
134
+ startRide(props = {}) {
135
135
  return __awaiter(this, void 0, void 0, function* () {
136
136
  this.logger.logEvent({ message: 'relaunch of device' });
137
- return yield this.launch(props, true);
137
+ try {
138
+ yield this.launch(props, true);
139
+ return true;
140
+ }
141
+ catch (err) {
142
+ this.logEvent({ message: 'start result: error', error: err.message });
143
+ throw err;
144
+ }
138
145
  });
139
146
  }
140
- start(props) {
147
+ start(props = {}) {
141
148
  return __awaiter(this, void 0, void 0, function* () {
142
149
  this.logger.logEvent({ message: 'initial start of device' });
143
- return yield this.launch(props, false);
150
+ try {
151
+ yield this.launch(props, false);
152
+ return true;
153
+ }
154
+ catch (err) {
155
+ this.logEvent({ message: 'start result: error', error: err.message });
156
+ throw err;
157
+ }
144
158
  });
145
159
  }
146
160
  launch(props, isRelaunch = false) {
@@ -178,7 +192,7 @@ class DaumClassicAdapter extends DaumAdapter_1.default {
178
192
  try {
179
193
  this.logger.logEvent({ message: 'start attempt', isRelaunch, isConnected: this.bike.isConnected() });
180
194
  if (!isRelaunch && !this.bike.isConnected())
181
- yield this.bike.saveConnect();
195
+ yield this.connect();
182
196
  yield this.getBike().resetDevice();
183
197
  if (!startState.setProg) {
184
198
  yield this.getBike().setProg(0);
@@ -44,6 +44,8 @@ export type DaumClassicUser = {
44
44
  };
45
45
  interface BikeData {
46
46
  cockpitVersion: number;
47
+ cockpitType: number;
48
+ serialNo: string;
47
49
  isPedalling: boolean;
48
50
  bikeType: number;
49
51
  person: DaumClassicUser;
@@ -77,6 +77,8 @@ class DaumClassicMockImpl {
77
77
  exports.DaumClassicMockImpl = DaumClassicMockImpl;
78
78
  const DEFAULT_BIKE_DATA = {
79
79
  cockpitVersion: 3,
80
+ serialNo: '4464:<;8',
81
+ cockpitType: 50,
80
82
  isPedalling: false,
81
83
  bikeType: 0,
82
84
  person: { weight: 75, length: 180, age: 30, sex: 0 }
@@ -208,7 +210,10 @@ class DaumClassicMockBinding extends binding_mock_1.MockPortBinding {
208
210
  onGetVersion(payload) {
209
211
  const bikeNo = payload.readUInt8(0);
210
212
  if (bikeNo >= 0 && bikeNo < 10) {
211
- const response = Buffer.from([0x73, bikeNo, this.simulator.bikes[bikeNo].cockpitVersion]);
213
+ const { cockpitType, serialNo } = this.simulator.bikes[bikeNo] || {};
214
+ const response = Buffer.from([0x73, bikeNo, 0, 0, 0, 0, 0, 0, 0, 0, cockpitType]);
215
+ for (let i = 0; i < serialNo.length && i < 8; i++)
216
+ response.writeUInt8(serialNo.charCodeAt(i), i + 2);
212
217
  this.emitData(response);
213
218
  }
214
219
  }
@@ -8,6 +8,7 @@ export default class DaumPremiumAdapter extends DaumAdapter {
8
8
  commProps: SerialCommProps;
9
9
  _startRetryTimeout: number;
10
10
  constructor(settings: SerialDeviceSettings, props?: DeviceProperties);
11
+ logEvent(event: any): void;
11
12
  getName(): string;
12
13
  getUniqueName(): string;
13
14
  getPort(): any;
@@ -60,6 +60,15 @@ class DaumPremiumAdapter extends DaumAdapter_1.default {
60
60
  this.distanceInternal = undefined;
61
61
  this.initData();
62
62
  }
63
+ logEvent(event) {
64
+ if (this.logger) {
65
+ this.logger.logEvent(event);
66
+ }
67
+ const w = global.window;
68
+ if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG) {
69
+ console.log('~~~ DaumPremium', event);
70
+ }
71
+ }
63
72
  getName() {
64
73
  return 'Daum8i';
65
74
  }
@@ -102,19 +111,19 @@ class DaumPremiumAdapter extends DaumAdapter_1.default {
102
111
  return __awaiter(this, void 0, void 0, function* () {
103
112
  var info = {};
104
113
  return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
105
- this.logger.logEvent({ message: "checking device", port: this.getPort() });
114
+ this.logEvent({ message: "checking device", port: this.getPort() });
106
115
  try {
116
+ yield this.bike.close();
107
117
  const connected = yield this.connect();
108
118
  if (!connected)
109
119
  resolve(false);
110
120
  info.deviceType = yield this.bike.getDeviceType();
111
121
  info.version = yield this.bike.getProtocolVersion();
112
- yield this.bike.close();
113
- this.logger.logEvent({ message: "checking device success", port: this.getPort(), info });
122
+ this.logEvent({ message: "checking device success", port: this.getPort(), info });
114
123
  resolve(true);
115
124
  }
116
125
  catch (err) {
117
- this.logger.logEvent({ message: "checking device failed", port: this.getPort(), reason: err.message || err });
126
+ this.logEvent({ message: "checking device failed", port: this.getPort(), reason: err.message || err });
118
127
  resolve(false);
119
128
  }
120
129
  }));
@@ -142,27 +151,27 @@ class DaumPremiumAdapter extends DaumAdapter_1.default {
142
151
  }
143
152
  startRide(props = {}) {
144
153
  return __awaiter(this, void 0, void 0, function* () {
145
- this.logger.logEvent({ message: 'relaunch of device' });
154
+ this.logEvent({ message: 'relaunch of device' });
146
155
  try {
147
156
  yield this.launch(props, true);
148
157
  return true;
149
158
  }
150
159
  catch (err) {
151
- this.logger.logEvent({ message: 'start result: error', error: err.message });
152
- throw new Error(`could not start device, reason:${err.message}`);
160
+ this.logEvent({ message: 'start result: error', error: err.message });
161
+ throw err;
153
162
  }
154
163
  });
155
164
  }
156
165
  start(props = {}) {
157
166
  return __awaiter(this, void 0, void 0, function* () {
158
- this.logger.logEvent({ message: 'initial start of device' });
167
+ this.logEvent({ message: 'initial start of device' });
159
168
  try {
160
169
  yield this.launch(props, false);
161
170
  return true;
162
171
  }
163
172
  catch (err) {
164
- this.logger.logEvent({ message: 'start result: error', error: err.message });
165
- throw new Error(`could not start device, reason:${err.message}`);
173
+ this.logEvent({ message: 'start result: error', error: err.message });
174
+ throw err;
166
175
  }
167
176
  });
168
177
  }
@@ -41,7 +41,8 @@ class Daum8i {
41
41
  const { logger, serial, path } = props;
42
42
  this.serial = serial;
43
43
  this.path = validatePath(path);
44
- this.logger = logger || (process.env.DEBUG ? DEBUG_LOGGER : new gd_eventlog_1.EventLogger('DaumPremium'));
44
+ const w = global.window;
45
+ this.logger = logger || ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.DEBUG ? DEBUG_LOGGER : new gd_eventlog_1.EventLogger('DaumPremium'));
45
46
  this.isLoggingPaused = false;
46
47
  this.connected = false;
47
48
  this.blocked = false;
@@ -75,6 +76,10 @@ class Daum8i {
75
76
  logEvent(e) {
76
77
  if (!this.isLoggingPaused)
77
78
  this.logger.logEvent(e);
79
+ const w = global.window;
80
+ if (w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) {
81
+ console.log('~~~ DaumPremium', e);
82
+ }
78
83
  }
79
84
  connect() {
80
85
  return __awaiter(this, void 0, void 0, function* () {
@@ -114,6 +119,7 @@ class Daum8i {
114
119
  }
115
120
  this.connected = false;
116
121
  if (this.sp) {
122
+ console.log('~~~ removing all listeners');
117
123
  this.sp.removeAllListeners();
118
124
  this.sp = null;
119
125
  }
@@ -149,6 +155,7 @@ class Daum8i {
149
155
  return __awaiter(this, void 0, void 0, function* () {
150
156
  this.connected = false;
151
157
  if (this.sp) {
158
+ console.log('~~~ removing all listeners');
152
159
  this.sp.removeAllListeners();
153
160
  this.sp = null;
154
161
  }
@@ -421,19 +428,18 @@ class Daum8i {
421
428
  }
422
429
  write(buffer) {
423
430
  return __awaiter(this, void 0, void 0, function* () {
424
- return new Promise(done => {
431
+ return new Promise((done) => __awaiter(this, void 0, void 0, function* () {
425
432
  this.state.writeBusy = true;
426
433
  try {
427
- this.sp.write(buffer, () => {
428
- this.state.writeBusy = false;
429
- done();
430
- });
434
+ yield this.sp.write(buffer);
435
+ this.state.writeBusy = false;
436
+ done();
431
437
  }
432
438
  catch (err) {
433
439
  this.state.writeBusy = false;
434
440
  done();
435
441
  }
436
- });
442
+ }));
437
443
  });
438
444
  }
439
445
  sendACK() {
@@ -143,9 +143,6 @@ class Daum8iMockBinding extends binding_mock_1.MockPortBinding {
143
143
  }
144
144
  this.writeOperation = (() => __awaiter(this, void 0, void 0, function* () {
145
145
  yield (0, utils_1.resolveNextTick)();
146
- if (!this.isOpen || !this.port) {
147
- throw new Error('Write canceled');
148
- }
149
146
  if (this.simulator._isSimulateACKTimeout) {
150
147
  this.simulator._isSimulateACKTimeout = false;
151
148
  }
@@ -164,7 +164,7 @@ class KettlerRacerMockBinding extends binding_mock_1.MockPortBinding {
164
164
  handler(payload);
165
165
  }
166
166
  else {
167
- this, this.emitData('ERROR' + CRLF);
167
+ this.emitData('ERROR' + CRLF);
168
168
  }
169
169
  });
170
170
  });
@@ -31,6 +31,7 @@ export declare class SinglePathScanner {
31
31
  props: SerialScannerProps;
32
32
  logger: EventLogger;
33
33
  constructor(path: string, serial: SerialInterface, props: SerialScannerProps);
34
+ logEvent(event: any): void;
34
35
  onStopRequest(resolve: any): Promise<void>;
35
36
  scan(): Promise<SerialDeviceSettings | undefined>;
36
37
  }
@@ -48,6 +49,7 @@ export default class SerialInterface extends EventEmitter implements IncyclistIn
48
49
  static getInstance(props: SerialInterfaceProps): SerialInterface;
49
50
  static _add(instance: SerialInterface): void;
50
51
  constructor(props: SerialInterfaceProps);
52
+ logEvent(event: any): void;
51
53
  setBinding(binding: BindingInterface): void;
52
54
  getName(): string;
53
55
  isConnected(): boolean;
@@ -32,9 +32,18 @@ class SinglePathScanner {
32
32
  this.props = props;
33
33
  this.logger = props.logger || new gd_eventlog_1.EventLogger('SerialScanner');
34
34
  }
35
+ logEvent(event) {
36
+ if (this.logger) {
37
+ this.logger.logEvent(event);
38
+ }
39
+ const w = global.window;
40
+ if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG) {
41
+ console.log('~~~ SerialScanner', event);
42
+ }
43
+ }
35
44
  onStopRequest(resolve) {
36
45
  return __awaiter(this, void 0, void 0, function* () {
37
- this.logger.logEvent({ message: 'stopping scan', path: this.path });
46
+ this.logEvent({ message: 'stopping scan', path: this.path });
38
47
  yield this.serial.closePort(this.path);
39
48
  this.isScanning = false;
40
49
  resolve(this.result);
@@ -46,7 +55,7 @@ class SinglePathScanner {
46
55
  return;
47
56
  this.isScanning = true;
48
57
  return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
49
- this.logger.logEvent({ message: 'starting scan', path: this.path });
58
+ this.logEvent({ message: 'starting scan', path: this.path });
50
59
  this.serial.scanEvents.on('timeout', () => this.onStopRequest(resolve));
51
60
  this.serial.scanEvents.on('stop', () => this.onStopRequest(resolve));
52
61
  let found = false;
@@ -65,12 +74,13 @@ class SinglePathScanner {
65
74
  found = yield adapter.check();
66
75
  if (found) {
67
76
  const name = adapter.getName();
77
+ yield this.serial.closePort(this.path).catch();
68
78
  resolve(Object.assign(Object.assign({}, adapterSettings), { name }));
69
79
  }
70
80
  yield (0, utils_1.sleep)(100);
71
81
  }
72
82
  catch (err) {
73
- this.logger.logEvent({ message: 'error', fn: 'scan()', error: err.message || err, stack: err.stack });
83
+ this.logEvent({ message: 'error', fn: 'scan()', error: err.message || err, stack: err.stack });
74
84
  yield (0, utils_1.sleep)(100);
75
85
  }
76
86
  }
@@ -113,12 +123,21 @@ class SerialInterface extends events_1.default {
113
123
  this.scanEvents.setMaxListeners(100);
114
124
  this.logger = props.logger || new gd_eventlog_1.EventLogger(`Serial:${ifaceName}`);
115
125
  this.connected = false;
116
- this.logger.logEvent({ message: 'new serial interface', ifaceName });
126
+ this.logEvent({ message: 'new serial interface', ifaceName });
117
127
  if (binding) {
118
128
  this.setBinding(binding);
119
129
  }
120
130
  SerialInterface._add(this);
121
131
  }
132
+ logEvent(event) {
133
+ if (this.logger) {
134
+ this.logger.logEvent(event);
135
+ }
136
+ const w = global.window;
137
+ if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || process.env.BLE_DEBUG) {
138
+ console.log('~~~ Serial', event);
139
+ }
140
+ }
122
141
  setBinding(binding) {
123
142
  this.binding = binding;
124
143
  serialport_1.default.getInstance().setBinding(this.ifaceName, binding);
@@ -138,7 +157,7 @@ class SerialInterface extends events_1.default {
138
157
  }
139
158
  try {
140
159
  const SerialPort = this.binding;
141
- const res = yield SerialPort.list();
160
+ yield SerialPort.list();
142
161
  this.connected = true;
143
162
  return true;
144
163
  }
@@ -156,7 +175,7 @@ class SerialInterface extends events_1.default {
156
175
  }
157
176
  openPort(path) {
158
177
  return __awaiter(this, void 0, void 0, function* () {
159
- this.logger.logEvent({ message: 'opening port', path });
178
+ this.logEvent({ message: 'opening port', path });
160
179
  const port = serialport_1.default.getInstance().getSerialPort(this.ifaceName, { path });
161
180
  if (!port) {
162
181
  return null;
@@ -164,20 +183,21 @@ class SerialInterface extends events_1.default {
164
183
  const existing = this.ports.findIndex(p => p.path === path);
165
184
  if (existing !== -1) {
166
185
  const port = this.ports[existing].port;
167
- if (port.isOpen)
186
+ if (port.isOpen) {
168
187
  return port;
188
+ }
169
189
  else {
170
190
  this.ports.splice(existing, 1);
171
191
  }
172
192
  }
173
193
  return new Promise((resolve) => {
174
194
  port.once('error', (err) => {
175
- this.logger.logEvent({ message: 'error', path, error: err || err.message });
195
+ this.logEvent({ message: 'error', path, error: err || err.message });
176
196
  port.removeAllListeners();
177
197
  resolve(null);
178
198
  });
179
199
  port.once('open', () => {
180
- this.logger.logEvent({ message: 'port opened', path });
200
+ this.logEvent({ message: 'port opened', path });
181
201
  port.removeAllListeners();
182
202
  this.ports.push({ path, port });
183
203
  resolve(port);
@@ -188,6 +208,7 @@ class SerialInterface extends events_1.default {
188
208
  }
189
209
  closePort(path) {
190
210
  return __awaiter(this, void 0, void 0, function* () {
211
+ this.logEvent({ message: 'closing port' });
191
212
  const existing = this.ports.findIndex(p => p.path === path);
192
213
  if (existing === -1)
193
214
  return true;
@@ -229,7 +250,7 @@ class SerialInterface extends events_1.default {
229
250
  this.scanEvents.emit('timeout');
230
251
  }, timeout);
231
252
  }
232
- this.logger.logEvent({ message: 'checking for ports ' });
253
+ this.logEvent({ message: 'checking for ports' });
233
254
  this.isScanning = true;
234
255
  do {
235
256
  try {
@@ -245,21 +266,21 @@ class SerialInterface extends events_1.default {
245
266
  console.log('~~~ERROR', err);
246
267
  }
247
268
  if (!paths || paths.length === 0) {
248
- this.logger.logEvent({ message: 'scanning: no ports detected', interface: this.ifaceName, paths: paths.map(p => p.path), timeout });
269
+ this.logEvent({ message: 'scanning: no ports detected', interface: this.ifaceName, paths: paths.map(p => p.path), timeout });
249
270
  yield (0, utils_1.sleep)(1000);
250
271
  }
251
272
  if (Date.now() > toExpiresAt)
252
273
  timeOutExpired = true;
253
274
  } while (this.isScanning && !timeOutExpired && paths.length === 0);
254
275
  if (paths.length === 0) {
255
- this.logger.logEvent({ message: 'nothing to scan ' });
276
+ this.logEvent({ message: 'nothing to scan ' });
256
277
  if (this.toScan) {
257
278
  clearTimeout(this.toScan);
258
279
  this.toScan = null;
259
280
  }
260
281
  return [];
261
282
  }
262
- this.logger.logEvent({ message: 'scanning on ', paths: paths.map(p => p.path), timeout });
283
+ this.logEvent({ message: 'scanning on ', paths: paths.map(p => p.path), timeout });
263
284
  const scanners = paths.map(p => new SinglePathScanner(p.path, this, Object.assign(Object.assign({}, props), { logger: this.logger })));
264
285
  try {
265
286
  yield Promise.all(scanners.map(s => s.scan()
@@ -272,14 +293,14 @@ class SerialInterface extends events_1.default {
272
293
  .catch()));
273
294
  }
274
295
  catch (err) {
275
- this.logger.logEvent({ message: 'error', fn: 'scan()', error: err.message || err, stack: err.stack });
296
+ this.logEvent({ message: 'error', fn: 'scan()', error: err.message || err, stack: err.stack });
276
297
  }
277
298
  if (this.toScan) {
278
299
  clearTimeout(this.toScan);
279
300
  this.toScan = null;
280
301
  }
281
302
  this.isScanning = false;
282
- this.logger.logEvent({ message: 'scan finished on', interface: this.ifaceName, paths: paths.map(p => p.path), devices: detected.map(d => {
303
+ this.logEvent({ message: 'scan finished on', interface: this.ifaceName, paths: paths.map(p => p.path), devices: detected.map(d => {
283
304
  const res = Object.assign({}, d);
284
305
  res.interface = this.ifaceName;
285
306
  return res;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-devices",
3
- "version": "2.0.6",
3
+ "version": "2.0.8",
4
4
  "dependencies": {
5
5
  "@serialport/bindings-interface": "^1.2.2",
6
6
  "@serialport/parser-byte-length": "^9.0.1",