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