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