blob: 24683a2079daa1c3767099f129a3ae604fe14fcb [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) :
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010012 ioc(ioc),
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020013 triggerId(triggerIdIn), actions(std::move(actionsIn)),
14 dwellTime(dwellTimeIn), direction(directionIn),
15 thresholdValue(thresholdValueIn), type(typeIn), clock(std::move(clockIn))
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010016{
Szymon Dompke94f71c52021-12-10 07:16:33 +010017 for (const auto& sensor : sensorsIn)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010018 {
Szymon Dompke94f71c52021-12-10 07:16:33 +010019 sensorDetails.emplace(sensor, makeDetails(sensor->getName()));
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010020 }
21}
22
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010023void NumericThreshold::initialize()
24{
Krzysztof Grobelny41fa80d2022-06-09 13:27:16 +020025 ThresholdOperations::initialize(this);
Szymon Dompke94f71c52021-12-10 07:16:33 +010026}
27
28void NumericThreshold::updateSensors(Sensors newSensors)
29{
Krzysztof Grobelny41fa80d2022-06-09 13:27:16 +020030 ThresholdOperations::updateSensors(this, std::move(newSensors));
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010031}
32
33NumericThreshold::ThresholdDetail&
Szymon Dompke94f71c52021-12-10 07:16:33 +010034 NumericThreshold::getDetails(const interfaces::Sensor& sensor)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010035{
Krzysztof Grobelny41fa80d2022-06-09 13:27:16 +020036 return ThresholdOperations::getDetails(this, sensor);
Szymon Dompke94f71c52021-12-10 07:16:33 +010037}
38
39std::shared_ptr<NumericThreshold::ThresholdDetail>
40 NumericThreshold::makeDetails(const std::string& sensorName)
41{
42 return std::make_shared<ThresholdDetail>(sensorName, thresholdValue, false,
43 ioc);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010044}
45
46void NumericThreshold::sensorUpdated(interfaces::Sensor& sensor,
Krzysztof Grobelny51f0fd52021-12-28 16:32:08 +010047 Milliseconds timestamp, double value)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010048{
Szymon Dompke94f71c52021-12-10 07:16:33 +010049 auto& details = getDetails(sensor);
50 auto& [sensorName, prevValue, dwell, timer] = details;
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010051 bool decreasing = thresholdValue < prevValue && thresholdValue > value;
52 bool increasing = thresholdValue > prevValue && thresholdValue < value;
53
54 if (dwell && (increasing || decreasing))
55 {
56 timer.cancel();
57 dwell = false;
58 }
59 if ((direction == numeric::Direction::decreasing && decreasing) ||
60 (direction == numeric::Direction::increasing && increasing) ||
61 (direction == numeric::Direction::either && (increasing || decreasing)))
62 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020063 startTimer(details, value);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010064 }
65
66 prevValue = value;
67}
68
Szymon Dompke94f71c52021-12-10 07:16:33 +010069void NumericThreshold::startTimer(NumericThreshold::ThresholdDetail& details,
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020070 double value)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010071{
Szymon Dompke94f71c52021-12-10 07:16:33 +010072 const auto& sensorName = details.sensorName;
73 auto& dwell = details.dwell;
74 auto& timer = details.timer;
75
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +000076 if (dwellTime == Milliseconds::zero())
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010077 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020078 commit(sensorName, value);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010079 }
80 else
81 {
82 dwell = true;
83 timer.expires_after(dwellTime);
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020084 timer.async_wait([this, &sensorName, &dwell,
Szymon Dompke94f71c52021-12-10 07:16:33 +010085 value](const boost::system::error_code ec) {
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010086 if (ec)
87 {
88 phosphor::logging::log<phosphor::logging::level::DEBUG>(
89 "Timer has been canceled");
90 return;
91 }
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020092 commit(sensorName, value);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010093 dwell = false;
94 });
95 }
96}
97
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +020098void NumericThreshold::commit(const std::string& sensorName, double value)
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010099{
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200100 Milliseconds timestamp = clock->systemTimestamp();
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100101 for (const auto& action : actions)
102 {
Szymon Dompkeb7b7e1b2022-05-19 10:15:48 +0200103 action->commit(triggerId, std::nullopt, sensorName, timestamp, value);
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100104 }
105}
Szymon Dompke94f71c52021-12-10 07:16:33 +0100106
107LabeledThresholdParam NumericThreshold::getThresholdParam() const
108{
109 return numeric::LabeledThresholdParam(type, dwellTime.count(), direction,
110 thresholdValue);
111}