github.com/simpleiot/simpleiot@v0.18.3/data/time_window_avg.go (about)

     1  package data
     2  
     3  import (
     4  	"time"
     5  )
     6  
     7  // TimeWindowAverager accumulates points, and averages them on a fixed time
     8  // period and outputs the average/min/max, etc as a point
     9  type TimeWindowAverager struct {
    10  	start     time.Time
    11  	windowLen time.Duration
    12  	total     float64
    13  	count     int
    14  	callBack  func(Point)
    15  	pointType string
    16  	pointTime time.Time
    17  }
    18  
    19  // NewTimeWindowAverager initializes and returns an averager
    20  func NewTimeWindowAverager(windowLen time.Duration, callBack func(Point), pointType string) *TimeWindowAverager {
    21  	return &TimeWindowAverager{
    22  		windowLen: windowLen,
    23  		callBack:  callBack,
    24  		pointType: pointType,
    25  	}
    26  }
    27  
    28  // NewPoint takes a point, and if the time window expired, it calls
    29  // the callback function with the a new point which is avg of
    30  // all points since start time.
    31  func (twa *TimeWindowAverager) NewPoint(s Point) {
    32  	// avg point timestamp is set to last point time
    33  	if s.Time.After(twa.pointTime) {
    34  		twa.pointTime = s.Time
    35  	}
    36  
    37  	// update statistical values.
    38  	twa.total += s.Value
    39  	twa.count++
    40  
    41  	// if time has expired, callback() with avg point
    42  	if time.Since(twa.start) >= twa.windowLen {
    43  		avgPoint := Point{
    44  			Type:  twa.pointType,
    45  			Time:  twa.pointTime,
    46  			Value: twa.total / float64(twa.count),
    47  		}
    48  
    49  		twa.callBack(avgPoint)
    50  
    51  		// reset statistical values and timestamp
    52  		twa.total = 0
    53  		twa.count = 0
    54  		twa.start = time.Now()
    55  	}
    56  }