blob: 2a02a92fc8c575eef117638a5e5dc38d575fd9ec [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(
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +02006 boost::asio::io_context& ioc, const std::string& triggerIdIn,
7 Sensors sensorsIn,
Wludzik, Jozef1477fe62021-01-02 11:56:10 +01008 std::vector<std::unique_ptr<interfaces::TriggerAction>> actionsIn,
Szymon Dompke94f71c52021-12-10 07:16:33 +01009 Milliseconds dwellTimeIn, numeric::Direction directionIn,
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020010 double thresholdValueIn, numeric::Type typeIn,
11 std::unique_ptr<interfaces::Clock> clockIn) :
Patrick Williamsf535cad2024-08-16 15:21:20 -040012 ioc(ioc), triggerId(triggerIdIn), actions(std::move(actionsIn)),
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020013 dwellTime(dwellTimeIn), direction(directionIn),
14 thresholdValue(thresholdValueIn), type(typeIn), clock(std::move(clockIn))
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010015{
Szymon Dompke94f71c52021-12-10 07:16:33 +010016 for (const auto& sensor : sensorsIn)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010017 {
Szymon Dompke94f71c52021-12-10 07:16:33 +010018 sensorDetails.emplace(sensor, makeDetails(sensor->getName()));
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010019 }
20}
21
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010022void NumericThreshold::initialize()
23{
Krzysztof Grobelny41fa80d2022-06-09 13:27:16 +020024 ThresholdOperations::initialize(this);
Szymon Dompke94f71c52021-12-10 07:16:33 +010025}
26
27void NumericThreshold::updateSensors(Sensors newSensors)
28{
Krzysztof Grobelny41fa80d2022-06-09 13:27:16 +020029 ThresholdOperations::updateSensors(this, std::move(newSensors));
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010030}
31
32NumericThreshold::ThresholdDetail&
Szymon Dompke94f71c52021-12-10 07:16:33 +010033 NumericThreshold::getDetails(const interfaces::Sensor& sensor)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010034{
Krzysztof Grobelny41fa80d2022-06-09 13:27:16 +020035 return ThresholdOperations::getDetails(this, sensor);
Szymon Dompke94f71c52021-12-10 07:16:33 +010036}
37
38std::shared_ptr<NumericThreshold::ThresholdDetail>
39 NumericThreshold::makeDetails(const std::string& sensorName)
40{
Szymon Dompke162b9762022-06-07 12:45:48 +020041 return std::make_shared<ThresholdDetail>(sensorName, ioc);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010042}
43
44void NumericThreshold::sensorUpdated(interfaces::Sensor& sensor,
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010045 Milliseconds timestamp, double value)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010046{
Szymon Dompke94f71c52021-12-10 07:16:33 +010047 auto& details = getDetails(sensor);
Szymon Dompke162b9762022-06-07 12:45:48 +020048 auto& prevValue = details.prevValue;
49 auto& prevDirection = details.prevDirection;
50 auto& dwell = details.dwell;
51 auto& timer = details.timer;
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010052
Szymon Dompke162b9762022-06-07 12:45:48 +020053 if (!prevValue)
54 {
55 prevValue = value;
56 return;
57 }
58
Patrick Williams3a1c2972023-05-10 07:51:04 -050059 bool crossedDecreasing = thresholdValue < prevValue &&
60 thresholdValue > value;
61 bool crossedIncreasing = thresholdValue > prevValue &&
62 thresholdValue < value;
Szymon Dompke162b9762022-06-07 12:45:48 +020063
64 if (!crossedDecreasing && !crossedIncreasing && thresholdValue == prevValue)
65 {
66 crossedDecreasing = prevDirection == numeric::Direction::decreasing &&
67 thresholdValue > value;
68 crossedIncreasing = prevDirection == numeric::Direction::increasing &&
69 thresholdValue < value;
70 }
71
72 if (dwell && (crossedIncreasing || crossedDecreasing))
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010073 {
74 timer.cancel();
75 dwell = false;
76 }
Szymon Dompke162b9762022-06-07 12:45:48 +020077 if ((direction == numeric::Direction::decreasing && crossedDecreasing) ||
78 (direction == numeric::Direction::increasing && crossedIncreasing) ||
79 (direction == numeric::Direction::either &&
80 (crossedIncreasing || crossedDecreasing)))
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010081 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020082 startTimer(details, value);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010083 }
84
Szymon Dompke162b9762022-06-07 12:45:48 +020085 prevDirection = value > prevValue ? numeric::Direction::increasing
86 : value < prevValue ? numeric::Direction::decreasing
87 : numeric::Direction::either;
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010088 prevValue = value;
89}
90
Szymon Dompke94f71c52021-12-10 07:16:33 +010091void NumericThreshold::startTimer(NumericThreshold::ThresholdDetail& details,
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020092 double value)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010093{
Szymon Dompke162b9762022-06-07 12:45:48 +020094 auto& sensorName = details.getSensorName();
Szymon Dompke94f71c52021-12-10 07:16:33 +010095 auto& dwell = details.dwell;
96 auto& timer = details.timer;
97
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000098 if (dwellTime == Milliseconds::zero())
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010099 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200100 commit(sensorName, value);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100101 }
102 else
103 {
104 dwell = true;
105 timer.expires_after(dwellTime);
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200106 timer.async_wait([this, &sensorName, &dwell,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100107 value](const boost::system::error_code ec) {
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100108 if (ec)
109 {
110 phosphor::logging::log<phosphor::logging::level::DEBUG>(
111 "Timer has been canceled");
112 return;
113 }
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200114 commit(sensorName, value);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100115 dwell = false;
116 });
117 }
118}
119
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200120void NumericThreshold::commit(const std::string& sensorName, double value)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100121{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200122 Milliseconds timestamp = clock->systemTimestamp();
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100123 for (const auto& action : actions)
124 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200125 action->commit(triggerId, std::nullopt, sensorName, timestamp, value);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100126 }
127}
Szymon Dompke94f71c52021-12-10 07:16:33 +0100128
129LabeledThresholdParam NumericThreshold::getThresholdParam() const
130{
131 return numeric::LabeledThresholdParam(type, dwellTime.count(), direction,
132 thresholdValue);
133}