xref: /openbmc/phosphor-hwmon/thresholds.hpp (revision e228acc0)
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 constexpr int64_t (WarningObject::*setLo)(int64_t) =
25         &WarningObject::warningLow;
26     static constexpr int64_t (WarningObject::*setHi)(int64_t) =
27         &WarningObject::warningHigh;
28     static constexpr int64_t (WarningObject::*getLo)() const =
29         &WarningObject::warningLow;
30     static constexpr int64_t (WarningObject::*getHi)() const =
31         &WarningObject::warningHigh;
32     static constexpr bool (WarningObject::*alarmLo)(bool) =
33         &WarningObject::warningAlarmLow;
34     static constexpr bool (WarningObject::*alarmHi)(bool) =
35         &WarningObject::warningAlarmHigh;
36 };
37 
38 /**@brief Thresholds specialization for critical thresholds. */
39 template <>
40 struct Thresholds<CriticalObject>
41 {
42     static constexpr InterfaceType type = InterfaceType::CRIT;
43     static constexpr const char* envLo = "CRITLO";
44     static constexpr const char* envHi = "CRITHI";
45     static constexpr int64_t (CriticalObject::*setLo)(int64_t) =
46         &CriticalObject::criticalLow;
47     static constexpr int64_t (CriticalObject::*setHi)(int64_t) =
48         &CriticalObject::criticalHigh;
49     static constexpr int64_t (CriticalObject::*getLo)() const =
50         &CriticalObject::criticalLow;
51     static constexpr int64_t (CriticalObject::*getHi)() const =
52         &CriticalObject::criticalHigh;
53     static constexpr bool (CriticalObject::*alarmLo)(bool) =
54         &CriticalObject::criticalAlarmLow;
55     static constexpr bool (CriticalObject::*alarmHi)(bool) =
56         &CriticalObject::criticalAlarmHigh;
57 };
58 
59 /** @brief checkThresholds
60  *
61  *  Compare a sensor reading to threshold values and set the
62  *  appropriate alarm property if bounds are exceeded.
63  *
64  *  @tparam T - The threshold type.
65  *
66  *  @param[in] iface - An sdbusplus server threshold instance.
67  *  @param[in] value - The sensor reading to compare to thresholds.
68  */
69 template <typename T>
70 void checkThresholds(std::experimental::any& iface, int64_t value)
71 {
72     auto realIface = std::experimental::any_cast<std::shared_ptr<T>>
73                      (iface);
74     auto lo = (*realIface.*Thresholds<T>::getLo)();
75     auto hi = (*realIface.*Thresholds<T>::getHi)();
76     (*realIface.*Thresholds<T>::alarmLo)(value < lo);
77     (*realIface.*Thresholds<T>::alarmHi)(value > hi);
78 }
79 
80 /** @brief addThreshold
81  *
82  *  Look for a configured threshold value in the environment and
83  *  create an sdbusplus server threshold if found.
84  *
85  *  @tparam T - The threshold type.
86  *
87  *  @param[in] sensor - A sensor type and name.
88  *  @param[in] value - The sensor reading.
89  *  @param[in] info - The sdbusplus server connection and interfaces.
90  */
91 template <typename T>
92 auto addThreshold(const SensorSet::key_type& sensor,
93                   int64_t value, ObjectInfo& info)
94 {
95     auto& bus = *std::get<sdbusplus::bus::bus*>(info);
96     auto& objPath = std::get<std::string>(info);
97     auto& obj = std::get<Object>(info);
98     std::shared_ptr<T> iface;
99     auto tLo = getEnv(Thresholds<T>::envLo, sensor);
100     auto tHi = getEnv(Thresholds<T>::envHi, sensor);
101     if (!tLo.empty() && !tHi.empty())
102     {
103         iface = std::make_shared<T>(bus, objPath.c_str());
104         auto lo = stoi(tLo);
105         auto hi = stoi(tHi);
106         (*iface.*Thresholds<T>::setLo)(lo);
107         (*iface.*Thresholds<T>::setHi)(hi);
108         (*iface.*Thresholds<T>::alarmLo)(value < lo);
109         (*iface.*Thresholds<T>::alarmHi)(value > hi);
110         auto type = Thresholds<T>::type;
111         obj[type] = iface;
112     }
113 
114     return iface;
115 }
116 
117 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
118