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