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 72 explicit ThresholdTimer(boost::asio::io_context& ioService) : io(ioService) 73 {} 74 75 bool hasActiveTimer(const Threshold& threshold, bool assert) 76 { 77 for (TimerPair& timer : timers) 78 { 79 if (timer.first.used) 80 { 81 if ((timer.first.level == threshold.level) && 82 (timer.first.direction == threshold.direction) && 83 (timer.first.assert == assert)) 84 { 85 return true; 86 } 87 } 88 } 89 return false; 90 } 91 92 void stopTimer(const Threshold& threshold, bool assert) 93 { 94 struct TimerUsed timerUsed = {}; 95 for (TimerPair& timer : timers) 96 { 97 timerUsed = timer.first; 98 if (timerUsed.used) 99 { 100 if ((timerUsed.level == threshold.level) && 101 (timerUsed.direction == threshold.direction) && 102 (timerUsed.assert == assert)) 103 { 104 timer.second.cancel(); 105 } 106 } 107 } 108 } 109 110 void startTimer(const std::weak_ptr<Sensor>& weakSensor, 111 const Threshold& threshold, bool assert, 112 double assertValue); 113 114 boost::asio::io_context& io; 115 std::list<TimerPair> timers; 116 }; 117 118 bool parseThresholdsFromConfig( 119 const SensorData& sensorData, 120 std::vector<thresholds::Threshold>& thresholdVector, 121 const std::string* matchLabel = nullptr, const int* sensorIndex = nullptr); 122 123 bool parseThresholdsFromAttr( 124 std::vector<thresholds::Threshold>& thresholdVector, 125 const std::string& inputPath, const double& scaleFactor, 126 const double& offset = 0); 127 128 struct ThresholdDefinition 129 { 130 Level level; 131 uint8_t sevOrder; 132 const char* levelName; 133 }; 134 135 constexpr static std::array<thresholds::ThresholdDefinition, 5> thresProp = { 136 {{Level::WARNING, 0, "Warning"}, 137 {Level::CRITICAL, 1, "Critical"}, 138 {Level::PERFORMANCELOSS, 2, "PerformanceLoss"}, 139 {Level::SOFTSHUTDOWN, 3, "SoftShutdown"}, 140 {Level::HARDSHUTDOWN, 4, "HardShutdown"}}}; 141 142 std::string getInterface(Level level); 143 144 void persistThreshold(const std::string& path, const std::string& baseInterface, 145 const thresholds::Threshold& threshold, 146 std::shared_ptr<sdbusplus::asio::connection>& conn, 147 size_t thresholdCount, const std::string& label); 148 149 void updateThresholds(Sensor* sensor); 150 // returns false if a critical threshold has been crossed, true otherwise 151 bool checkThresholds(Sensor* sensor); 152 void checkThresholdsPowerDelay(const std::weak_ptr<Sensor>& weakSensor, 153 ThresholdTimer& thresholdTimer); 154 155 } // namespace thresholds 156