@@ -187,6 +187,12 @@ function refreshFromIBM_() {
187
187
"in" : Number ( ibmConditions . imperial . precipTotal ) . toFixedNumber ( 3 ) ,
188
188
"mm" : Number ( ibmConditions . imperial . precipTotal ) . inTomm ( ) . toFixedNumber ( 2 )
189
189
} ;
190
+
191
+ let calculatedHourlyPrecipRate = getCalculatedHourlyPrecipRate_ ( conditions . precipRate . in ) ;
192
+ if ( calculatedHourlyPrecipRate != null ) conditions . precipLastHour = {
193
+ "in" : Number ( calculatedHourlyPrecipRate ) . toFixedNumber ( 3 ) ,
194
+ "mm" : Number ( calculatedHourlyPrecipRate ) . inTomm ( ) . toFixedNumber ( 2 )
195
+ } ;
190
196
191
197
console . log ( JSON . stringify ( conditions ) ) ;
192
198
@@ -341,6 +347,12 @@ function refreshFromAcurite_() {
341
347
"in" : rain . chart_unit === 'in' ? Number ( rain . last_reading_value ) . toFixedNumber ( 3 ) : Number ( rain . last_reading_value ) . mmToIn ( ) . toFixedNumber ( 3 ) ,
342
348
"mm" : rain . chart_unit === 'mm' ? Number ( rain . last_reading_value ) . toFixedNumber ( 2 ) : Number ( rain . last_reading_value ) . inTomm ( ) . toFixedNumber ( 2 )
343
349
} ;
350
+
351
+ let calculatedHourlyPrecipRate = getCalculatedHourlyPrecipRate_ ( conditions . precipRate . in ) ;
352
+ if ( calculatedHourlyPrecipRate != null ) conditions . precipLastHour = {
353
+ "in" : Number ( calculatedHourlyPrecipRate ) . toFixedNumber ( 3 ) ,
354
+ "mm" : Number ( calculatedHourlyPrecipRate ) . inTomm ( ) . toFixedNumber ( 2 )
355
+ } ;
344
356
345
357
console . log ( JSON . stringify ( conditions ) ) ;
346
358
@@ -598,6 +610,12 @@ function refreshFromAmbientWeather_() {
598
610
"mm" : Number ( station . lastData [ '24hourrainin' ] ) . inTomm ( ) . toFixedNumber ( 2 )
599
611
} ;
600
612
613
+ let calculatedHourlyPrecipRate = getCalculatedHourlyPrecipRate_ ( conditions . precipRate . in ) ;
614
+ if ( calculatedHourlyPrecipRate != null ) conditions . precipLastHour = {
615
+ "in" : Number ( calculatedHourlyPrecipRate ) . toFixedNumber ( 3 ) ,
616
+ "mm" : Number ( calculatedHourlyPrecipRate ) . inTomm ( ) . toFixedNumber ( 2 )
617
+ } ;
618
+
601
619
console . log ( JSON . stringify ( conditions ) ) ;
602
620
603
621
CacheService . getScriptCache ( ) . put ( 'conditions' , JSON . stringify ( conditions ) , 21600 ) ;
@@ -671,6 +689,12 @@ function refreshFromAPRSFI() {
671
689
"mm" : Number ( aprsConditions . rain_24h ) . toFixedNumber ( 2 )
672
690
} ;
673
691
692
+ let calculatedHourlyPrecipRate = getCalculatedHourlyPrecipRate_ ( conditions . precipRate . in ) ;
693
+ if ( calculatedHourlyPrecipRate != null ) conditions . precipLastHour = {
694
+ "in" : Number ( calculatedHourlyPrecipRate ) . toFixedNumber ( 3 ) ,
695
+ "mm" : Number ( calculatedHourlyPrecipRate ) . inTomm ( ) . toFixedNumber ( 2 )
696
+ } ;
697
+
674
698
console . log ( JSON . stringify ( conditions ) ) ;
675
699
676
700
CacheService . getScriptCache ( ) . put ( 'conditions' , JSON . stringify ( conditions ) , 21600 ) ;
@@ -1047,35 +1071,33 @@ function updateCWOP_() {
1047
1071
}
1048
1072
1049
1073
function getCalculatedHourlyPrecipRate_ ( currentPrecipRate ) {
1050
-
1051
- let precipHistory = JSON . parse ( CacheService . getScriptCache ( ) . get ( 'calculatedHourlyPrecipRate' ) || '[]' ) ;
1052
1074
1053
- let now = new Date ( ) ;
1054
-
1055
- // add the new reading with a timestamp
1056
- precipHistory . push ( {
1057
- "rate" : currentPrecipRate ,
1058
- "timestamp" : now . getTime ( )
1059
- } ) ;
1060
-
1061
- // remove entries older than 1 hour
1062
- const oneHourAgo = now . getTime ( ) - 3600000 ;
1063
- precipHistory = precipHistory . filter ( entry => entry . timestamp >= oneHourAgo ) ;
1064
-
1065
- console . log ( JSON . stringify ( precipHistory ) ) ;
1066
-
1067
- CacheService . getScriptCache ( ) . put ( 'calculatedHourlyPrecipRate' , JSON . stringify ( precipHistory ) , 21600 ) ; // 6 hours
1075
+ const ONE_HOUR_MS = 3600000 ; // 1 hour in milliseconds
1068
1076
1069
- // calculate the average if we have data spanning close to an hour
1070
- if ( precipHistory . length > 1 &&
1071
- ( precipHistory [ precipHistory . length - 1 ] . timestamp - precipHistory [ 0 ] . timestamp ) >= 3600000 * 0.9 ) { // are there two or more readings spanning almost an hour?
1072
- const sum = precipHistory . reduce ( ( acc , entry ) => acc + entry . rate , 0 ) ;
1073
- const average = sum / precipHistory . length ;
1074
- return average ;
1075
- } else {
1076
- return null ; // not enough data spanning an hour yet
1077
+ let precipHistory = JSON . parse ( CacheService . getScriptCache ( ) . get ( 'calculatedHourlyPrecipRate' ) || '[]' ) ;
1078
+ const currentTime = new Date ( ) . getTime ( ) ;
1079
+
1080
+ // add the new reading and remove old entries
1081
+ precipHistory . push ( { rate : currentPrecipRate , timestamp : currentTime } ) ;
1082
+ precipHistory = precipHistory . filter ( entry => entry . timestamp >= currentTime - ONE_HOUR_MS ) ;
1083
+
1084
+ // save the updated history back to cache
1085
+ CacheService . getScriptCache ( ) . put ( 'calculatedHourlyPrecipRate' , JSON . stringify ( precipHistory ) , 21600 ) ; // 6 hours cache
1086
+
1087
+ // calculate the accumulation if we have sufficient data
1088
+ if ( precipHistory . length > 1 && currentTime - precipHistory [ 0 ] . timestamp >= ONE_HOUR_MS * 0.95 ) { // are there two or more readings spanning almost an hour?
1089
+ const totalPrecip = precipHistory . reduce ( ( acc , entry , index , array ) => {
1090
+ if ( index === 0 ) return acc ; // skip the first entry
1091
+ const prevEntry = array [ index - 1 ] ;
1092
+ const timeFraction = ( entry . timestamp - prevEntry . timestamp ) / ONE_HOUR_MS ; // how much of one hour does the last entry to this entry represent
1093
+ return acc + prevEntry . rate * timeFraction ; // add that much of the rain rate during that fraction of the hour to the total
1094
+ } , 0 ) ;
1095
+
1096
+ return totalPrecip ;
1077
1097
}
1078
1098
1099
+ return null ; // not enough data spanning an hour yet
1100
+
1079
1101
}
1080
1102
1081
1103
// https://gist.github.com/rcknr/ad7d4623b0a2d90415323f96e634cdee
0 commit comments