1e228acc0SBrad Bishop #pragma once
2e228acc0SBrad Bishop
37a5285deSPatrick Venture #include "env.hpp"
4ee73f5bdSJames Feist #include "interface.hpp"
5ee73f5bdSJames Feist
6ee73f5bdSJames Feist #include <cmath>
77a5285deSPatrick Venture
8e228acc0SBrad Bishop /** @class Thresholds
9e228acc0SBrad Bishop * @brief Threshold type traits.
10e228acc0SBrad Bishop *
11e228acc0SBrad Bishop * @tparam T - The threshold type.
12e228acc0SBrad Bishop */
13e228acc0SBrad Bishop template <typename T>
14e228acc0SBrad Bishop struct Thresholds
15e228acc0SBrad Bishop {
failThresholds16e228acc0SBrad Bishop static void fail()
17e228acc0SBrad Bishop {
18e228acc0SBrad Bishop static_assert(sizeof(Thresholds) == -1, "Unsupported Threshold type");
19e228acc0SBrad Bishop }
20e228acc0SBrad Bishop };
21e228acc0SBrad Bishop
22e228acc0SBrad Bishop /**@brief Thresholds specialization for warning thresholds. */
23e228acc0SBrad Bishop template <>
24e228acc0SBrad Bishop struct Thresholds<WarningObject>
25e228acc0SBrad Bishop {
26e228acc0SBrad Bishop static constexpr InterfaceType type = InterfaceType::WARN;
27e228acc0SBrad Bishop static constexpr const char* envLo = "WARNLO";
28e228acc0SBrad Bishop static constexpr const char* envHi = "WARNHI";
29ee73f5bdSJames Feist static SensorValueType (WarningObject::* const setLo)(SensorValueType);
30ee73f5bdSJames Feist static SensorValueType (WarningObject::* const setHi)(SensorValueType);
31ee73f5bdSJames Feist static SensorValueType (WarningObject::* const getLo)() const;
32ee73f5bdSJames Feist static SensorValueType (WarningObject::* const getHi)() const;
33973886dbSSaqib Khan static bool (WarningObject::* const alarmLo)(bool);
34973886dbSSaqib Khan static bool (WarningObject::* const alarmHi)(bool);
3573769099SDuke Du static bool (WarningObject::* const getAlarmLow)() const;
3673769099SDuke Du static bool (WarningObject::* const getAlarmHigh)() const;
3773769099SDuke Du static void (WarningObject::* const assertLowSignal)(SensorValueType);
3873769099SDuke Du static void (WarningObject::* const assertHighSignal)(SensorValueType);
3973769099SDuke Du static void (WarningObject::* const deassertLowSignal)(SensorValueType);
4073769099SDuke Du static void (WarningObject::* const deassertHighSignal)(SensorValueType);
41e228acc0SBrad Bishop };
42e228acc0SBrad Bishop
43e228acc0SBrad Bishop /**@brief Thresholds specialization for critical thresholds. */
44e228acc0SBrad Bishop template <>
45e228acc0SBrad Bishop struct Thresholds<CriticalObject>
46e228acc0SBrad Bishop {
47e228acc0SBrad Bishop static constexpr InterfaceType type = InterfaceType::CRIT;
48e228acc0SBrad Bishop static constexpr const char* envLo = "CRITLO";
49e228acc0SBrad Bishop static constexpr const char* envHi = "CRITHI";
50ee73f5bdSJames Feist static SensorValueType (CriticalObject::* const setLo)(SensorValueType);
51ee73f5bdSJames Feist static SensorValueType (CriticalObject::* const setHi)(SensorValueType);
52ee73f5bdSJames Feist static SensorValueType (CriticalObject::* const getLo)() const;
53ee73f5bdSJames Feist static SensorValueType (CriticalObject::* const getHi)() const;
54973886dbSSaqib Khan static bool (CriticalObject::* const alarmLo)(bool);
55973886dbSSaqib Khan static bool (CriticalObject::* const alarmHi)(bool);
5673769099SDuke Du static bool (CriticalObject::* const getAlarmLow)() const;
5773769099SDuke Du static bool (CriticalObject::* const getAlarmHigh)() const;
5873769099SDuke Du static void (CriticalObject::* const assertLowSignal)(SensorValueType);
5973769099SDuke Du static void (CriticalObject::* const assertHighSignal)(SensorValueType);
6073769099SDuke Du static void (CriticalObject::* const deassertLowSignal)(SensorValueType);
6173769099SDuke Du static void (CriticalObject::* const deassertHighSignal)(SensorValueType);
62e228acc0SBrad Bishop };
63e228acc0SBrad Bishop
64e228acc0SBrad Bishop /** @brief checkThresholds
65e228acc0SBrad Bishop *
66e228acc0SBrad Bishop * Compare a sensor reading to threshold values and set the
67e228acc0SBrad Bishop * appropriate alarm property if bounds are exceeded.
68e228acc0SBrad Bishop *
69e228acc0SBrad Bishop * @tparam T - The threshold type.
70e228acc0SBrad Bishop *
71e228acc0SBrad Bishop * @param[in] iface - An sdbusplus server threshold instance.
72e228acc0SBrad Bishop * @param[in] value - The sensor reading to compare to thresholds.
73e228acc0SBrad Bishop */
74e228acc0SBrad Bishop template <typename T>
checkThresholds(std::any & iface,SensorValueType value)75ee73f5bdSJames Feist void checkThresholds(std::any& iface, SensorValueType value)
76e228acc0SBrad Bishop {
774cbdfef2SWilliam A. Kennington III auto realIface = std::any_cast<std::shared_ptr<T>>(iface);
78e228acc0SBrad Bishop auto lo = (*realIface.*Thresholds<T>::getLo)();
79e228acc0SBrad Bishop auto hi = (*realIface.*Thresholds<T>::getHi)();
8073769099SDuke Du auto alarmLowState = (*realIface.*Thresholds<T>::getAlarmLow)();
8173769099SDuke Du auto alarmHighState = (*realIface.*Thresholds<T>::getAlarmHigh)();
82fe17effcSChiabing Lee (*realIface.*Thresholds<T>::alarmLo)(value <= lo);
83fe17effcSChiabing Lee (*realIface.*Thresholds<T>::alarmHi)(value >= hi);
8473769099SDuke Du if (alarmLowState != (value <= lo))
8573769099SDuke Du {
8673769099SDuke Du if (value <= lo)
8773769099SDuke Du {
8873769099SDuke Du (*realIface.*Thresholds<T>::assertLowSignal)(value);
8973769099SDuke Du }
9073769099SDuke Du else
9173769099SDuke Du {
9273769099SDuke Du (*realIface.*Thresholds<T>::deassertLowSignal)(value);
9373769099SDuke Du }
9473769099SDuke Du }
9573769099SDuke Du if (alarmHighState != (value >= hi))
9673769099SDuke Du {
9773769099SDuke Du if (value >= hi)
9873769099SDuke Du {
9973769099SDuke Du (*realIface.*Thresholds<T>::assertHighSignal)(value);
10073769099SDuke Du }
10173769099SDuke Du else
10273769099SDuke Du {
10373769099SDuke Du (*realIface.*Thresholds<T>::deassertHighSignal)(value);
10473769099SDuke Du }
10573769099SDuke Du }
106e228acc0SBrad Bishop }
107e228acc0SBrad Bishop
108e228acc0SBrad Bishop /** @brief addThreshold
109e228acc0SBrad Bishop *
110e228acc0SBrad Bishop * Look for a configured threshold value in the environment and
111e228acc0SBrad Bishop * create an sdbusplus server threshold if found.
112e228acc0SBrad Bishop *
113e228acc0SBrad Bishop * @tparam T - The threshold type.
114e228acc0SBrad Bishop *
115ccfc77b6SMatt Spinler * @param[in] sensorType - sensor type, like 'temp'
116ccfc77b6SMatt Spinler * @param[in] sensorID - sensor ID, like '5'
117e228acc0SBrad Bishop * @param[in] value - The sensor reading.
118e228acc0SBrad Bishop * @param[in] info - The sdbusplus server connection and interfaces.
119e228acc0SBrad Bishop */
120e228acc0SBrad Bishop template <typename T>
addThreshold(const std::string & sensorType,const std::string & sensorID,SensorValueType value,ObjectInfo & info,int64_t scale)121043d3230SPatrick Venture auto addThreshold(const std::string& sensorType, const std::string& sensorID,
12273769099SDuke Du SensorValueType value, ObjectInfo& info, int64_t scale)
123e228acc0SBrad Bishop {
124e228acc0SBrad Bishop auto& objPath = std::get<std::string>(info);
1256206723dSPatrick Venture auto& obj = std::get<InterfaceMap>(info);
126e228acc0SBrad Bishop std::shared_ptr<T> iface;
127ccfc77b6SMatt Spinler
1287a5285deSPatrick Venture auto tLo = env::getEnv(Thresholds<T>::envLo, sensorType, sensorID);
1297a5285deSPatrick Venture auto tHi = env::getEnv(Thresholds<T>::envHi, sensorType, sensorID);
13004da0551SThang Q. Nguyen if (!tLo.empty() || !tHi.empty())
131e228acc0SBrad Bishop {
132*ad6043f6SPatrick Williams auto& bus = *std::get<sdbusplus::bus_t*>(info);
133685efa16SPatrick Venture
134d273b1e0SPatrick Williams iface = std::make_shared<T>(bus, objPath.c_str(),
135d273b1e0SPatrick Williams T::action::emit_no_signals);
13604da0551SThang Q. Nguyen if (!tLo.empty())
13704da0551SThang Q. Nguyen {
138ee73f5bdSJames Feist auto lo = stod(tLo) * std::pow(10, scale);
139e228acc0SBrad Bishop (*iface.*Thresholds<T>::setLo)(lo);
14073769099SDuke Du auto alarmLowState = (*iface.*Thresholds<T>::getAlarmLow)();
141fe17effcSChiabing Lee (*iface.*Thresholds<T>::alarmLo)(value <= lo);
14273769099SDuke Du if (alarmLowState != (value <= lo))
14373769099SDuke Du {
14473769099SDuke Du if (value <= lo)
14573769099SDuke Du {
14673769099SDuke Du (*iface.*Thresholds<T>::assertLowSignal)(value);
14773769099SDuke Du }
14873769099SDuke Du else
14973769099SDuke Du {
15073769099SDuke Du (*iface.*Thresholds<T>::deassertLowSignal)(value);
15173769099SDuke Du }
15273769099SDuke Du }
15304da0551SThang Q. Nguyen }
15404da0551SThang Q. Nguyen if (!tHi.empty())
15504da0551SThang Q. Nguyen {
15604da0551SThang Q. Nguyen auto hi = stod(tHi) * std::pow(10, scale);
15704da0551SThang Q. Nguyen (*iface.*Thresholds<T>::setHi)(hi);
15804da0551SThang Q. Nguyen auto alarmHighState = (*iface.*Thresholds<T>::getAlarmHigh)();
15904da0551SThang Q. Nguyen (*iface.*Thresholds<T>::alarmHi)(value >= hi);
16073769099SDuke Du if (alarmHighState != (value >= hi))
16173769099SDuke Du {
16273769099SDuke Du if (value >= hi)
16373769099SDuke Du {
16473769099SDuke Du (*iface.*Thresholds<T>::assertHighSignal)(value);
16573769099SDuke Du }
16673769099SDuke Du else
16773769099SDuke Du {
16873769099SDuke Du (*iface.*Thresholds<T>::deassertHighSignal)(value);
16973769099SDuke Du }
17073769099SDuke Du }
17104da0551SThang Q. Nguyen }
172e228acc0SBrad Bishop auto type = Thresholds<T>::type;
173e228acc0SBrad Bishop obj[type] = iface;
174e228acc0SBrad Bishop }
175e228acc0SBrad Bishop
176e228acc0SBrad Bishop return iface;
177e228acc0SBrad Bishop }
178