#pragma once #include "env.hpp" /** @class Thresholds * @brief Threshold type traits. * * @tparam T - The threshold type. */ template struct Thresholds { static void fail() { static_assert(sizeof(Thresholds) == -1, "Unsupported Threshold type"); } }; /**@brief Thresholds specialization for warning thresholds. */ template <> struct Thresholds { static constexpr InterfaceType type = InterfaceType::WARN; static constexpr const char* envLo = "WARNLO"; static constexpr const char* envHi = "WARNHI"; static int64_t (WarningObject::*const setLo)(int64_t); static int64_t (WarningObject::*const setHi)(int64_t); static int64_t (WarningObject::*const getLo)() const; static int64_t (WarningObject::*const getHi)() const; static bool (WarningObject::*const alarmLo)(bool); static bool (WarningObject::*const alarmHi)(bool); }; /**@brief Thresholds specialization for critical thresholds. */ template <> struct Thresholds { static constexpr InterfaceType type = InterfaceType::CRIT; static constexpr const char* envLo = "CRITLO"; static constexpr const char* envHi = "CRITHI"; static int64_t (CriticalObject::*const setLo)(int64_t); static int64_t (CriticalObject::*const setHi)(int64_t); static int64_t (CriticalObject::*const getLo)() const; static int64_t (CriticalObject::*const getHi)() const; static bool (CriticalObject::*const alarmLo)(bool); static bool (CriticalObject::*const alarmHi)(bool); }; /** @brief checkThresholds * * Compare a sensor reading to threshold values and set the * appropriate alarm property if bounds are exceeded. * * @tparam T - The threshold type. * * @param[in] iface - An sdbusplus server threshold instance. * @param[in] value - The sensor reading to compare to thresholds. */ template void checkThresholds(std::experimental::any& iface, int64_t value) { auto realIface = std::experimental::any_cast>(iface); auto lo = (*realIface.*Thresholds::getLo)(); auto hi = (*realIface.*Thresholds::getHi)(); (*realIface.*Thresholds::alarmLo)(value <= lo); (*realIface.*Thresholds::alarmHi)(value >= hi); } /** @brief addThreshold * * Look for a configured threshold value in the environment and * create an sdbusplus server threshold if found. * * @tparam T - The threshold type. * * @param[in] sensorType - sensor type, like 'temp' * @param[in] sensorID - sensor ID, like '5' * @param[in] value - The sensor reading. * @param[in] info - The sdbusplus server connection and interfaces. */ template auto addThreshold(const std::string& sensorType, const std::string& sensorID, int64_t value, ObjectInfo& info) { static constexpr bool deferSignals = true; auto& bus = *std::get(info); auto& objPath = std::get(info); auto& obj = std::get(info); std::shared_ptr iface; auto tLo = env::getEnv(Thresholds::envLo, sensorType, sensorID); auto tHi = env::getEnv(Thresholds::envHi, sensorType, sensorID); if (!tLo.empty() && !tHi.empty()) { iface = std::make_shared(bus, objPath.c_str(), deferSignals); auto lo = stoll(tLo); auto hi = stoll(tHi); (*iface.*Thresholds::setLo)(lo); (*iface.*Thresholds::setHi)(hi); (*iface.*Thresholds::alarmLo)(value <= lo); (*iface.*Thresholds::alarmHi)(value >= hi); auto type = Thresholds::type; obj[type] = iface; } return iface; } // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4