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