Support threshold hysteresis
Add support for a hysteresis value on the warning high/low and critical
high/low sensor thresholds. On the high thresholds, this requires the
sensor value to dip below the (threshold - hysteresis) value before the
alarm clears, and on the low thresholds it has to go above (threshold +
hysteresis).
These are optional fields in the configuration JSON and will default to
zero if not present, which results in the previous behavior of not
having a hysteresis at all.
Tested: with IBM's Ambient_Virtual_Temp sensor. When changing the value
above a high threshold and then back below the threshold, we only see
the alarm deasserted when the temp is below (threshold - hysteresis).
Change-Id: Ied1d40def94e1b66cf4ec8826799bada4e6236ab
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
diff --git a/virtualSensor.cpp b/virtualSensor.cpp
index 4e9f50a..0f27019 100644
--- a/virtualSensor.cpp
+++ b/virtualSensor.cpp
@@ -18,6 +18,7 @@
static constexpr auto vsThresholdsIfaceSuffix = ".Thresholds";
static constexpr std::array<const char*, 1> calculationIfaces = {
"xyz.openbmc_project.Configuration.ModifiedMedian"};
+static constexpr auto defaultHysteresis = 0;
using namespace phosphor::logging;
@@ -185,6 +186,13 @@
auto threshold = getThresholdType(direction, severity);
thresholds[threshold] = value;
+
+ auto hysteresis =
+ getNumberFromConfig<double>(propertyMap, "Hysteresis", false);
+ if (hysteresis != std::numeric_limits<double>::quiet_NaN())
+ {
+ thresholds[threshold + "Hysteresis"] = hysteresis;
+ }
}
void VirtualSensor::parseConfigInterface(const PropertyMap& propertyMap,
@@ -507,6 +515,10 @@
"CriticalHigh", std::numeric_limits<double>::quiet_NaN()));
criticalIface->criticalLow(threshold.value(
"CriticalLow", std::numeric_limits<double>::quiet_NaN()));
+ criticalIface->setHighHysteresis(
+ threshold.value("CriticalHighHysteresis", defaultHysteresis));
+ criticalIface->setLowHysteresis(
+ threshold.value("CriticalLowHysteresis", defaultHysteresis));
}
if (threshold.contains("WarningHigh") || threshold.contains("WarningLow"))
@@ -518,6 +530,10 @@
"WarningHigh", std::numeric_limits<double>::quiet_NaN()));
warningIface->warningLow(threshold.value(
"WarningLow", std::numeric_limits<double>::quiet_NaN()));
+ warningIface->setHighHysteresis(
+ threshold.value("WarningHighHysteresis", defaultHysteresis));
+ warningIface->setLowHysteresis(
+ threshold.value("WarningLowHysteresis", defaultHysteresis));
}
if (threshold.contains("HardShutdownHigh") ||
@@ -530,6 +546,10 @@
"HardShutdownHigh", std::numeric_limits<double>::quiet_NaN()));
hardShutdownIface->hardShutdownLow(threshold.value(
"HardShutdownLow", std::numeric_limits<double>::quiet_NaN()));
+ hardShutdownIface->setHighHysteresis(
+ threshold.value("HardShutdownHighHysteresis", defaultHysteresis));
+ hardShutdownIface->setLowHysteresis(
+ threshold.value("HardShutdownLowHysteresis", defaultHysteresis));
}
if (threshold.contains("SoftShutdownHigh") ||
@@ -542,6 +562,10 @@
"SoftShutdownHigh", std::numeric_limits<double>::quiet_NaN()));
softShutdownIface->softShutdownLow(threshold.value(
"SoftShutdownLow", std::numeric_limits<double>::quiet_NaN()));
+ softShutdownIface->setHighHysteresis(
+ threshold.value("SoftShutdownHighHysteresis", defaultHysteresis));
+ softShutdownIface->setLowHysteresis(
+ threshold.value("SoftShutdownLowHysteresis", defaultHysteresis));
}
if (threshold.contains("PerformanceLossHigh") ||
@@ -554,6 +578,10 @@
"PerformanceLossHigh", std::numeric_limits<double>::quiet_NaN()));
perfLossIface->performanceLossLow(threshold.value(
"PerformanceLossLow", std::numeric_limits<double>::quiet_NaN()));
+ perfLossIface->setHighHysteresis(threshold.value(
+ "PerformanceLossHighHysteresis", defaultHysteresis));
+ perfLossIface->setLowHysteresis(
+ threshold.value("PerformanceLossLowHysteresis", defaultHysteresis));
}
}