1 #pragma once 2 3 #include "Utils.hpp" 4 5 #include <boost/asio/io_context.hpp> 6 #include <boost/asio/steady_timer.hpp> 7 #include <nlohmann/json.hpp> 8 9 #include <list> 10 #include <memory> 11 #include <string> 12 #include <utility> 13 #include <vector> 14 15 struct Sensor; 16 namespace thresholds 17 { 18 enum class Level 19 { 20 WARNING, 21 CRITICAL, 22 PERFORMANCELOSS, 23 SOFTSHUTDOWN, 24 HARDSHUTDOWN, 25 ERROR 26 }; 27 enum class Direction 28 { 29 HIGH, 30 LOW, 31 ERROR 32 }; 33 struct Threshold 34 { 35 Threshold( 36 const Level& lev, const Direction& dir, const double& val, 37 const double hysteresis = std::numeric_limits<double>::quiet_NaN(), 38 bool write = true) : 39 level(lev), 40 direction(dir), value(val), hysteresis(hysteresis), writeable(write) 41 {} 42 Level level; 43 Direction direction; 44 double value; 45 double hysteresis; 46 bool writeable; 47 48 bool operator==(const Threshold& rhs) const 49 { 50 return (level == rhs.level && direction == rhs.direction && 51 value == rhs.value); 52 } 53 }; 54 55 void assertThresholds(Sensor* sensor, double assertValue, 56 thresholds::Level level, thresholds::Direction direction, 57 bool assert); 58 59 struct TimerUsed 60 { 61 bool used; 62 Level level; 63 Direction direction; 64 bool assert; 65 }; 66 67 using TimerPair = std::pair<struct TimerUsed, boost::asio::steady_timer>; 68 69 struct ThresholdTimer 70 { 71 explicit ThresholdTimer(boost::asio::io_context& ioService) : io(ioService) 72 {} 73 74 bool hasActiveTimer(const Threshold& threshold, bool assert) 75 { 76 for (TimerPair& timer : timers) 77 { 78 if (timer.first.used) 79 { 80 if ((timer.first.level == threshold.level) && 81 (timer.first.direction == threshold.direction) && 82 (timer.first.assert == assert)) 83 { 84 return true; 85 } 86 } 87 } 88 return false; 89 } 90 91 void stopTimer(const Threshold& threshold, bool assert) 92 { 93 struct TimerUsed timerUsed = {}; 94 for (TimerPair& timer : timers) 95 { 96 timerUsed = timer.first; 97 if (timerUsed.used) 98 { 99 if ((timerUsed.level == threshold.level) && 100 (timerUsed.direction == threshold.direction) && 101 (timerUsed.assert == assert)) 102 { 103 timer.second.cancel(); 104 } 105 } 106 } 107 } 108 109 void startTimer(const std::weak_ptr<Sensor>& weakSensor, 110 const Threshold& threshold, bool assert, 111 double assertValue); 112 113 boost::asio::io_context& io; 114 std::list<TimerPair> timers; 115 }; 116 117 bool parseThresholdsFromConfig( 118 const SensorData& sensorData, 119 std::vector<thresholds::Threshold>& thresholdVector, 120 const std::string* matchLabel = nullptr, const int* sensorIndex = nullptr); 121 122 bool parseThresholdsFromAttr( 123 std::vector<thresholds::Threshold>& thresholdVector, 124 const std::string& inputPath, const double& scaleFactor, 125 const double& offset = 0); 126 127 struct ThresholdDefinition 128 { 129 Level level; 130 uint8_t sevOrder; 131 const char* levelName; 132 }; 133 134 constexpr static std::array<thresholds::ThresholdDefinition, 5> thresProp = { 135 {{Level::WARNING, 0, "Warning"}, 136 {Level::CRITICAL, 1, "Critical"}, 137 {Level::PERFORMANCELOSS, 2, "PerformanceLoss"}, 138 {Level::SOFTSHUTDOWN, 3, "SoftShutdown"}, 139 {Level::HARDSHUTDOWN, 4, "HardShutdown"}}}; 140 141 std::string getInterface(Level level); 142 143 void persistThreshold(const std::string& path, const std::string& baseInterface, 144 const thresholds::Threshold& threshold, 145 std::shared_ptr<sdbusplus::asio::connection>& conn, 146 size_t thresholdCount, const std::string& label); 147 148 void updateThresholds(Sensor* sensor); 149 // returns false if a critical threshold has been crossed, true otherwise 150 bool checkThresholds(Sensor* sensor); 151 void checkThresholdsPowerDelay(const std::weak_ptr<Sensor>& weakSensor, 152 ThresholdTimer& thresholdTimer); 153 154 } // namespace thresholds 155