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