xref: /openbmc/telemetry/src/discrete_threshold.cpp (revision aa572361124d4797b25674297bbc4cc2682030fa)
1 #include "discrete_threshold.hpp"
2 
3 #include "utils/conversion_trigger.hpp"
4 
5 #include <phosphor-logging/log.hpp>
6 
7 DiscreteThreshold::DiscreteThreshold(
8     boost::asio::io_context& ioc, Sensors sensorsIn,
9     std::vector<std::unique_ptr<interfaces::TriggerAction>> actionsIn,
10     Milliseconds dwellTimeIn, const std::string& thresholdValueIn,
11     const std::string& nameIn, const discrete::Severity severityIn) :
12     ioc(ioc),
13     actions(std::move(actionsIn)), dwellTime(dwellTimeIn),
14     thresholdValue(thresholdValueIn),
15     numericThresholdValue(utils::stodStrict(thresholdValue)), name(nameIn),
16     severity(severityIn)
17 {
18     for (const auto& sensor : sensorsIn)
19     {
20         sensorDetails.emplace(sensor, makeDetails(sensor->getName()));
21     }
22 }
23 
24 void DiscreteThreshold::initialize()
25 {
26     ThresholdOperations().initialize(this);
27 }
28 
29 void DiscreteThreshold::updateSensors(Sensors newSensors)
30 {
31     ThresholdOperations().updateSensors(this, std::move(newSensors));
32 }
33 
34 DiscreteThreshold::ThresholdDetail&
35     DiscreteThreshold::getDetails(const interfaces::Sensor& sensor)
36 {
37     return ThresholdOperations().getDetails(this, sensor);
38 }
39 
40 std::shared_ptr<DiscreteThreshold::ThresholdDetail>
41     DiscreteThreshold::makeDetails(const std::string& sensorName)
42 {
43     return std::make_shared<ThresholdDetail>(sensorName, false, ioc);
44 }
45 
46 void DiscreteThreshold::sensorUpdated(interfaces::Sensor& sensor,
47                                       Milliseconds timestamp, double value)
48 {
49     auto& details = getDetails(sensor);
50     auto& [sensorName, dwell, timer] = details;
51 
52     if (dwell && value != numericThresholdValue)
53     {
54         timer.cancel();
55         dwell = false;
56     }
57     else if (value == numericThresholdValue)
58     {
59         startTimer(details, timestamp, value);
60     }
61 }
62 
63 void DiscreteThreshold::startTimer(DiscreteThreshold::ThresholdDetail& details,
64                                    Milliseconds timestamp, double value)
65 {
66     const auto& sensorName = details.sensorName;
67     auto& dwell = details.dwell;
68     auto& timer = details.timer;
69 
70     if (dwellTime == Milliseconds::zero())
71     {
72         commit(sensorName, timestamp, value);
73     }
74     else
75     {
76         dwell = true;
77         timer.expires_after(dwellTime);
78         timer.async_wait([this, &sensorName, &dwell, timestamp,
79                           value](const boost::system::error_code ec) {
80             if (ec)
81             {
82                 phosphor::logging::log<phosphor::logging::level::DEBUG>(
83                     "Timer has been canceled");
84                 return;
85             }
86             commit(sensorName, timestamp, value);
87             dwell = false;
88         });
89     }
90 }
91 
92 void DiscreteThreshold::commit(const std::string& sensorName,
93                                Milliseconds timestamp, double value)
94 {
95     for (const auto& action : actions)
96     {
97         action->commit(sensorName, timestamp, value);
98     }
99 }
100 
101 LabeledThresholdParam DiscreteThreshold::getThresholdParam() const
102 {
103     return discrete::LabeledThresholdParam(name, severity, dwellTime.count(),
104                                            thresholdValue);
105 }
106