xref: /openbmc/phosphor-hwmon/average.cpp (revision e8771fd4)
1 #include "average.hpp"
2 
3 #include <cassert>
4 
5 std::optional<Average::averageValue>
6     Average::getAverageValue(const Average::averageKey& sensorKey) const
7 {
8     const auto it = _previousAverageMap.find(sensorKey);
9     if (it == _previousAverageMap.end())
10     {
11         return {};
12     }
13 
14     return std::optional(it->second);
15 }
16 
17 void Average::setAverageValue(const Average::averageKey& sensorKey,
18                               const Average::averageValue& sensorValue)
19 {
20     _previousAverageMap[sensorKey] = sensorValue;
21 }
22 
23 std::optional<int64_t> Average::calcAverage(int64_t preAverage,
24                                             int64_t preInterval,
25                                             int64_t curAverage,
26                                             int64_t curInterval)
27 {
28     int64_t value = 0;
29     // Estimate that the interval will overflow about 292471
30     // years after it starts counting, so consider it won't
31     // overflow
32     int64_t delta = curInterval - preInterval;
33 
34     assert(delta >= 0);
35     // 0 means the delta interval is too short, the value of
36     // power*_average_interval is not changed yet
37     if (delta == 0)
38     {
39         return {};
40     }
41     // Change formula (a2*i2-a1*i1)/(i2-i1) to be the
42     // following formula, to avoid multiplication overflow.
43     // (a2*i2-a1*i1)/(i2-i1) =
44     // (a2*(i1+delta)-a1*i1)/delta =
45     // (a2-a1)(i1/delta)+a2
46     value = (curAverage - preAverage) *
47                 (static_cast<double>(preInterval) / delta) +
48             curAverage;
49 
50     return value;
51 }
52