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::unique_ptr<interfaces::TriggerAction>> actionsIn, 8 Milliseconds dwellTimeIn, numeric::Direction directionIn, 9 double thresholdValueIn, numeric::Type typeIn) : 10 ioc(ioc), 11 actions(std::move(actionsIn)), dwellTime(dwellTimeIn), 12 direction(directionIn), thresholdValue(thresholdValueIn), type(typeIn) 13 { 14 for (const auto& sensor : sensorsIn) 15 { 16 sensorDetails.emplace(sensor, makeDetails(sensor->getName())); 17 } 18 } 19 20 void NumericThreshold::initialize() 21 { 22 ThresholdOperations().initialize(this); 23 } 24 25 void NumericThreshold::updateSensors(Sensors newSensors) 26 { 27 ThresholdOperations().updateSensors(this, std::move(newSensors)); 28 } 29 30 NumericThreshold::ThresholdDetail& 31 NumericThreshold::getDetails(const interfaces::Sensor& sensor) 32 { 33 return ThresholdOperations().getDetails(this, sensor); 34 } 35 36 std::shared_ptr<NumericThreshold::ThresholdDetail> 37 NumericThreshold::makeDetails(const std::string& sensorName) 38 { 39 return std::make_shared<ThresholdDetail>(sensorName, thresholdValue, false, 40 ioc); 41 } 42 43 void NumericThreshold::sensorUpdated(interfaces::Sensor& sensor, 44 Milliseconds timestamp, double value) 45 { 46 auto& details = getDetails(sensor); 47 auto& [sensorName, prevValue, dwell, timer] = details; 48 bool decreasing = thresholdValue < prevValue && thresholdValue > value; 49 bool increasing = thresholdValue > prevValue && thresholdValue < value; 50 51 if (dwell && (increasing || decreasing)) 52 { 53 timer.cancel(); 54 dwell = false; 55 } 56 if ((direction == numeric::Direction::decreasing && decreasing) || 57 (direction == numeric::Direction::increasing && increasing) || 58 (direction == numeric::Direction::either && (increasing || decreasing))) 59 { 60 startTimer(details, timestamp, value); 61 } 62 63 prevValue = value; 64 } 65 66 void NumericThreshold::startTimer(NumericThreshold::ThresholdDetail& details, 67 Milliseconds timestamp, double value) 68 { 69 const auto& sensorName = details.sensorName; 70 auto& dwell = details.dwell; 71 auto& timer = details.timer; 72 73 if (dwellTime == Milliseconds::zero()) 74 { 75 commit(sensorName, timestamp, value); 76 } 77 else 78 { 79 dwell = true; 80 timer.expires_after(dwellTime); 81 timer.async_wait([this, &sensorName, &dwell, timestamp, 82 value](const boost::system::error_code ec) { 83 if (ec) 84 { 85 phosphor::logging::log<phosphor::logging::level::DEBUG>( 86 "Timer has been canceled"); 87 return; 88 } 89 commit(sensorName, timestamp, value); 90 dwell = false; 91 }); 92 } 93 } 94 95 void NumericThreshold::commit(const std::string& sensorName, 96 Milliseconds timestamp, double value) 97 { 98 for (const auto& action : actions) 99 { 100 action->commit(sensorName, timestamp, value); 101 } 102 } 103 104 LabeledThresholdParam NumericThreshold::getThresholdParam() const 105 { 106 return numeric::LabeledThresholdParam(type, dwellTime.count(), direction, 107 thresholdValue); 108 } 109