blob: ebb78262272ca39a689f20ad589688d2fb6b0771 [file] [log] [blame]
Wludzik, Jozef1477fe62021-01-02 11:56:10 +01001#include "numeric_threshold.hpp"
2
3#include <phosphor-logging/log.hpp>
4
5NumericThreshold::NumericThreshold(
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +00006 boost::asio::io_context& ioc, Sensors sensorsIn,
Wludzik, Jozef1477fe62021-01-02 11:56:10 +01007 std::vector<std::string> sensorNames,
8 std::vector<std::unique_ptr<interfaces::TriggerAction>> actionsIn,
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +00009 Milliseconds dwellTimeIn, numeric::Direction direction,
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010010 double thresholdValueIn) :
11 ioc(ioc),
12 sensors(std::move(sensorsIn)), actions(std::move(actionsIn)),
13 dwellTime(dwellTimeIn), direction(direction),
14 thresholdValue(thresholdValueIn)
15{
16 details.reserve(sensors.size());
17 for (size_t i = 0; i < sensors.size(); i++)
18 {
19 details.emplace_back(sensorNames[i], thresholdValue, false, ioc);
20 }
21}
22
23NumericThreshold::~NumericThreshold()
24{}
25
26void NumericThreshold::initialize()
27{
28 for (auto& sensor : sensors)
29 {
30 sensor->registerForUpdates(weak_from_this());
31 }
32}
33
34NumericThreshold::ThresholdDetail&
35 NumericThreshold::getDetails(interfaces::Sensor& sensor)
36{
37 auto it =
38 std::find_if(sensors.begin(), sensors.end(),
39 [&sensor](const auto& x) { return &sensor == x.get(); });
40 auto index = std::distance(sensors.begin(), it);
41 return details.at(index);
42}
43
44void NumericThreshold::sensorUpdated(interfaces::Sensor& sensor,
45 uint64_t timestamp)
46{}
47
48void NumericThreshold::sensorUpdated(interfaces::Sensor& sensor,
49 uint64_t timestamp, double value)
50{
51 auto& [sensorName, prevValue, dwell, timer] = getDetails(sensor);
52 bool decreasing = thresholdValue < prevValue && thresholdValue > value;
53 bool increasing = thresholdValue > prevValue && thresholdValue < value;
54
55 if (dwell && (increasing || decreasing))
56 {
57 timer.cancel();
58 dwell = false;
59 }
60 if ((direction == numeric::Direction::decreasing && decreasing) ||
61 (direction == numeric::Direction::increasing && increasing) ||
62 (direction == numeric::Direction::either && (increasing || decreasing)))
63 {
64 startTimer(sensorName, timestamp, value, dwell, timer);
65 }
66
67 prevValue = value;
68}
69
70void NumericThreshold::startTimer(const std::string& sensorName,
71 uint64_t timestamp, double value, bool& dwell,
72 boost::asio::steady_timer& timer)
73{
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000074 if (dwellTime == Milliseconds::zero())
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010075 {
76 commit(sensorName, timestamp, value);
77 }
78 else
79 {
80 dwell = true;
81 timer.expires_after(dwellTime);
82 timer.async_wait([this, sensorName, timestamp, value,
83 &dwell](const boost::system::error_code ec) {
84 if (ec)
85 {
86 phosphor::logging::log<phosphor::logging::level::DEBUG>(
87 "Timer has been canceled");
88 return;
89 }
90 commit(sensorName, timestamp, value);
91 dwell = false;
92 });
93 }
94}
95
96void NumericThreshold::commit(const std::string& sensorName, uint64_t timestamp,
97 double value)
98{
99 for (const auto& action : actions)
100 {
101 action->commit(sensorName, timestamp, value);
102 }
103}