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