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