@@ -36,12 +36,15 @@ RegisterMainLogger();
36
36
37
37
const CONNECTION_RETRY_PERIOD = 3000 ;
38
38
const DRIVE_RETRY_PERIOD = 1000 ;
39
- const BATTERY_POLL_PERIOD = 30 * 1000 ;
40
- const CLOCK_POLL_PERIOD = 5 * 1000 ;
41
39
const SENSOR_POLL_WAIT_PERIOD = 10 ;
42
40
const DEFAULT_RETRY_COUNT = 3 ;
43
41
const DEFAULT_RETRY_DELAY = 500 ;
44
42
43
+ const BATTERY_FAST_POLL_PERIOD = 3 * 1000 ;
44
+ const CLOCK_FAST_POLL_PERIOD = 3 * 1000 ;
45
+ const BATTERY_SLOW_POLL_PERIOD = 30 * 1000 ;
46
+ const CLOCK_SLOW_POLL_PERIOD = 60 * 1000 ;
47
+
45
48
const IMU_POLL_COMMAND = 'S0' ;
46
49
const PHO_POLL_COMMAND = 'S1' ;
47
50
const TOF_POLL_COMMAND = 'S2' ;
@@ -55,6 +58,28 @@ export const CALIBRATIONDB_PATH = () => path.join(FIRMWARE_PATH(), 'calibrationD
55
58
export const DOCUMENTATION_PATH = ( ) => path . join ( ROOT_RESOURCE_PATH ( ) , 'documentation' ) ;
56
59
const VEET_MANUAL_PATH = ( ) => path . join ( DOCUMENTATION_PATH ( ) , 'VEET 2.0 Device Manual.pdf' ) ;
57
60
61
+
62
+ class PollingHelper {
63
+ timeoutHandler_ : NodeJS . Timeout | null = null ;
64
+ isPolling_ = true ;
65
+ constructor ( readonly pollingCallback : ( ) => Promise < number > ) {
66
+ this . runPolling ( ) ;
67
+ }
68
+ public stop ( ) {
69
+ this . isPolling_ = false ;
70
+ this . timeoutHandler_ && clearTimeout ( this . timeoutHandler_ ) ;
71
+ this . timeoutHandler_ = null ;
72
+ }
73
+ private runPolling ( ) {
74
+ void this . pollingCallback ( ) . then ( nextDelay => {
75
+ if ( nextDelay > 0 && this . isPolling_ ) {
76
+ this . timeoutHandler_ = setTimeout ( ( ) => this . runPolling ( ) , nextDelay ) ;
77
+ }
78
+ } ) ;
79
+ }
80
+ }
81
+
82
+
58
83
export class MainWindow {
59
84
private serialManager_ : SerialManager ;
60
85
private browserWindow_ : BrowserWindow | undefined = undefined ;
@@ -64,8 +89,8 @@ export class MainWindow {
64
89
private streamRecorder_ : StreamRecorder | undefined = undefined ;
65
90
66
91
// Intervals
67
- private batteryInterval_ : NodeJS . Timeout | null = null ;
68
- private clockInterval_ : NodeJS . Timeout | null = null ;
92
+ private batteryPoller_ : PollingHelper | null = null ;
93
+ private clockPoller_ : PollingHelper | null = null ;
69
94
private connectionRetry_ : NodeJS . Timeout | null = null ;
70
95
private driveRetry_ : NodeJS . Timeout | null = null ;
71
96
private driveWatch_ : FSWatcher | null = null ;
@@ -206,29 +231,32 @@ export class MainWindow {
206
231
return await this . serialManager_ . runCommand ( cmd ) ;
207
232
} ;
208
233
234
+
235
+
209
236
startPolls = async ( ) => {
210
- if ( this . batteryInterval_ == null ) {
211
- await this . pollBattery ( ) ;
212
- this . batteryInterval_ = setInterval ( this . pollBattery , BATTERY_POLL_PERIOD ) ;
237
+ if ( this . batteryPoller_ ) {
238
+ this . batteryPoller_ . stop ( ) ;
213
239
}
214
- if ( this . clockInterval_ == null ) {
215
- await this . pollClock ( ) ;
216
- this . clockInterval_ = setInterval ( this . pollClock , CLOCK_POLL_PERIOD ) ;
240
+ this . batteryPoller_ = new PollingHelper ( this . pollBattery ) ;
241
+
242
+
243
+ if ( this . clockPoller_ ) {
244
+ this . clockPoller_ . stop ( ) ;
217
245
}
246
+ this . clockPoller_ = new PollingHelper ( this . pollClock ) ;
247
+
248
+ // Start polling
218
249
void this . startPollSensorThread ( ) ; // note that this doesn't need to be stopped as it sleeps itself. also don't await this one
219
250
} ;
220
251
221
252
stopPolls = ( ) => {
222
- if ( this . batteryInterval_ != null ) {
223
- clearInterval ( this . batteryInterval_ ) ;
224
- this . batteryInterval_ = null ;
225
- setDatastoreValue ( 'batteryPct' , null ) ;
226
- setDatastoreValue ( 'batteryMV' , null ) ;
227
- }
228
- if ( this . clockInterval_ != null ) {
229
- clearInterval ( this . clockInterval_ ) ;
230
- this . clockInterval_ = null ;
231
- }
253
+ this . batteryPoller_ ?. stop ( ) ;
254
+ this . batteryPoller_ = null ;
255
+ this . clockPoller_ ?. stop ( ) ;
256
+ this . clockPoller_ = null ;
257
+
258
+ setDatastoreValue ( 'batteryPct' , null ) ;
259
+ setDatastoreValue ( 'batteryMV' , null ) ;
232
260
} ;
233
261
234
262
stopDriveWatch = ( ) => {
@@ -307,11 +335,12 @@ export class MainWindow {
307
335
308
336
} ;
309
337
310
- pollBattery = async ( ) => {
338
+ private pollBattery = async ( ) : Promise < number > => {
311
339
if ( ! this . isConnected_ ) {
312
340
// We're disconnected. Shouldn't be called, so just return
313
- return ;
341
+ return BATTERY_FAST_POLL_PERIOD ;
314
342
}
343
+
315
344
const batteryString = await this . runCommand ( null , 'GB' ) ;
316
345
if ( batteryString ) {
317
346
@@ -331,15 +360,19 @@ export class MainWindow {
331
360
if ( mv < 100 || mv > 6000 ) {
332
361
// probably an invalid string
333
362
logger . error ( `Invalid battery response: "${ batteryString } "` ) ;
334
- return ;
363
+ return BATTERY_FAST_POLL_PERIOD ;
335
364
}
336
365
// Map to a percentage. This is very rough, and things get wonky at the extremes, but we'll call anything over
337
366
// 4.1V 100%, and anything less than 3.6V 1%, and linearly interpolate
338
367
const frac = Math . max ( invLerpClamped ( 3600 , 4100 , mv ) , 0.01 ) ;
339
368
setDatastoreValue ( 'batteryPct' , frac ) ;
340
369
setDatastoreValue ( 'batteryMV' , mv ) ;
341
370
logger . info ( `${ batteryString } -> ${ ( frac * 100 ) . toFixed ( 1 ) } %` ) ;
371
+
372
+ // Valid battery value, so poll at the slower rate
373
+ return BATTERY_SLOW_POLL_PERIOD ;
342
374
}
375
+ return BATTERY_FAST_POLL_PERIOD ;
343
376
} ;
344
377
345
378
checkDriveSpace = async ( ) => {
@@ -580,11 +613,12 @@ export class MainWindow {
580
613
return await this . runCommand ( null , `ST${ curEpoch } ` ) ;
581
614
} ;
582
615
583
- pollClock = async ( ) => {
616
+ private pollClock = async ( ) : Promise < number > => {
584
617
if ( ! this . isConnected_ ) {
585
618
// We're disconnected. Shouldn't be called, so just return
586
- return ;
619
+ return CLOCK_FAST_POLL_PERIOD ;
587
620
}
621
+
588
622
// Note that with the current serial connection, it will take an extra second or so
589
623
// before we get the time back from the VEET, but we do not need precision timing
590
624
const timeString = await this . runCommand ( null , 'GT' ) ;
@@ -598,13 +632,18 @@ export class MainWindow {
598
632
if ( diff < - 5 ) {
599
633
logger . info ( `VEET is ${ - diff } seconds behind, syncing` ) ;
600
634
await this . syncClock ( ) ;
635
+ return CLOCK_FAST_POLL_PERIOD ;
601
636
} else if ( diff > 5 ) {
602
637
logger . info ( `VEET is ${ diff } seconds ahead, syncing` ) ;
603
638
await this . syncClock ( ) ;
639
+ return CLOCK_FAST_POLL_PERIOD ;
604
640
} else {
605
641
logger . info ( 'VEET is within 5 seconds of your PC' ) ;
642
+ // Normal clock time, so poll at the slower rate
643
+ return CLOCK_SLOW_POLL_PERIOD ;
606
644
}
607
645
}
646
+ return CLOCK_SLOW_POLL_PERIOD ;
608
647
} ;
609
648
610
649
startPollSensorThread = async ( ) => {
0 commit comments