incyclist-services 1.0.52 → 1.0.54

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.
@@ -18,11 +18,12 @@ export declare class DeviceAccessService extends EventEmitter {
18
18
  constructor();
19
19
  protected logEvent(event: any): void;
20
20
  setDefaultInterfaceProperties(props: InterfaceAccessProps): void;
21
- enableInterface(ifaceName: string, binding?: any, props?: InterfaceAccessProps): void;
22
- disableInterface(ifaceName: string, avalailable?: boolean): void;
21
+ enableInterface(ifaceName: string, binding?: any, props?: InterfaceAccessProps): Promise<void>;
22
+ disableInterface(ifaceName: string, avalailable?: boolean): Promise<void>;
23
23
  setInterfaceProperties(ifaceName: string, props: InterfaceAccessProps): void;
24
24
  getInterfaceInfo(ifaceName: string): InterfaceInfo;
25
25
  enrichWithAccessState(interfaces: InterfaceSetting[]): EnrichedInterfaceSetting[];
26
+ initInterface(ifaceName: string, binding: any, props?: InterfaceAccessProps): void;
26
27
  protected getInterface(ifaceName: string): IncyclistInterface;
27
28
  connect(ifaceName?: string): Promise<boolean>;
28
29
  private getScanTimeout;
@@ -44,55 +44,67 @@ class DeviceAccessService extends events_1.default {
44
44
  this.defaultProps = props;
45
45
  }
46
46
  enableInterface(ifaceName, binding, props = {}) {
47
- const existing = this.interfaces[ifaceName];
48
- if (!binding && !existing) {
49
- this.logEvent({ message: 'Interface has not been initialized with binding', interface: ifaceName });
50
- this.emit('interface-changed', ifaceName, { name: ifaceName, state: 'unavailable', isScanning: false });
51
- }
52
- if (!existing) {
53
- const properties = (0, clone_1.default)(this.defaultProps);
54
- (0, merge_1.merge)(properties, props);
55
- const info = { name: ifaceName, interface: incyclist_devices_1.InterfaceFactory.create(ifaceName, { binding }), enabled: true, isScanning: false, properties, state: 'unknown' };
56
- this.interfaces[ifaceName] = info;
57
- info.interface.setBinding(binding);
58
- const keys = Object.keys(this.interfaces);
59
- const interfaces = keys.map(name => (Object.assign(Object.assign({}, this.interfaces[name]), { name })));
60
- this.emit('interface-changed', ifaceName, this.interfaces[ifaceName], interfaces);
61
- }
62
- else {
63
- if (this.isScanning(ifaceName)) {
64
- this.logEvent({ message: 'Illegal State, enable Interface cannot be called during an ongoing scan' });
65
- return;
47
+ var _a;
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ try {
50
+ if (binding)
51
+ this.initInterface(ifaceName, binding, props);
52
+ const existing = this.interfaces[ifaceName];
53
+ if (!binding && !existing) {
54
+ this.logEvent({ message: 'Interface has not been initialized with binding', interface: ifaceName });
55
+ this.emit('interface-changed', ifaceName, { name: ifaceName, state: 'unavailable', isScanning: false });
56
+ }
57
+ if (this.isScanning(ifaceName)) {
58
+ this.logEvent({ message: 'Illegal State, enable Interface cannot be called during an ongoing scan' });
59
+ return;
60
+ }
61
+ if (existing.enabled && ((existing.state === 'connected' && ((_a = existing === null || existing === void 0 ? void 0 : existing.interface) === null || _a === void 0 ? void 0 : _a.isConnected())) || existing.state === 'connecting')) {
62
+ return;
63
+ }
64
+ existing.enabled = true;
65
+ const state = existing.interface.isConnected() ? 'connected' : 'disconnected';
66
+ existing.state = state;
67
+ (0, merge_1.merge)(existing.properties || this.defaultProps, props);
68
+ this.emit('interface-changed', ifaceName, Object.assign({}, existing));
69
+ if (!existing.interface.isConnected()) {
70
+ this.emit('interface-changed', ifaceName, Object.assign(Object.assign({}, existing), { state: 'connecting' }));
71
+ const conected = yield this.connect(ifaceName);
72
+ const state = conected ? 'connected' : 'disconnected';
73
+ this.emit('interface-changed', ifaceName, Object.assign(Object.assign({}, existing), { state }));
74
+ }
66
75
  }
67
- if (binding)
68
- existing.interface.setBinding(binding);
69
- existing.enabled = true;
70
- (0, merge_1.merge)(existing.properties || this.defaultProps, props);
71
- this.emit('interface-changed', ifaceName, this.interfaces[ifaceName]);
72
- }
76
+ catch (err) {
77
+ this.logEvent({ message: 'Error', fn: 'enableInterface', error: err.message, stack: err.stack });
78
+ }
79
+ });
73
80
  }
74
81
  disableInterface(ifaceName, avalailable = true) {
75
- const existing = this.interfaces[ifaceName];
76
- if (!existing)
77
- return;
78
- if (this.isScanning(ifaceName)) {
79
- const info = this.interfaces[ifaceName];
80
- info.interface.stopScan().then((stopped) => {
81
- this.emit('interface-changed', ifaceName, this.interfaces[ifaceName]);
82
- info.isScanning = !stopped;
83
- if (stopped)
84
- this.disableInterface(ifaceName);
85
- });
86
- return;
87
- }
88
- existing.enabled = false;
89
- if (!avalailable) {
90
- existing.state = 'unavailable';
91
- existing.unavailable = true;
92
- this.emit('interface-changed', ifaceName, { name: ifaceName, state: 'unavailable', isScanning: false });
93
- return;
94
- }
95
- this.emit('interface-changed', ifaceName, this.interfaces[ifaceName]);
82
+ return __awaiter(this, void 0, void 0, function* () {
83
+ const existing = this.interfaces[ifaceName];
84
+ if (!existing)
85
+ return;
86
+ if (this.isScanning(ifaceName)) {
87
+ try {
88
+ const info = this.interfaces[ifaceName];
89
+ const stopped = yield info.interface.stopScan();
90
+ info.isScanning = !stopped;
91
+ this.emit('interface-changed', ifaceName, this.interfaces[ifaceName]);
92
+ if (stopped)
93
+ this.disableInterface(ifaceName);
94
+ }
95
+ catch (err) {
96
+ this.logEvent({ message: 'Error', fn: 'disableInterface', error: err.message, stack: err.stack });
97
+ }
98
+ }
99
+ existing.enabled = false;
100
+ yield this.disconnect(ifaceName);
101
+ if (!avalailable) {
102
+ existing.state = 'unavailable';
103
+ existing.unavailable = true;
104
+ this.emit('interface-changed', ifaceName, { name: ifaceName, state: 'unavailable', isScanning: false });
105
+ return;
106
+ }
107
+ });
96
108
  }
97
109
  setInterfaceProperties(ifaceName, props) {
98
110
  if (this.isScanning(ifaceName)) {
@@ -132,34 +144,60 @@ class DeviceAccessService extends events_1.default {
132
144
  return enriched;
133
145
  });
134
146
  }
147
+ initInterface(ifaceName, binding, props = {}) {
148
+ const existing = this.interfaces[ifaceName];
149
+ if (!existing) {
150
+ const properties = (0, clone_1.default)(this.defaultProps);
151
+ (0, merge_1.merge)(properties, props);
152
+ const info = { name: ifaceName, interface: incyclist_devices_1.InterfaceFactory.create(ifaceName, { binding }), enabled: false, isScanning: false, properties, state: 'unknown' };
153
+ this.interfaces[ifaceName] = info;
154
+ info.interface.setBinding(binding);
155
+ const keys = Object.keys(this.interfaces);
156
+ const interfaces = keys.map(name => (Object.assign(Object.assign({}, this.interfaces[name]), { name })));
157
+ this.emit('interface-changed', ifaceName, this.interfaces[ifaceName], interfaces);
158
+ }
159
+ else {
160
+ const info = existing;
161
+ info.interface.setBinding(binding);
162
+ }
163
+ }
135
164
  getInterface(ifaceName) {
136
165
  const info = this.interfaces[ifaceName];
137
166
  return info === null || info === void 0 ? void 0 : info.interface;
138
167
  }
139
168
  connect(ifaceName) {
169
+ var _a;
140
170
  return __awaiter(this, void 0, void 0, function* () {
141
- if (!ifaceName) {
142
- const interfaces = Object.keys(this.interfaces);
143
- interfaces.forEach(name => { if (name)
144
- this.connect(name); });
145
- return;
171
+ try {
172
+ if (!ifaceName) {
173
+ const interfaces = Object.keys(this.interfaces);
174
+ interfaces.forEach(name => { if (name)
175
+ this.connect(name); });
176
+ return;
177
+ }
178
+ if (((_a = this.interfaces[ifaceName]) === null || _a === void 0 ? void 0 : _a.enabled) === false)
179
+ return;
180
+ const impl = this.getInterface(ifaceName);
181
+ if (!impl) {
182
+ this.emit('interface-changed', ifaceName, { name: ifaceName, state: 'unavailable', isScanning: false });
183
+ this.interfaces[ifaceName].state = 'unavailable';
184
+ return false;
185
+ }
186
+ const prevState = this.interfaces[ifaceName].state;
187
+ if (prevState === 'connected')
188
+ return true;
189
+ this.interfaces[ifaceName].state = 'connecting';
190
+ this.emit('interface-changed', ifaceName, Object.assign(Object.assign({}, this.interfaces[ifaceName]), { state: 'connecting' }));
191
+ const connected = yield impl.connect();
192
+ const state = connected ? 'connected' : 'disconnected';
193
+ this.interfaces[ifaceName].state = state;
194
+ this.emit('interface-changed', ifaceName, this.interfaces[ifaceName]);
195
+ return connected;
146
196
  }
147
- const impl = this.getInterface(ifaceName);
148
- if (!impl) {
149
- this.emit('interface-changed', ifaceName, { name: ifaceName, state: 'unavailable', isScanning: false });
150
- this.interfaces[ifaceName].state = 'unavailable';
197
+ catch (err) {
198
+ this.logEvent({ message: 'Error', fn: 'connect', error: err.message, stack: err.stack });
151
199
  return false;
152
200
  }
153
- const prevState = this.interfaces[ifaceName].state;
154
- if (prevState === 'connected')
155
- return true;
156
- this.interfaces[ifaceName].state = 'connecting';
157
- this.emit('interface-changed', ifaceName, this.interfaces[ifaceName]);
158
- const connected = yield impl.connect();
159
- const state = connected ? 'connected' : 'disconnected';
160
- this.interfaces[ifaceName].state = state;
161
- this.emit('interface-changed', ifaceName, this.interfaces[ifaceName]);
162
- return connected;
163
201
  });
164
202
  }
165
203
  getScanTimeout(propsTimeout, interfaceSettingsTimeout) {
@@ -187,11 +225,11 @@ class DeviceAccessService extends events_1.default {
187
225
  return true;
188
226
  const prevState = this.interfaces[ifaceName].state;
189
227
  this.interfaces[ifaceName].state = 'disconnecting';
190
- this.emit('interface-changed', ifaceName, this.interfaces[ifaceName]);
228
+ this.emit('interface-changed', ifaceName, Object.assign({}, this.interfaces[ifaceName]));
191
229
  const disconnected = yield impl.disconnect();
192
230
  const state = disconnected ? 'disconnected' : prevState;
193
231
  this.interfaces[ifaceName].state = state;
194
- this.emit('interface-changed', ifaceName, this.interfaces[ifaceName]);
232
+ this.emit('interface-changed', ifaceName, Object.assign({}, this.interfaces[ifaceName]));
195
233
  return disconnected;
196
234
  });
197
235
  }
@@ -38,10 +38,16 @@ export interface PairingState {
38
38
  canStartRide?: boolean;
39
39
  adapters?: Array<AdapterInfo>;
40
40
  }
41
+ export interface DeleteListEntry {
42
+ capability: IncyclistCapability;
43
+ udid: string;
44
+ }
41
45
  export interface InternalPairingState extends PairingState {
42
46
  initialized: boolean;
43
47
  stopRequested?: boolean;
44
48
  stopped?: boolean;
49
+ waiting?: boolean;
50
+ deleted: Array<DeleteListEntry>;
45
51
  check?: {
46
52
  promise: Promise<boolean>;
47
53
  };
@@ -5,8 +5,6 @@ import { DeviceData, IncyclistCapability, IncyclistDeviceAdapter } from "incycli
5
5
  import { AdapterStateInfo, DeviceRideService } from "../ride";
6
6
  import { IncyclistService } from "../../base/service";
7
7
  import { EnrichedInterfaceSetting } from "../access";
8
- export declare const mappedCapability: (c: CapabilityInformation) => CapabilityData;
9
- export declare const mappedCapabilities: (capabilities: DeviceConfigurationInfo) => Array<CapabilityData>;
10
8
  export interface Services {
11
9
  configuration?: DeviceConfigurationService;
12
10
  access?: DeviceAccessService;
@@ -106,5 +104,10 @@ export declare class DevicePairingService extends IncyclistService {
106
104
  protected isPairing(): boolean;
107
105
  protected _stopDeviceSelection(changed: boolean): Promise<void>;
108
106
  private numberOfSelectedCababilities;
107
+ protected addToDeletedList(capability: IncyclistCapability | CapabilityData, udid: string): void;
108
+ protected removeFromDeletedList(capability: IncyclistCapability | CapabilityData, udid: string): void;
109
+ protected isOnDeletedList(c: IncyclistCapability | CapabilityData, udid: string): boolean;
110
+ mappedCapability(c: CapabilityInformation): CapabilityData;
111
+ protected mappedCapabilities(capabilities: DeviceConfigurationInfo): Array<CapabilityData>;
109
112
  }
110
113
  export declare const useDevicePairing: () => DevicePairingService;
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.useDevicePairing = exports.DevicePairingService = exports.mappedCapabilities = exports.mappedCapability = void 0;
15
+ exports.useDevicePairing = exports.DevicePairingService = void 0;
16
16
  const service_1 = require("../access/service");
17
17
  const configuration_1 = require("../configuration");
18
18
  const incyclist_devices_1 = require("incyclist-devices");
@@ -26,28 +26,6 @@ const Units = [
26
26
  { capability: incyclist_devices_1.IncyclistCapability.Speed, unit: 'km/h', value: 'speed', decimals: 1 },
27
27
  { capability: incyclist_devices_1.IncyclistCapability.Cadence, unit: 'rpm', value: 'cadence', decimals: 0 },
28
28
  ];
29
- const mappedCapability = (c) => {
30
- var _a, _b, _c;
31
- const { devices } = c;
32
- const mapped = Object.assign({}, c);
33
- mapped.deviceNames = devices.map(d => d.name).join(';');
34
- mapped.selected = (_a = devices.find(d => d.selected)) === null || _a === void 0 ? void 0 : _a.udid;
35
- mapped.deviceName = (_b = devices.find(d => d.selected)) === null || _b === void 0 ? void 0 : _b.name;
36
- mapped.interface = (_c = devices.find(d => d.selected)) === null || _c === void 0 ? void 0 : _c.interface;
37
- mapped.devices = devices;
38
- return mapped;
39
- };
40
- exports.mappedCapability = mappedCapability;
41
- const mappedCapabilities = (capabilities) => {
42
- const caps = [];
43
- const ci = capabilities ? Object.keys(capabilities) || [] : [];
44
- ci.forEach(name => {
45
- const c = capabilities[name];
46
- caps.push((0, exports.mappedCapability)(c));
47
- });
48
- return caps;
49
- };
50
- exports.mappedCapabilities = mappedCapabilities;
51
29
  const getInterfaceSettings = (ifName, v) => {
52
30
  if (!v)
53
31
  return {};
@@ -62,7 +40,7 @@ class DevicePairingService extends service_2.IncyclistService {
62
40
  constructor(services) {
63
41
  super('Pairing');
64
42
  this.settings = {};
65
- this.state = { initialized: false };
43
+ this.state = { initialized: false, deleted: [] };
66
44
  this.deviceSelectState = null;
67
45
  this.onPairingStartedHandler = this.onPairingStarted.bind(this);
68
46
  this.onPairingSuccessHandler = this.onPairingSuccess.bind(this);
@@ -81,6 +59,10 @@ class DevicePairingService extends service_2.IncyclistService {
81
59
  }
82
60
  start(onStateChanged) {
83
61
  return __awaiter(this, void 0, void 0, function* () {
62
+ if (this.state.stopped) {
63
+ this.state.stopped = false;
64
+ this.state.deleted = [];
65
+ }
84
66
  try {
85
67
  if (this.settings.onStateChanged) {
86
68
  this.settings.onStateChanged = onStateChanged;
@@ -89,7 +71,9 @@ class DevicePairingService extends service_2.IncyclistService {
89
71
  }
90
72
  yield this.waitForInit();
91
73
  const { capabilities, interfaces } = this.configuration.load();
92
- this.state.capabilities = (0, exports.mappedCapabilities)(capabilities);
74
+ const state = Object.assign({}, this.state);
75
+ delete state.adapters;
76
+ this.state.capabilities = this.mappedCapabilities(capabilities);
93
77
  this.state.interfaces = this.access.enrichWithAccessState(interfaces);
94
78
  this.state.canStartRide = this.configuration.canStartRide();
95
79
  this.state.stopRequested = false;
@@ -129,6 +113,11 @@ class DevicePairingService extends service_2.IncyclistService {
129
113
  this.removeConfigHandlers();
130
114
  this.settings = {};
131
115
  this.state.initialized = false;
116
+ this.state.waiting = false;
117
+ this.state.check = null;
118
+ this.state.scan = null;
119
+ this.state.stopRequested = false;
120
+ this.state.stopped = true;
132
121
  }
133
122
  catch (err) {
134
123
  this.logError(err, 'stop');
@@ -140,7 +129,7 @@ class DevicePairingService extends service_2.IncyclistService {
140
129
  const capabilityData = this.getCapability(capability);
141
130
  this.settings = Object.assign(this.settings || {}, { onDeviceSelectStateChanged, capabilityForScan: capability });
142
131
  const devices = (capabilityData === null || capabilityData === void 0 ? void 0 : capabilityData.devices) || [];
143
- const available = devices.filter(d => this.isInterfaceEnabled(d.interface));
132
+ const available = devices.filter(d => this.isInterfaceEnabled(d.interface)).filter(d => !this.isOnDeletedList(capability, d.udid));
144
133
  const startScan = () => __awaiter(this, void 0, void 0, function* () {
145
134
  if (devices.length > 0)
146
135
  yield this.stopAdaptersWithCapability(capability);
@@ -246,15 +235,6 @@ class DevicePairingService extends service_2.IncyclistService {
246
235
  if (!changed)
247
236
  return;
248
237
  this.configuration.setInterfaceSettings(name, settings);
249
- if (settings.enabled) {
250
- this.connectInterface(name);
251
- }
252
- else {
253
- this.stopAdaptersOnInterface(name);
254
- this.disconnectInterface(name);
255
- }
256
- this.emitStateChange();
257
- yield this.restart();
258
238
  }
259
239
  catch (err) {
260
240
  this.logError(err, 'changeInterfaceSettings');
@@ -263,8 +243,17 @@ class DevicePairingService extends service_2.IncyclistService {
263
243
  }
264
244
  restart() {
265
245
  return __awaiter(this, void 0, void 0, function* () {
246
+ const wasActive = this.isPairing() || this.isScanning();
266
247
  yield this._stop();
267
- this.run();
248
+ if (wasActive) {
249
+ yield this.rideService.stop();
250
+ yield (0, utils_1.sleep)(500);
251
+ this.run();
252
+ }
253
+ if (this.state.waiting) {
254
+ this.state.waiting = false;
255
+ this.run();
256
+ }
268
257
  });
269
258
  }
270
259
  _stop() {
@@ -273,6 +262,8 @@ class DevicePairingService extends service_2.IncyclistService {
273
262
  yield this.stopPairing();
274
263
  if (this.isScanning())
275
264
  yield this.stopScanning();
265
+ this.state.capabilities.forEach(c => c.connectState = 'waiting');
266
+ this.state.waiting = true;
276
267
  });
277
268
  }
278
269
  getCapability(capability) {
@@ -284,14 +275,14 @@ class DevicePairingService extends service_2.IncyclistService {
284
275
  const c = this.getCapability(capability);
285
276
  if (!c)
286
277
  return false;
287
- return c.selected !== udid;
278
+ return c.selected !== udid && !this.isOnDeletedList(capability, udid);
288
279
  }
289
280
  getCapabilityDevice(capability, udid) {
290
281
  const c = this.getCapability(capability);
291
282
  if (!(c === null || c === void 0 ? void 0 : c.devices))
292
283
  return;
293
284
  if (udid) {
294
- return c.devices.find(d => d.udid === udid);
285
+ return c.devices.find(d => d.udid === udid && !this.isOnDeletedList(capability, udid));
295
286
  }
296
287
  else {
297
288
  return c.devices.find(d => d.selected);
@@ -301,7 +292,7 @@ class DevicePairingService extends service_2.IncyclistService {
301
292
  return __awaiter(this, void 0, void 0, function* () {
302
293
  if (this.state.initialized)
303
294
  return;
304
- this.state.capabilities = (0, exports.mappedCapabilities)(capabilitiesLoaded);
295
+ this.state.capabilities = this.mappedCapabilities(capabilitiesLoaded);
305
296
  this.state.canStartRide = this.configuration.canStartRide();
306
297
  this.state.interfaces = this.access.enrichWithAccessState(interfacesLoaded);
307
298
  this.state.initialized = true;
@@ -337,6 +328,8 @@ class DevicePairingService extends service_2.IncyclistService {
337
328
  delete state.scan;
338
329
  delete state.initialized;
339
330
  delete state.props;
331
+ delete state.deleted;
332
+ delete state.waiting;
340
333
  return state;
341
334
  }
342
335
  emitStateChange(newState) {
@@ -378,6 +371,7 @@ class DevicePairingService extends service_2.IncyclistService {
378
371
  current.port = settings.port;
379
372
  current.protocol = settings.protocol;
380
373
  this.emitStateChange();
374
+ this.restart();
381
375
  }
382
376
  catch (err) {
383
377
  this.logError(err, 'onInterfaceConfigChanged()');
@@ -404,7 +398,7 @@ class DevicePairingService extends service_2.IncyclistService {
404
398
  keys.forEach(key => {
405
399
  const newCap = newCapabilities[key];
406
400
  const current = capabilities.find(c => c.capability === key);
407
- this.mergeState(current, (0, exports.mappedCapability)(newCap));
401
+ this.mergeState(current, this.mappedCapability(newCap));
408
402
  });
409
403
  this.checkCanStart();
410
404
  }
@@ -467,7 +461,7 @@ class DevicePairingService extends service_2.IncyclistService {
467
461
  ci.forEach(c => {
468
462
  var _a;
469
463
  const { devices = [], disabled } = c;
470
- const deviceNames = devices.map(d => d.name).join(';');
464
+ const deviceNames = devices.filter(d => !this.isOnDeletedList(c.capability, d.udid)).map(d => d.name).join(';');
471
465
  const selected = (_a = devices.find(d => d.selected)) === null || _a === void 0 ? void 0 : _a.name;
472
466
  this.logEvent({ message: 'capability info', capability: c.capability, devices: deviceNames, selected, disabled });
473
467
  });
@@ -577,6 +571,8 @@ class DevicePairingService extends service_2.IncyclistService {
577
571
  return;
578
572
  capabilities.forEach(c => {
579
573
  var _a;
574
+ if (this.isOnDeletedList(c, udid))
575
+ return;
580
576
  const unitInfo = Units.find(ui => ui.capability === c.capability);
581
577
  const device = this.getCapabilityDevice(c, udid);
582
578
  if (unitInfo) {
@@ -619,6 +615,8 @@ class DevicePairingService extends service_2.IncyclistService {
619
615
  markConnected(adapter, udid) {
620
616
  const capabilites = adapter.getCapabilities();
621
617
  capabilites.forEach(c => {
618
+ if (this.isOnDeletedList(c, udid))
619
+ return;
622
620
  const info = this.getCapability(c);
623
621
  if (!info) {
624
622
  this.logEvent({ message: 'warning: capabability not found', c, caps: this.state.capabilities });
@@ -710,7 +708,7 @@ class DevicePairingService extends service_2.IncyclistService {
710
708
  run(props = {}) {
711
709
  return __awaiter(this, void 0, void 0, function* () {
712
710
  this.emit('run');
713
- if (this.isPairing() || this.isScanning()) {
711
+ if (this.isPairing() || this.isScanning() || !this.state.waiting) {
714
712
  yield this._stop();
715
713
  }
716
714
  if (this.state.stopRequested || this.state.stopped) {
@@ -743,14 +741,14 @@ class DevicePairingService extends service_2.IncyclistService {
743
741
  startPairing(adapters, props) {
744
742
  return __awaiter(this, void 0, void 0, function* () {
745
743
  this.emit('pairing-start');
746
- const isReady = !this.state.interfaces.find(i => i.enabled && i.state === 'connecting');
744
+ const isReady = !this.state.interfaces.find(i => i.enabled && i.state !== 'connected' && i.state !== 'unavailable');
747
745
  if (!isReady) {
748
746
  setTimeout(() => {
749
- this.run();
747
+ if (!this.isPairing() && !this.isScanning())
748
+ this.run();
750
749
  }, 1000);
751
750
  return;
752
751
  }
753
- this.logEvent({ message: 'Start Pairing', adapters, props });
754
752
  this.processConnectedDevices(adapters);
755
753
  const selected = this.state.capabilities.map(c => c.selected);
756
754
  const target = adapters.filter(ai => !ai.adapter.isStarted() && selected.includes(ai.udid));
@@ -759,12 +757,14 @@ class DevicePairingService extends service_2.IncyclistService {
759
757
  const promise = this.rideService.startAdapters(selectedAdapters, 'pair');
760
758
  this.state.check = { promise };
761
759
  this.onPairingStarted();
760
+ this.logEvent({ message: 'Start Pairing', adapters, props });
762
761
  yield this.state.check.promise;
763
762
  if (this.state.check)
764
763
  delete this.state.check;
765
764
  this.emit('pairing-done');
766
765
  if (!this.checkPairingSuccess()) {
767
766
  this.logEvent({ message: 'Pairing done', adapters, props });
767
+ yield this.rideService.stop();
768
768
  yield (0, utils_1.sleep)(this.getPairingRetryDelay());
769
769
  if (!this.state.scan)
770
770
  this.run();
@@ -790,7 +790,8 @@ class DevicePairingService extends service_2.IncyclistService {
790
790
  const interfaces = this.state.interfaces.filter(i => this.isInterfaceEnabled(i)) || [].map(i => i.name);
791
791
  if (interfaces.length === 0) {
792
792
  setTimeout(() => {
793
- this.run();
793
+ if (!this.isPairing() && !this.isScanning())
794
+ this.run();
794
795
  }, 1000);
795
796
  return;
796
797
  }
@@ -919,7 +920,9 @@ class DevicePairingService extends service_2.IncyclistService {
919
920
  const impactedCapabilties = this.getCapabilitiesUsingInterface(name);
920
921
  const enabledInterfaces = this.getEnabedInterfaces().filter(i => i.name !== name).map(i => i.name);
921
922
  impactedCapabilties.forEach(c => {
922
- const available = c.devices.filter(d => d.interface !== name && enabledInterfaces.includes(d.interface));
923
+ const available = c.devices
924
+ .filter(d => d.interface !== name && enabledInterfaces.includes(d.interface))
925
+ .filter(d => !this.isOnDeletedList(c, d.udid));
923
926
  if (!(available === null || available === void 0 ? void 0 : available.length)) {
924
927
  this.configuration.unselect(c.capability, true);
925
928
  }
@@ -932,7 +935,9 @@ class DevicePairingService extends service_2.IncyclistService {
932
935
  const impactedCapabilties = this.state.capabilities.filter(c => !c.selected);
933
936
  const enabledInterfaces = this.getEnabedInterfaces().filter(i => i.name !== name).map(i => i.name);
934
937
  impactedCapabilties.forEach(c => {
935
- const available = c.devices.filter(d => d.interface === name || enabledInterfaces.includes(d.interface));
938
+ const available = c.devices
939
+ .filter(d => d.interface === name || enabledInterfaces.includes(d.interface))
940
+ .filter(d => !this.isOnDeletedList(c, d.udid));
936
941
  if ((available === null || available === void 0 ? void 0 : available.length) > 0) {
937
942
  this.configuration.select(available[0].udid, c.capability, { emit: true });
938
943
  }
@@ -1029,6 +1034,7 @@ class DevicePairingService extends service_2.IncyclistService {
1029
1034
  c.connectState = undefined;
1030
1035
  }
1031
1036
  this.configuration.delete(udid, capability, shouldEmit);
1037
+ this.addToDeletedList(capability, udid);
1032
1038
  this.emitStateChange({ capabilities: this.state.capabilities });
1033
1039
  }
1034
1040
  isScanning() {
@@ -1056,6 +1062,44 @@ class DevicePairingService extends service_2.IncyclistService {
1056
1062
  numberOfSelectedCababilities(udid) {
1057
1063
  return (this.state.capabilities || []).map(c => c.selected === udid ? 1 : 0).reduce((a, c) => a + c, 0);
1058
1064
  }
1065
+ addToDeletedList(capability, udid) {
1066
+ if (this.isOnDeletedList(capability, udid))
1067
+ return;
1068
+ const c = this.getCapability(capability);
1069
+ this.state.deleted.push({ capability: c.capability, udid });
1070
+ }
1071
+ removeFromDeletedList(capability, udid) {
1072
+ const c = this.getCapability(capability);
1073
+ const idx = this.state.deleted.findIndex(e => e.capability === c.capability && e.udid === udid);
1074
+ if (idx === -1)
1075
+ return;
1076
+ this.state.deleted.splice(idx, 1);
1077
+ }
1078
+ isOnDeletedList(c, udid) {
1079
+ const capability = this.getCapability(c);
1080
+ return this.state.deleted.find(e => e.capability === capability.capability && e.udid === udid) !== undefined;
1081
+ }
1082
+ mappedCapability(c) {
1083
+ var _a, _b, _c;
1084
+ const { devices } = c;
1085
+ const mapped = Object.assign({}, c);
1086
+ const available = devices.filter(d => !this.isOnDeletedList(c.capability, d.udid));
1087
+ mapped.deviceNames = available.map(d => d.name).join(';');
1088
+ mapped.selected = (_a = available.find(d => d.selected)) === null || _a === void 0 ? void 0 : _a.udid;
1089
+ mapped.deviceName = (_b = devices.find(d => d.selected)) === null || _b === void 0 ? void 0 : _b.name;
1090
+ mapped.interface = (_c = devices.find(d => d.selected)) === null || _c === void 0 ? void 0 : _c.interface;
1091
+ mapped.devices = devices;
1092
+ return mapped;
1093
+ }
1094
+ mappedCapabilities(capabilities) {
1095
+ const caps = [];
1096
+ const ci = capabilities ? Object.keys(capabilities) || [] : [];
1097
+ ci.forEach(name => {
1098
+ const c = capabilities[name];
1099
+ caps.push(this.mappedCapability(c));
1100
+ });
1101
+ return caps;
1102
+ }
1059
1103
  }
1060
1104
  exports.DevicePairingService = DevicePairingService;
1061
1105
  const useDevicePairing = () => DevicePairingService.getInstance();
@@ -529,7 +529,10 @@ class DeviceRideService extends events_1.default {
529
529
  this.verifySelected(selectedDevices, incyclist_devices_1.IncyclistCapability.Speed);
530
530
  this.verifySelected(selectedDevices, incyclist_devices_1.IncyclistCapability.Cadence);
531
531
  this.verifySelected(selectedDevices, incyclist_devices_1.IncyclistCapability.Power);
532
- const enabledCapabilities = selectedDevices.filter(sd => sd.selected === adapterInfo.udid).map(c => c.capability);
532
+ const enabledCapabilities = this.enforceSimulator ?
533
+ [incyclist_devices_1.IncyclistCapability.Control, incyclist_devices_1.IncyclistCapability.Power, incyclist_devices_1.IncyclistCapability.Speed, incyclist_devices_1.IncyclistCapability.HeartRate, incyclist_devices_1.IncyclistCapability.Cadence]
534
+ :
535
+ selectedDevices.filter(sd => sd.selected === adapterInfo.udid).map(c => c.capability);
533
536
  this.logEvent({ message: 'Data Update', device: adapterInfo.adapter.getName(), data, enabledCapabilities });
534
537
  enabledCapabilities.forEach(capability => {
535
538
  switch (capability) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-services",
3
- "version": "1.0.52",
3
+ "version": "1.0.54",
4
4
  "peerDependencies": {
5
5
  "gd-eventlog": "^0.1.24"
6
6
  },
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "axios": "^1.6.1",
42
- "incyclist-devices": "^2.1.21",
42
+ "incyclist-devices": "^2.1.22",
43
43
  "uuid": "^9.0.0"
44
44
  }
45
45
  }