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