1 #pragma once 2 3 #include "env.hpp" 4 5 /** @class Thresholds 6 * @brief Threshold type traits. 7 * 8 * @tparam T - The threshold type. 9 */ 10 template <typename T> 11 struct Thresholds 12 { 13 static void fail() 14 { 15 static_assert(sizeof(Thresholds) == -1, "Unsupported Threshold type"); 16 } 17 }; 18 19 /**@brief Thresholds specialization for warning thresholds. */ 20 template <> 21 struct Thresholds<WarningObject> 22 { 23 static constexpr InterfaceType type = InterfaceType::WARN; 24 static constexpr const char* envLo = "WARNLO"; 25 static constexpr const char* envHi = "WARNHI"; 26 static int64_t (WarningObject::*const setLo)(int64_t); 27 static int64_t (WarningObject::*const setHi)(int64_t); 28 static int64_t (WarningObject::*const getLo)() const; 29 static int64_t (WarningObject::*const getHi)() const; 30 static bool (WarningObject::*const alarmLo)(bool); 31 static bool (WarningObject::*const alarmHi)(bool); 32 }; 33 34 /**@brief Thresholds specialization for critical thresholds. */ 35 template <> 36 struct Thresholds<CriticalObject> 37 { 38 static constexpr InterfaceType type = InterfaceType::CRIT; 39 static constexpr const char* envLo = "CRITLO"; 40 static constexpr const char* envHi = "CRITHI"; 41 static int64_t (CriticalObject::*const setLo)(int64_t); 42 static int64_t (CriticalObject::*const setHi)(int64_t); 43 static int64_t (CriticalObject::*const getLo)() const; 44 static int64_t (CriticalObject::*const getHi)() const; 45 static bool (CriticalObject::*const alarmLo)(bool); 46 static bool (CriticalObject::*const alarmHi)(bool); 47 }; 48 49 /** @brief checkThresholds 50 * 51 * Compare a sensor reading to threshold values and set the 52 * appropriate alarm property if bounds are exceeded. 53 * 54 * @tparam T - The threshold type. 55 * 56 * @param[in] iface - An sdbusplus server threshold instance. 57 * @param[in] value - The sensor reading to compare to thresholds. 58 */ 59 template <typename T> 60 void checkThresholds(std::experimental::any& iface, int64_t value) 61 { 62 auto realIface = std::experimental::any_cast<std::shared_ptr<T>> 63 (iface); 64 auto lo = (*realIface.*Thresholds<T>::getLo)(); 65 auto hi = (*realIface.*Thresholds<T>::getHi)(); 66 (*realIface.*Thresholds<T>::alarmLo)(value <= lo); 67 (*realIface.*Thresholds<T>::alarmHi)(value >= hi); 68 } 69 70 /** @brief addThreshold 71 * 72 * Look for a configured threshold value in the environment and 73 * create an sdbusplus server threshold if found. 74 * 75 * @tparam T - The threshold type. 76 * 77 * @param[in] sensorType - sensor type, like 'temp' 78 * @param[in] sensorID - sensor ID, like '5' 79 * @param[in] value - The sensor reading. 80 * @param[in] info - The sdbusplus server connection and interfaces. 81 */ 82 template <typename T> 83 auto addThreshold(const std::string& sensorType, 84 const std::string& sensorID, 85 int64_t value, 86 ObjectInfo& info) 87 { 88 static constexpr bool deferSignals = true; 89 90 auto& bus = *std::get<sdbusplus::bus::bus*>(info); 91 auto& objPath = std::get<std::string>(info); 92 auto& obj = std::get<Object>(info); 93 std::shared_ptr<T> iface; 94 95 auto tLo = env::getEnv(Thresholds<T>::envLo, sensorType, sensorID); 96 auto tHi = env::getEnv(Thresholds<T>::envHi, sensorType, sensorID); 97 if (!tLo.empty() && !tHi.empty()) 98 { 99 iface = std::make_shared<T>(bus, objPath.c_str(), deferSignals); 100 auto lo = stoll(tLo); 101 auto hi = stoll(tHi); 102 (*iface.*Thresholds<T>::setLo)(lo); 103 (*iface.*Thresholds<T>::setHi)(hi); 104 (*iface.*Thresholds<T>::alarmLo)(value <= lo); 105 (*iface.*Thresholds<T>::alarmHi)(value >= hi); 106 auto type = Thresholds<T>::type; 107 obj[type] = iface; 108 } 109 110 return iface; 111 } 112 113 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 114