blob: 25cc46f0d13257099adbc1d07dbacb6c8461d310 [file] [log] [blame]
Szymon Dompkef763c9e2021-03-12 09:19:22 +01001#include "discrete_threshold.hpp"
2
3#include <phosphor-logging/log.hpp>
4
5DiscreteThreshold::DiscreteThreshold(
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +00006 boost::asio::io_context& ioc, Sensors sensorsIn,
Szymon Dompkef763c9e2021-03-12 09:19:22 +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, double thresholdValueIn, std::string name) :
Szymon Dompkef763c9e2021-03-12 09:19:22 +010010 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
21void DiscreteThreshold::initialize()
22{
23 for (auto& sensor : sensors)
24 {
25 sensor->registerForUpdates(weak_from_this());
26 }
27}
28
29DiscreteThreshold::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
39void DiscreteThreshold::sensorUpdated(interfaces::Sensor& sensor,
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010040 Milliseconds timestamp)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010041{}
42
43void DiscreteThreshold::sensorUpdated(interfaces::Sensor& sensor,
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010044 Milliseconds timestamp, double value)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010045{
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
62void DiscreteThreshold::startTimer(interfaces::Sensor& sensor,
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010063 Milliseconds timestamp, double value)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010064{
65 auto& [sensorName, dwell, timer] = getDetails(sensor);
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000066 if (dwellTime == Milliseconds::zero())
Szymon Dompkef763c9e2021-03-12 09:19:22 +010067 {
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
89void DiscreteThreshold::commit(const std::string& sensorName,
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010090 Milliseconds timestamp, double value)
Szymon Dompkef763c9e2021-03-12 09:19:22 +010091{
92 for (const auto& action : actions)
93 {
94 action->commit(sensorName, timestamp, value);
95 }
96}