xref: /openbmc/phosphor-hwmon/average.cpp (revision 02e598ab445833e0ce615f88ac0aed7288a100e0)
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>
24      Average::calcAverage(int64_t preAverage, int64_t preInterval,
25                           int64_t curAverage, int64_t curInterval)
26  {
27      int64_t value = 0;
28      // Estimate that the interval will overflow about 292471
29      // years after it starts counting, so consider it won't
30      // overflow
31      int64_t delta = curInterval - preInterval;
32  
33      assert(delta >= 0);
34      // 0 means the delta interval is too short, the value of
35      // power*_average_interval is not changed yet
36      if (delta == 0)
37      {
38          return {};
39      }
40      // Change formula (a2*i2-a1*i1)/(i2-i1) to be the
41      // following formula, to avoid multiplication overflow.
42      // (a2*i2-a1*i1)/(i2-i1) =
43      // (a2*(i1+delta)-a1*i1)/delta =
44      // (a2-a1)(i1/delta)+a2
45      value =
46          (curAverage - preAverage) * (static_cast<double>(preInterval) / delta) +
47          curAverage;
48  
49      return value;
50  }
51