incyclist-services 1.0.70 → 1.0.72

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.
@@ -823,7 +823,7 @@ class DevicePairingService extends service_2.IncyclistService {
823
823
  this.state.tsPrevStart = Date.now();
824
824
  this.processConnectedDevices(adapters);
825
825
  const selected = this.state.capabilities.map(c => c.selected);
826
- const target = adapters.filter(ai => !ai.adapter.isStarted() && selected.includes(ai.udid));
826
+ const target = adapters.filter(ai => selected.includes(ai.udid));
827
827
  if (this.isPairing() && this.state.check.preparing !== preparing) {
828
828
  return;
829
829
  }
@@ -340,29 +340,35 @@ class DeviceRideService extends events_1.default {
340
340
  }
341
341
  }
342
342
  checkAntSameDeviceID(adapters) {
343
- const antDevices = adapters.map((ai, idx) => (Object.assign(Object.assign({}, ai), { idx })))
344
- .filter(ai => ai.adapter.getInterface() === 'ant')
345
- .map(ai => ({ idx: ai.idx, deviceID: ai.adapter.getID(), capabilities: ai.capabilities, udid: ai.udid }));
346
- const antDeviceIds = antDevices.map(di => di.deviceID);
347
- const duplicateIds = antDeviceIds.filter((item, index) => antDeviceIds.indexOf(item) !== index);
348
- const score = (capabilities) => {
349
- let value = 0;
350
- if (capabilities.includes(incyclist_devices_1.IncyclistCapability.Control))
351
- value += 100;
352
- if (capabilities.includes(incyclist_devices_1.IncyclistCapability.Power))
353
- value += 50;
354
- value += capabilities.length;
355
- return value;
356
- };
357
- const duplicateDevices = antDevices.filter(di => duplicateIds.includes(di.deviceID)).sort((a, b) => score(b.capabilities) - score(a.capabilities));
358
- const leading = duplicateDevices[0];
359
- const duplicateAdapters = [];
360
- duplicateDevices.forEach((di, i) => {
361
- if (i == 0)
362
- return;
363
- duplicateAdapters.push({ udid: leading.udid, info: adapters[di.idx] });
364
- });
365
- return duplicateAdapters;
343
+ try {
344
+ const antDevices = adapters.map((ai, idx) => (Object.assign(Object.assign({}, ai), { idx })))
345
+ .filter(ai => ai.adapter.getInterface() === 'ant')
346
+ .map(ai => ({ idx: ai.idx, deviceID: ai.adapter.getID(), capabilities: ai.capabilities, udid: ai.udid }));
347
+ const antDeviceIds = antDevices.map(di => di.deviceID);
348
+ const duplicateIds = antDeviceIds.filter((item, index) => antDeviceIds.indexOf(item) !== index);
349
+ const score = (capabilities) => {
350
+ let value = 0;
351
+ if (capabilities.includes(incyclist_devices_1.IncyclistCapability.Control))
352
+ value += 100;
353
+ if (capabilities.includes(incyclist_devices_1.IncyclistCapability.Power))
354
+ value += 50;
355
+ value += capabilities.length;
356
+ return value;
357
+ };
358
+ const duplicateDevices = antDevices.filter(di => duplicateIds.includes(di.deviceID)).sort((a, b) => score(b.capabilities) - score(a.capabilities));
359
+ const leading = duplicateDevices[0];
360
+ const duplicateAdapters = [];
361
+ duplicateDevices.forEach((di, i) => {
362
+ if (i == 0)
363
+ return;
364
+ duplicateAdapters.push({ udid: leading.udid, info: adapters[di.idx] });
365
+ });
366
+ return duplicateAdapters;
367
+ }
368
+ catch (err) {
369
+ console.log('~~~~ ERROR', err);
370
+ return [];
371
+ }
366
372
  }
367
373
  startAdapters(adapters, startType, props) {
368
374
  return __awaiter(this, void 0, void 0, function* () {
@@ -474,6 +480,8 @@ class DeviceRideService extends events_1.default {
474
480
  }
475
481
  startHealthCheck(ai) {
476
482
  const check = () => {
483
+ if (!ai.ivToCheck)
484
+ return;
477
485
  const tsNow = Date.now();
478
486
  const isPaused = ai.adapter.isPaused();
479
487
  const prevStatus = ai.dataStatus;
@@ -492,7 +500,6 @@ class DeviceRideService extends events_1.default {
492
500
  if (ai.isHealthy && (isAmber || isRed)) {
493
501
  ai.isHealthy = false;
494
502
  this.logEvent({ message: 'device unhealthy', device: ai.adapter.getUniqueName(), udid: ai.udid });
495
- console.log('~~~~ health check: prepare reconnect');
496
503
  this.prepareReconnect(ai);
497
504
  }
498
505
  else if (!ai.isHealthy && !isAmber && !isRed) {
@@ -504,7 +511,10 @@ class DeviceRideService extends events_1.default {
504
511
  this.emit('health', ai.udid, ai.dataStatus, enabledCapabilities);
505
512
  }
506
513
  };
507
- ai.ivToCheck = (0, timers_1.setInterval)(check, 1000);
514
+ if (ai.ivToCheck) {
515
+ this.stopHealthCheck(ai);
516
+ }
517
+ ai.ivToCheck = (0, timers_1.setInterval)(() => { check(); }, 1000);
508
518
  ai.isHealthy = true;
509
519
  }
510
520
  stopHealthCheck(ai) {
@@ -518,12 +528,9 @@ class DeviceRideService extends events_1.default {
518
528
  return __awaiter(this, void 0, void 0, function* () {
519
529
  if (unhealthy.isRestarting)
520
530
  return;
521
- console.log('~~~~ health check: wait 45s', unhealthy.udid);
522
531
  yield (0, sleep_1.sleep)(UNHEALTHY_THRESHOLD - NO_DATA_THRESHOLD - 5000);
523
532
  if (unhealthy.isHealthy || unhealthy.isRestarting)
524
533
  return;
525
- console.log('~~~~ health check: still unhealthy', unhealthy.udid, unhealthy.isHealthy, unhealthy.isRestarting);
526
- unhealthy.isRestarting = true;
527
534
  const ifName = unhealthy.adapter.getInterface();
528
535
  const adapters = this.getAdapterList().filter(ai => ai.adapter.getInterface() === ifName);
529
536
  if (!adapters.find(ai => ai.isHealthy)) {
@@ -537,52 +544,50 @@ class DeviceRideService extends events_1.default {
537
544
  }
538
545
  reconnectInterface(ifName, adapters) {
539
546
  return __awaiter(this, void 0, void 0, function* () {
540
- console.log('~~~~ health check: restart interface', ifName);
541
547
  this.logger.logEvent({ message: 'restart interface', interface: ifName });
542
548
  let stopRequested = false;
543
549
  this.once('stop-ride', () => { stopRequested = true; });
544
- const i = incyclist_devices_1.InterfaceFactory.create(ifName);
545
550
  try {
546
- console.log('~~~~ health check: stop Adapters', ifName);
551
+ const i = incyclist_devices_1.InterfaceFactory.create(ifName);
547
552
  const promisesStop = [];
548
553
  adapters.map(ai => {
549
- if (ai.isRestarting) {
550
- promisesStop.push(this.stopAfterRestart(ai));
551
- }
552
- else {
553
- promisesStop.push(ai.adapter.stop());
554
- }
555
- ai.isRestarting = true;
556
- ai.adapter.off('data', this.deviceDataHandler);
554
+ promisesStop.push(this.stopAfterRestart(ai));
557
555
  });
558
556
  if (promisesStop.length > 0) {
559
- yield Promise.allSettled(promisesStop);
557
+ yield Promise.race([(0, sleep_1.sleep)(66000), Promise.allSettled(promisesStop)]);
560
558
  }
561
- console.log('~~~~ health check: reconnect interface', ifName);
562
559
  if (!stopRequested) {
563
560
  yield i.disconnect();
564
561
  yield (0, sleep_1.sleep)(1000);
565
562
  yield i.connect();
566
563
  }
567
- console.log('~~~~ health check: start adapters', ifName);
568
564
  if (!stopRequested) {
569
565
  const promisesStart = [];
570
566
  adapters.map(ai => { promisesStart.push(ai.adapter.start()); });
571
567
  if (promisesStart.length > 0) {
572
- yield Promise.allSettled(promisesStart);
568
+ if (ifName === 'ant') {
569
+ for (let i = 0; i < promisesStart.length; i++) {
570
+ try {
571
+ yield promisesStart[i];
572
+ }
573
+ catch (_a) {
574
+ }
575
+ }
576
+ }
577
+ else {
578
+ yield Promise.allSettled(promisesStart);
579
+ }
573
580
  }
574
581
  }
575
582
  }
576
583
  catch (err) {
577
584
  this.logger.logEvent({ message: 'restart interface failed', interface: ifName, reason: err.message });
578
- console.log('~~~~ health check: restart interface error', ifName, err);
579
585
  }
580
586
  adapters.map(ai => {
581
587
  if (ai.adapter.isStarted()) {
582
588
  ai.tsLastData = Date.now();
583
589
  }
584
590
  else {
585
- console.log('~~~~ health check: adapter still not healthy', ifName, ai.udid);
586
591
  ai.isRestarting = false;
587
592
  this.prepareReconnect(ai);
588
593
  }
@@ -593,19 +598,26 @@ class DeviceRideService extends events_1.default {
593
598
  }
594
599
  stopAfterRestart(unhealthy) {
595
600
  return __awaiter(this, void 0, void 0, function* () {
601
+ this.emit('stop-adapter', unhealthy.udid);
596
602
  if (unhealthy.isRestarting) {
597
603
  yield new Promise(done => {
604
+ const to = setTimeout(done, 65000);
598
605
  this.once('stop-adapter-confirmed', (udid) => {
599
- if (udid === unhealthy.udid)
606
+ if (udid === unhealthy.udid) {
607
+ clearTimeout(to);
600
608
  done();
609
+ }
601
610
  });
602
611
  });
603
612
  }
613
+ unhealthy.isRestarting = true;
614
+ unhealthy.adapter.off('data', this.deviceDataHandler);
604
615
  yield unhealthy.adapter.stop();
605
616
  });
606
617
  }
607
618
  reconnectSingle(unhealthy) {
608
619
  return __awaiter(this, void 0, void 0, function* () {
620
+ unhealthy.isRestarting = true;
609
621
  let stopRequested = false;
610
622
  this.once('stop-ride', () => { stopRequested = true; });
611
623
  this.once('stop-adapter', (udid) => {
@@ -614,7 +626,6 @@ class DeviceRideService extends events_1.default {
614
626
  });
615
627
  let success = false;
616
628
  do {
617
- console.log('~~~~ health check: restart adapter', unhealthy.udid);
618
629
  this.logger.logEvent({ message: 'restart adapter', device: unhealthy.udid });
619
630
  unhealthy.adapter.off('data', this.deviceDataHandler);
620
631
  const adapter = unhealthy.adapter;
@@ -677,7 +688,7 @@ class DeviceRideService extends events_1.default {
677
688
  startRide(_props) {
678
689
  const adapters = this.getAdapterList();
679
690
  adapters === null || adapters === void 0 ? void 0 : adapters.forEach(ai => {
680
- ai.adapter.removeAllListeners('data');
691
+ ai.adapter.off('data', this.deviceDataHandler);
681
692
  ai.adapter.on('data', this.deviceDataHandler);
682
693
  });
683
694
  }
@@ -705,6 +716,7 @@ class DeviceRideService extends events_1.default {
705
716
  ai.tsLastData = Date.now();
706
717
  ai.adapter.pause();
707
718
  ai.adapter.off('data', this.deviceDataHandler);
719
+ this.stopHealthCheck(ai);
708
720
  });
709
721
  }
710
722
  resume() {
@@ -713,6 +725,7 @@ class DeviceRideService extends events_1.default {
713
725
  ai.tsLastData = Date.now();
714
726
  ai.adapter.resume();
715
727
  ai.adapter.on('data', this.deviceDataHandler);
728
+ this.startHealthCheck(ai);
716
729
  });
717
730
  }
718
731
  verifySelected(selectedDevices, capability) {
@@ -222,7 +222,7 @@ class RouteListService extends service_1.IncyclistService {
222
222
  }
223
223
  console.log('~~~ DATA', content);
224
224
  const parser = parsers.findMatching(file.ext, content);
225
- const res = yield parser.import(file, content);
225
+ const res = yield parser.import(file, content, this.loader);
226
226
  const data = res.data;
227
227
  data.state = 'loaded';
228
228
  const details = res.data;
@@ -2,15 +2,19 @@ import { EventLogger } from 'gd-eventlog';
2
2
  import { IUserSettingsBinding } from './bindings';
3
3
  export declare class UserSettingsService {
4
4
  static _instance: UserSettingsService;
5
+ static _defaultBinding: IUserSettingsBinding;
5
6
  settings: any;
6
7
  binding: IUserSettingsBinding;
7
8
  logger: EventLogger;
8
9
  isInitialized: boolean;
9
10
  isDirty: boolean;
10
11
  savePromise: Promise<boolean> | null;
12
+ instanceId: number;
13
+ initPromise: Promise<boolean>;
11
14
  static getInstance(): UserSettingsService;
12
15
  constructor(binding?: IUserSettingsBinding);
13
16
  setBinding(binding: IUserSettingsBinding): void;
17
+ static setDefaultBinding(binding: IUserSettingsBinding): void;
14
18
  init(): Promise<boolean>;
15
19
  getAll(): any;
16
20
  get(key: string, defValue: any): any;
@@ -30,19 +30,29 @@ class UserSettingsService {
30
30
  this.isInitialized = false;
31
31
  this.isDirty = false;
32
32
  this.savePromise = null;
33
+ this.instanceId = Date.now();
34
+ this.initPromise = undefined;
33
35
  this.setBinding(binding);
34
36
  }
35
37
  setBinding(binding) {
36
38
  this.binding = binding;
39
+ UserSettingsService.setDefaultBinding(binding);
40
+ }
41
+ static setDefaultBinding(binding) {
42
+ UserSettingsService._defaultBinding = binding;
37
43
  }
38
44
  init() {
39
45
  return __awaiter(this, void 0, void 0, function* () {
40
46
  if (this.isInitialized)
41
47
  return true;
42
- if (!this.binding)
48
+ if (this.initPromise)
49
+ return yield this.initPromise;
50
+ const binding = this.binding || UserSettingsService._defaultBinding;
51
+ if (!binding)
43
52
  return false;
44
53
  try {
45
- this.settings = yield this.binding.getAll();
54
+ this.initPromise = binding.getAll();
55
+ this.settings = yield this.initPromise;
46
56
  this.logger.logEvent({ message: 'settings loaded' });
47
57
  this.isInitialized = true;
48
58
  return true;
@@ -175,6 +185,7 @@ exports.useUserSettings = useUserSettings;
175
185
  const initUserSettings = (binding) => {
176
186
  const us = UserSettingsService.getInstance();
177
187
  us.setBinding(binding);
188
+ us.init();
178
189
  return us;
179
190
  };
180
191
  exports.initUserSettings = initUserSettings;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-services",
3
- "version": "1.0.70",
3
+ "version": "1.0.72",
4
4
  "peerDependencies": {
5
5
  "gd-eventlog": "^0.1.26"
6
6
  },
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "axios": "^1.6.1",
42
- "incyclist-devices": "^2.1.29",
42
+ "incyclist-devices": "^2.1.31",
43
43
  "uuid": "^9.0.0",
44
44
  "xml2js": "^0.6.2"
45
45
  }