blob: 8d557fc2ea2ebd324e27c7f89f92b079af90be4c [file] [log] [blame]
Brad Bishope228acc2017-01-06 15:29:35 -05001#pragma once
2
Patrick Venture7a5285d2018-04-17 19:15:05 -07003#include "env.hpp"
James Feistee73f5b2018-08-01 16:31:42 -07004#include "interface.hpp"
5
6#include <cmath>
Patrick Venture7a5285d2018-04-17 19:15:05 -07007
Brad Bishope228acc2017-01-06 15:29:35 -05008/** @class Thresholds
9 * @brief Threshold type traits.
10 *
11 * @tparam T - The threshold type.
12 */
13template <typename T>
14struct Thresholds
15{
16 static void fail()
17 {
18 static_assert(sizeof(Thresholds) == -1, "Unsupported Threshold type");
19 }
20};
21
22/**@brief Thresholds specialization for warning thresholds. */
23template <>
24struct Thresholds<WarningObject>
25{
26 static constexpr InterfaceType type = InterfaceType::WARN;
27 static constexpr const char* envLo = "WARNLO";
28 static constexpr const char* envHi = "WARNHI";
James Feistee73f5b2018-08-01 16:31:42 -070029 static SensorValueType (WarningObject::*const setLo)(SensorValueType);
30 static SensorValueType (WarningObject::*const setHi)(SensorValueType);
31 static SensorValueType (WarningObject::*const getLo)() const;
32 static SensorValueType (WarningObject::*const getHi)() const;
Saqib Khan973886d2017-03-15 14:01:16 -050033 static bool (WarningObject::*const alarmLo)(bool);
34 static bool (WarningObject::*const alarmHi)(bool);
Duke Du73769092021-04-14 15:35:21 +080035 static bool (WarningObject::*const getAlarmLow)() const;
36 static bool (WarningObject::*const getAlarmHigh)() const;
37 static void (WarningObject::*const assertLowSignal)(SensorValueType);
38 static void (WarningObject::*const assertHighSignal)(SensorValueType);
39 static void (WarningObject::*const deassertLowSignal)(SensorValueType);
40 static void (WarningObject::*const deassertHighSignal)(SensorValueType);
Brad Bishope228acc2017-01-06 15:29:35 -050041};
42
43/**@brief Thresholds specialization for critical thresholds. */
44template <>
45struct Thresholds<CriticalObject>
46{
47 static constexpr InterfaceType type = InterfaceType::CRIT;
48 static constexpr const char* envLo = "CRITLO";
49 static constexpr const char* envHi = "CRITHI";
James Feistee73f5b2018-08-01 16:31:42 -070050 static SensorValueType (CriticalObject::*const setLo)(SensorValueType);
51 static SensorValueType (CriticalObject::*const setHi)(SensorValueType);
52 static SensorValueType (CriticalObject::*const getLo)() const;
53 static SensorValueType (CriticalObject::*const getHi)() const;
Saqib Khan973886d2017-03-15 14:01:16 -050054 static bool (CriticalObject::*const alarmLo)(bool);
55 static bool (CriticalObject::*const alarmHi)(bool);
Duke Du73769092021-04-14 15:35:21 +080056 static bool (CriticalObject::*const getAlarmLow)() const;
57 static bool (CriticalObject::*const getAlarmHigh)() const;
58 static void (CriticalObject::*const assertLowSignal)(SensorValueType);
59 static void (CriticalObject::*const assertHighSignal)(SensorValueType);
60 static void (CriticalObject::*const deassertLowSignal)(SensorValueType);
61 static void (CriticalObject::*const deassertHighSignal)(SensorValueType);
Brad Bishope228acc2017-01-06 15:29:35 -050062};
63
64/** @brief checkThresholds
65 *
66 * Compare a sensor reading to threshold values and set the
67 * appropriate alarm property if bounds are exceeded.
68 *
69 * @tparam T - The threshold type.
70 *
71 * @param[in] iface - An sdbusplus server threshold instance.
72 * @param[in] value - The sensor reading to compare to thresholds.
73 */
74template <typename T>
James Feistee73f5b2018-08-01 16:31:42 -070075void checkThresholds(std::any& iface, SensorValueType value)
Brad Bishope228acc2017-01-06 15:29:35 -050076{
William A. Kennington III4cbdfef2018-10-18 19:19:51 -070077 auto realIface = std::any_cast<std::shared_ptr<T>>(iface);
Brad Bishope228acc2017-01-06 15:29:35 -050078 auto lo = (*realIface.*Thresholds<T>::getLo)();
79 auto hi = (*realIface.*Thresholds<T>::getHi)();
Duke Du73769092021-04-14 15:35:21 +080080 auto alarmLowState = (*realIface.*Thresholds<T>::getAlarmLow)();
81 auto alarmHighState = (*realIface.*Thresholds<T>::getAlarmHigh)();
Chiabing Leefe17eff2017-10-30 10:51:00 +080082 (*realIface.*Thresholds<T>::alarmLo)(value <= lo);
83 (*realIface.*Thresholds<T>::alarmHi)(value >= hi);
Duke Du73769092021-04-14 15:35:21 +080084 if (alarmLowState != (value <= lo))
85 {
86 if (value <= lo)
87 {
88 (*realIface.*Thresholds<T>::assertLowSignal)(value);
89 }
90 else
91 {
92 (*realIface.*Thresholds<T>::deassertLowSignal)(value);
93 }
94 }
95 if (alarmHighState != (value >= hi))
96 {
97 if (value >= hi)
98 {
99 (*realIface.*Thresholds<T>::assertHighSignal)(value);
100 }
101 else
102 {
103 (*realIface.*Thresholds<T>::deassertHighSignal)(value);
104 }
105 }
Brad Bishope228acc2017-01-06 15:29:35 -0500106}
107
108/** @brief addThreshold
109 *
110 * Look for a configured threshold value in the environment and
111 * create an sdbusplus server threshold if found.
112 *
113 * @tparam T - The threshold type.
114 *
Matt Spinlerccfc77b2017-10-12 16:49:24 -0500115 * @param[in] sensorType - sensor type, like 'temp'
116 * @param[in] sensorID - sensor ID, like '5'
Brad Bishope228acc2017-01-06 15:29:35 -0500117 * @param[in] value - The sensor reading.
118 * @param[in] info - The sdbusplus server connection and interfaces.
119 */
120template <typename T>
Patrick Venture043d3232018-08-31 10:10:53 -0700121auto addThreshold(const std::string& sensorType, const std::string& sensorID,
Duke Du73769092021-04-14 15:35:21 +0800122 SensorValueType value, ObjectInfo& info, int64_t scale)
Brad Bishope228acc2017-01-06 15:29:35 -0500123{
Brad Bishope228acc2017-01-06 15:29:35 -0500124 auto& objPath = std::get<std::string>(info);
Patrick Venture62067232019-06-19 17:39:33 -0700125 auto& obj = std::get<InterfaceMap>(info);
Brad Bishope228acc2017-01-06 15:29:35 -0500126 std::shared_ptr<T> iface;
Matt Spinlerccfc77b2017-10-12 16:49:24 -0500127
Patrick Venture7a5285d2018-04-17 19:15:05 -0700128 auto tLo = env::getEnv(Thresholds<T>::envLo, sensorType, sensorID);
129 auto tHi = env::getEnv(Thresholds<T>::envHi, sensorType, sensorID);
Brad Bishope228acc2017-01-06 15:29:35 -0500130 if (!tLo.empty() && !tHi.empty())
131 {
Patrick Venture685efa12018-10-12 18:00:13 -0700132 static constexpr bool deferSignals = true;
133 auto& bus = *std::get<sdbusplus::bus::bus*>(info);
134
Brad Bishop30dbcee2017-01-18 07:55:42 -0500135 iface = std::make_shared<T>(bus, objPath.c_str(), deferSignals);
James Feistee73f5b2018-08-01 16:31:42 -0700136 auto lo = stod(tLo) * std::pow(10, scale);
137 auto hi = stod(tHi) * std::pow(10, scale);
Brad Bishope228acc2017-01-06 15:29:35 -0500138 (*iface.*Thresholds<T>::setLo)(lo);
139 (*iface.*Thresholds<T>::setHi)(hi);
Duke Du73769092021-04-14 15:35:21 +0800140 auto alarmLowState = (*iface.*Thresholds<T>::getAlarmLow)();
141 auto alarmHighState = (*iface.*Thresholds<T>::getAlarmHigh)();
Chiabing Leefe17eff2017-10-30 10:51:00 +0800142 (*iface.*Thresholds<T>::alarmLo)(value <= lo);
143 (*iface.*Thresholds<T>::alarmHi)(value >= hi);
Duke Du73769092021-04-14 15:35:21 +0800144 if (alarmLowState != (value <= lo))
145 {
146 if (value <= lo)
147 {
148 (*iface.*Thresholds<T>::assertLowSignal)(value);
149 }
150 else
151 {
152 (*iface.*Thresholds<T>::deassertLowSignal)(value);
153 }
154 }
155 if (alarmHighState != (value >= hi))
156 {
157 if (value >= hi)
158 {
159 (*iface.*Thresholds<T>::assertHighSignal)(value);
160 }
161 else
162 {
163 (*iface.*Thresholds<T>::deassertHighSignal)(value);
164 }
165 }
Brad Bishope228acc2017-01-06 15:29:35 -0500166 auto type = Thresholds<T>::type;
167 obj[type] = iface;
168 }
169
170 return iface;
171}
172
173// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4