xref: /openbmc/phosphor-hwmon/thresholds.hpp (revision 043d3230)
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>>(iface);
63     auto lo = (*realIface.*Thresholds<T>::getLo)();
64     auto hi = (*realIface.*Thresholds<T>::getHi)();
65     (*realIface.*Thresholds<T>::alarmLo)(value <= lo);
66     (*realIface.*Thresholds<T>::alarmHi)(value >= hi);
67 }
68 
69 /** @brief addThreshold
70  *
71  *  Look for a configured threshold value in the environment and
72  *  create an sdbusplus server threshold if found.
73  *
74  *  @tparam T - The threshold type.
75  *
76  *  @param[in] sensorType - sensor type, like 'temp'
77  *  @param[in] sensorID - sensor ID, like '5'
78  *  @param[in] value - The sensor reading.
79  *  @param[in] info - The sdbusplus server connection and interfaces.
80  */
81 template <typename T>
82 auto addThreshold(const std::string& sensorType, const std::string& sensorID,
83                   int64_t value, ObjectInfo& info)
84 {
85     static constexpr bool deferSignals = true;
86 
87     auto& bus = *std::get<sdbusplus::bus::bus*>(info);
88     auto& objPath = std::get<std::string>(info);
89     auto& obj = std::get<Object>(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         iface = std::make_shared<T>(bus, objPath.c_str(), deferSignals);
97         auto lo = stoll(tLo);
98         auto hi = stoll(tHi);
99         (*iface.*Thresholds<T>::setLo)(lo);
100         (*iface.*Thresholds<T>::setHi)(hi);
101         (*iface.*Thresholds<T>::alarmLo)(value <= lo);
102         (*iface.*Thresholds<T>::alarmHi)(value >= hi);
103         auto type = Thresholds<T>::type;
104         obj[type] = iface;
105     }
106 
107     return iface;
108 }
109 
110 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
111