xref: /openbmc/telemetry/src/discrete_threshold.cpp (revision f763c9e3bbe0f86a4a41e7bb0dc70bffde0af9b2)
1 #include "discrete_threshold.hpp"
2 
3 #include <phosphor-logging/log.hpp>
4 
5 DiscreteThreshold::DiscreteThreshold(
6     boost::asio::io_context& ioc,
7     std::vector<std::shared_ptr<interfaces::Sensor>> sensorsIn,
8     std::vector<std::string> sensorNames,
9     std::vector<std::unique_ptr<interfaces::TriggerAction>> actionsIn,
10     std::chrono::milliseconds dwellTimeIn, double thresholdValueIn,
11     std::string name) :
12     ioc(ioc),
13     sensors(std::move(sensorsIn)), actions(std::move(actionsIn)),
14     dwellTime(dwellTimeIn), thresholdValue(thresholdValueIn), name(name)
15 {
16     details.reserve(sensors.size());
17     for (size_t i = 0; i < sensors.size(); i++)
18     {
19         details.emplace_back(sensorNames[i], false, ioc);
20     }
21 }
22 
23 void DiscreteThreshold::initialize()
24 {
25     for (auto& sensor : sensors)
26     {
27         sensor->registerForUpdates(weak_from_this());
28     }
29 }
30 
31 DiscreteThreshold::ThresholdDetail&
32     DiscreteThreshold::getDetails(interfaces::Sensor& sensor)
33 {
34     auto it =
35         std::find_if(sensors.begin(), sensors.end(),
36                      [&sensor](const auto& x) { return &sensor == x.get(); });
37     auto index = std::distance(sensors.begin(), it);
38     return details.at(index);
39 }
40 
41 void DiscreteThreshold::sensorUpdated(interfaces::Sensor& sensor,
42                                       uint64_t timestamp)
43 {}
44 
45 void DiscreteThreshold::sensorUpdated(interfaces::Sensor& sensor,
46                                       uint64_t timestamp, double value)
47 {
48     auto& [sensorName, dwell, timer] = getDetails(sensor);
49 
50     if (thresholdValue)
51     {
52         if (dwell && value != thresholdValue)
53         {
54             timer.cancel();
55             dwell = false;
56         }
57         else if (value == thresholdValue)
58         {
59             startTimer(sensor, timestamp, value);
60         }
61     }
62 }
63 
64 void DiscreteThreshold::startTimer(interfaces::Sensor& sensor,
65                                    uint64_t timestamp, double value)
66 {
67     auto& [sensorName, dwell, timer] = getDetails(sensor);
68     if (dwellTime == std::chrono::milliseconds::zero())
69     {
70         commit(sensorName, timestamp, value);
71     }
72     else
73     {
74         dwell = true;
75         timer.expires_after(dwellTime);
76         timer.async_wait([this, &sensor, timestamp,
77                           value](const boost::system::error_code ec) {
78             if (ec)
79             {
80                 phosphor::logging::log<phosphor::logging::level::DEBUG>(
81                     "Timer has been canceled");
82                 return;
83             }
84             auto& [sensorName, dwell, timer] = getDetails(sensor);
85             commit(sensorName, timestamp, value);
86             dwell = false;
87         });
88     }
89 }
90 
91 void DiscreteThreshold::commit(const std::string& sensorName,
92                                uint64_t timestamp, double value)
93 {
94     for (const auto& action : actions)
95     {
96         action->commit(sensorName, timestamp, value);
97     }
98 }
99 
100 const char* DiscreteThreshold::getName() const
101 {
102     return name.c_str();
103 }
104