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