@@ -83,7 +83,7 @@ const settings: Record<string, string> = {
8383 AWC_ALLOW_CORS : 'true' ,
8484 AWC_KIOSK_MODE : 'true' ,
8585 AWC_LOG_CACHE_ACTIVITY : 'false' ,
86- AWC_NTP_SERVER : 'pool.ntp.org ' ,
86+ AWC_NTP_SERVERS : '' ,
8787 AWC_PORT : '8080' ,
8888 AWC_PREFERRED_WS : 'wunderground' ,
8989 AWC_WIRED_TH_GPIO : '17' ,
@@ -318,9 +318,17 @@ if (treatAsRaspberryPi) {
318318 if ( ! clearAcu && oldSettings . AWC_WIRELESS_TH_GPIO )
319319 doAcu = true ;
320320
321+ if ( ! settings . AWC_NTP_SERVERS ) {
322+ if ( oldSettings . AWC_NTP_SERVER === 'pool.ntp.org' )
323+ settings . AWC_NTP_SERVERS = '' ;
324+ else if ( oldSettings . AWC_NTP_SERVER )
325+ settings . AWC_NTP_SERVERS = oldSettings . AWC_NTP_SERVER ;
326+ }
327+
321328 delete settings . AWC_HAS_INDOOR_SENSOR ;
322329 delete settings . AWC_TH_SENSOR_GPIO ;
323330 delete settings . AWC_WIRELESS_TEMP ;
331+ delete settings . AWC_NTP_SERVER ;
324332
325333 if ( clearKiosk )
326334 doKiosk = false ;
@@ -605,46 +613,47 @@ function portValidate(s: string): boolean {
605613 return true ;
606614}
607615
616+ const DOMAIN_PATTERN =
617+ / ^ ( ( (? ! - ) ) ( x n - - | _ ) ? [ - a - z 0 - 9 ] { 0 , 61 } [ a - z 0 - 9 ] \. ) * ( x n - - ) ? ( [ a - z 0 - 9 ] [ - a - z 0 - 9 ] { 0 , 60 } | [ - a - z 0 - 9 ] { 1 , 30 } \. [ a - z ] { 2 , } ) ( : \d { 1 , 5 } ) ? $ / i;
618+
608619function ntpValidate ( s : string ) : boolean {
609- if ( / ^ ( ( (? ! - ) ) ( x n - - | _ ) ? [ - a - z 0 - 9 ] { 0 , 61 } [ a - z 0 - 9 ] \. ) * ( x n - - ) ? ( [ a - z 0 - 9 ] [ - a - z 0 - 9 ] { 0 , 60 } | [ - a - z 0 - 9 ] { 1 , 30 } \. [ a - z ] { 2 , } ) ( : \d { 1 , 5 } ) ? $ / i. test ( s ) )
620+ const domains = s . split ( ',' ) . map ( d => d . trim ( ) ) ;
621+
622+ if ( s . trim ( ) === '' || ( domains . length > 0 && domains . findIndex ( d => ! DOMAIN_PATTERN . test ( d ) ) < 0 ) )
610623 return true ;
611624
612- console . log ( chalk . redBright ( 'NTP server must be a valid domain name (with optional port number )' ) ) ;
625+ console . log ( chalk . redBright ( 'NTP servers must be a valid domain names (with optional port numbers )' ) ) ;
613626 return false ;
614627}
615628
616- const NO_MORE_DARK_SKY = ( Date . now ( ) > Date . parse ( '2021-11-30' ) ) ;
617-
618- if ( NO_MORE_DARK_SKY && process . env . AWC_PREFERRED_WS === 'darksky' )
629+ // Change out-of-date preference to default.
630+ if ( process . env . AWC_PREFERRED_WS === 'darksky' )
619631 process . env . AWC_PREFERRED_WS = 'wunderground' ;
620632
621633function wsValidate ( s : string ) : boolean | string {
622634 if ( / ^ w [ - b ] * $ / i. test ( s ) )
623635 return 'wunderground' ;
624636 else if ( / b / i. test ( s ) )
625637 return 'weatherbit' ;
626- else if ( ! NO_MORE_DARK_SKY && / ^ d / i. test ( s ) )
627- return 'darksky ' ;
638+ else if ( / ^ v / i. test ( s ) )
639+ return 'visual_x ' ;
628640
629- if ( NO_MORE_DARK_SKY )
630- console . log ( chalk . redBright ( 'Weather service must be either (w)underground, weather(b)it, or (d)arksky' ) ) ;
631- else
632- console . log ( chalk . redBright ( 'Weather service must be either (w)underground, or weather(b)it' ) ) ;
641+ console . log ( chalk . redBright ( 'Weather service must be either (w)underground, weather(b)it, or (v)isual crossing' ) ) ;
633642
634643 return false ;
635644}
636645
637646function wsAfter ( s : string ) : void {
638647 if ( / ^ w [ - b ] * $ / i. test ( s ) ) {
639- console . log ( chalk . paleBlue ( ` Weather Underground chosen, but Weatherbit.io${ NO_MORE_DARK_SKY ? '' : ' or Dark Sky' } can be used` ) ) ;
648+ console . log ( chalk . paleBlue ( ' Weather Underground chosen, but Weatherbit.io or Visual Crossing can be used' ) ) ;
640649 console . log ( chalk . paleBlue ( ' as fallback weather services.' ) ) ;
641650 }
642651 else if ( / b / i. test ( s ) ) {
643652 console . log ( chalk . paleBlue ( ' Weatherbit.io chosen, but Weather Underground will be used' ) ) ;
644653 console . log ( chalk . paleBlue ( ' as a fallback weather service.' ) ) ;
645654 }
646- else if ( / ^ d / i. test ( s ) ) {
647- console . log ( chalk . paleBlue ( ' Dark Sky chosen, but Weather Underground will be used' ) ) ;
655+ else if ( / ^ v / i. test ( s ) ) {
656+ console . log ( chalk . paleBlue ( ' Visual Crossing chosen, but Weather Underground will be used' ) ) ;
648657 console . log ( chalk . paleBlue ( ' as a fallback weather service.' ) ) ;
649658 }
650659}
@@ -722,7 +731,7 @@ let questions = [
722731 { prompt : 'Perform npm install? (N option for debug only)' , ask : true , yn : true , deflt : doNpmI ? 'Y' : 'N' , validate : npmIValidate } ,
723732 { name : 'AWC_PORT' , prompt : 'HTTP server port.' , ask : true , validate : portValidate } ,
724733 { prompt : 'Allow user to reboot, shutdown, update, etc.?' , ask : true , yn : true , deflt : doAdmin ? 'Y' : 'N' , validate : adminValidate } ,
725- { name : 'AWC_NTP_SERVER ' , prompt : 'time server ' , ask : true , validate : ntpValidate } ,
734+ { name : 'AWC_NTP_SERVERS ' , prompt : 'time servers (comma-separated domains, blank for defaults) ' , ask : true , validate : ntpValidate } ,
726735 {
727736 name : 'AWC_GOOGLE_API_KEY' ,
728737 prompt : 'Optional Google geocoding API key (for city names from\n GPS coordinates).' +
@@ -731,7 +740,7 @@ let questions = [
731740 } ,
732741 { // #5
733742 name : 'AWC_PREFERRED_WS' ,
734- prompt : 'preferred weather service, (w)underground, weather(b)it,\n or (d)arksky ).' ,
743+ prompt : 'preferred weather service, (w)underground, weather(b)it,\n or (v)isual crossing ).' ,
735744 ask : true ,
736745 validate : wsValidate ,
737746 after : wsAfter
@@ -743,9 +752,9 @@ let questions = [
743752 ask : true
744753 } ,
745754 { // #7
746- name : 'AWC_DARK_SKY_API_KEY ' ,
747- prompt : 'Optional Dark Sky weather API key.' +
748- ( settings . AWC_DARK_SKY_API_KEY ? '\n Enter - (dash) to remove old API key' : '' ) ,
755+ name : 'AWC_VISUAL_CROSSING_API_KEY ' ,
756+ prompt : 'Optional Visual Crossing weather API key.' +
757+ ( settings . AWC_VISUAL_CROSSING_API_KEY ? '\n Enter - (dash) to remove old API key' : '' ) ,
749758 ask : true
750759 } ,
751760 { prompt : 'Use wired DHT temperature/humidity sensor?' , ask : true , yn : true , deflt : doDht ? 'Y' : 'N' , validate : dhtValidate } ,
@@ -760,11 +769,6 @@ let questions = [
760769 }
761770] ;
762771
763- if ( NO_MORE_DARK_SKY ) {
764- questions [ 5 ] . prompt = 'preferred weather service, (w)underground, or weather(b)it' ;
765- questions . splice ( 7 , 1 ) ;
766- }
767-
768772if ( doDedicated ) {
769773 questions . splice ( questions . length - 1 , 0 ,
770774 { prompt : 'Launch browser in kiosk mode?' , ask : true , yn : true , deflt : doKiosk ? 'Y' : 'N' , validate : kioskValidate }
0 commit comments