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