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>>(iface); 63 auto lo = (*realIface.*Thresholds<T>::getLo)(); 64 auto hi = (*realIface.*Thresholds<T>::getHi)(); 65 (*realIface.*Thresholds<T>::alarmLo)(value <= lo); 66 (*realIface.*Thresholds<T>::alarmHi)(value >= hi); 67 } 68 69 /** @brief addThreshold 70 * 71 * Look for a configured threshold value in the environment and 72 * create an sdbusplus server threshold if found. 73 * 74 * @tparam T - The threshold type. 75 * 76 * @param[in] sensorType - sensor type, like 'temp' 77 * @param[in] sensorID - sensor ID, like '5' 78 * @param[in] value - The sensor reading. 79 * @param[in] info - The sdbusplus server connection and interfaces. 80 */ 81 template <typename T> 82 auto addThreshold(const std::string& sensorType, const std::string& sensorID, 83 int64_t value, ObjectInfo& info) 84 { 85 static constexpr bool deferSignals = true; 86 87 auto& bus = *std::get<sdbusplus::bus::bus*>(info); 88 auto& objPath = std::get<std::string>(info); 89 auto& obj = std::get<Object>(info); 90 std::shared_ptr<T> iface; 91 92 auto tLo = env::getEnv(Thresholds<T>::envLo, sensorType, sensorID); 93 auto tHi = env::getEnv(Thresholds<T>::envHi, sensorType, sensorID); 94 if (!tLo.empty() && !tHi.empty()) 95 { 96 iface = std::make_shared<T>(bus, objPath.c_str(), deferSignals); 97 auto lo = stoll(tLo); 98 auto hi = stoll(tHi); 99 (*iface.*Thresholds<T>::setLo)(lo); 100 (*iface.*Thresholds<T>::setHi)(hi); 101 (*iface.*Thresholds<T>::alarmLo)(value <= lo); 102 (*iface.*Thresholds<T>::alarmHi)(value >= hi); 103 auto type = Thresholds<T>::type; 104 obj[type] = iface; 105 } 106 107 return iface; 108 } 109 110 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 111