xref: /openbmc/phosphor-hwmon/thresholds.hpp (revision 7b587377)
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