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) 45 {} 46 47 void NumericThreshold::sensorUpdated(interfaces::Sensor& sensor, 48 Milliseconds timestamp, double value) 49 { 50 auto& details = getDetails(sensor); 51 auto& [sensorName, prevValue, dwell, timer] = details; 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(details, timestamp, value); 65 } 66 67 prevValue = value; 68 } 69 70 void NumericThreshold::startTimer(NumericThreshold::ThresholdDetail& details, 71 Milliseconds timestamp, double value) 72 { 73 const auto& sensorName = details.sensorName; 74 auto& dwell = details.dwell; 75 auto& timer = details.timer; 76 77 if (dwellTime == Milliseconds::zero()) 78 { 79 commit(sensorName, timestamp, value); 80 } 81 else 82 { 83 dwell = true; 84 timer.expires_after(dwellTime); 85 timer.async_wait([this, &sensorName, &dwell, timestamp, 86 value](const boost::system::error_code ec) { 87 if (ec) 88 { 89 phosphor::logging::log<phosphor::logging::level::DEBUG>( 90 "Timer has been canceled"); 91 return; 92 } 93 commit(sensorName, timestamp, value); 94 dwell = false; 95 }); 96 } 97 } 98 99 void NumericThreshold::commit(const std::string& sensorName, 100 Milliseconds timestamp, double value) 101 { 102 for (const auto& action : actions) 103 { 104 action->commit(sensorName, timestamp, value); 105 } 106 } 107 108 LabeledThresholdParam NumericThreshold::getThresholdParam() const 109 { 110 return numeric::LabeledThresholdParam(type, dwellTime.count(), direction, 111 thresholdValue); 112 } 113