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 =>
|
|
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
|
-
|
|
344
|
-
.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
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
|
|
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
|
-
|
|
551
|
+
const i = incyclist_devices_1.InterfaceFactory.create(ifName);
|
|
547
552
|
const promisesStop = [];
|
|
548
553
|
adapters.map(ai => {
|
|
549
|
-
|
|
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
|
-
|
|
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.
|
|
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 (
|
|
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.
|
|
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.
|
|
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.
|
|
42
|
+
"incyclist-devices": "^2.1.31",
|
|
43
43
|
"uuid": "^9.0.0",
|
|
44
44
|
"xml2js": "^0.6.2"
|
|
45
45
|
}
|