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