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