platform-mc: Add sensor manager
Added sensor_manager class. The sensor_manager class manages the timing
of sensor polling.
tested: Verified on ast2600 EVB which is connected to a PLDM device
over I2C. bmcweb can display the state of numeric sensor.
Signed-off-by: Gilbert Chen <gilbert.chen@arm.com>
Signed-off-by: Thu Nguyen <thu@os.amperecomputing.com>
Change-Id: I4257f823ea26d7fdb322cc82d847e94db056258c
diff --git a/platform-mc/numeric_sensor.cpp b/platform-mc/numeric_sensor.cpp
index ad563fd..af6efad 100644
--- a/platform-mc/numeric_sensor.cpp
+++ b/platform-mc/numeric_sensor.cpp
@@ -15,11 +15,10 @@
namespace platform_mc
{
-NumericSensor::NumericSensor(const pldm_tid_t tid, const bool sensorDisabled,
- std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr,
- std::string& sensorName,
- std::string& associationPath) :
- tid(tid), sensorName(sensorName), isPriority(false)
+NumericSensor::NumericSensor(
+ const pldm_tid_t tid, const bool sensorDisabled,
+ std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr, std::string& sensorName,
+ std::string& associationPath) : tid(tid), sensorName(sensorName)
{
if (!pdr)
{
@@ -264,6 +263,7 @@
resolution = pdr->resolution;
offset = pdr->offset;
baseUnitModifier = pdr->unit_modifier;
+ timeStamp = 0;
/**
* DEFAULT_SENSOR_UPDATER_INTERVAL is in milliseconds
@@ -362,7 +362,7 @@
const pldm_tid_t tid, const bool sensorDisabled,
std::shared_ptr<pldm_compact_numeric_sensor_pdr> pdr,
std::string& sensorName, std::string& associationPath) :
- tid(tid), sensorName(sensorName), isPriority(false)
+ tid(tid), sensorName(sensorName)
{
if (!pdr)
{
@@ -478,6 +478,7 @@
resolution = std::numeric_limits<double>::quiet_NaN();
offset = std::numeric_limits<double>::quiet_NaN();
baseUnitModifier = pdr->unit_modifier;
+ timeStamp = 0;
/**
* DEFAULT_SENSOR_UPDATER_INTERVAL is in milliseconds
@@ -579,5 +580,175 @@
{
return std::isnan(value) ? value : value * std::pow(10, baseUnitModifier);
}
+
+void NumericSensor::updateReading(bool available, bool functional, double value)
+{
+ if (!availabilityIntf || !operationalStatusIntf || !valueIntf)
+ {
+ lg2::error(
+ "Failed to update sensor {NAME} D-Bus interface don't exist.",
+ "NAME", sensorName);
+ return;
+ }
+ availabilityIntf->available(available);
+ operationalStatusIntf->functional(functional);
+ double curValue = valueIntf->value();
+ double newValue = std::numeric_limits<double>::quiet_NaN();
+ if (functional && available)
+ {
+ newValue = unitModifier(conversionFormula(value));
+ if (newValue != curValue &&
+ (!std::isnan(newValue) || !std::isnan(curValue)))
+ {
+ valueIntf->value(newValue);
+ updateThresholds();
+ }
+ }
+ else
+ {
+ if (newValue != curValue &&
+ (!std::isnan(newValue) || !std::isnan(curValue)))
+ {
+ valueIntf->value(std::numeric_limits<double>::quiet_NaN());
+ }
+ }
+}
+
+void NumericSensor::handleErrGetSensorReading()
+{
+ if (!operationalStatusIntf || !valueIntf)
+ {
+ lg2::error(
+ "Failed to update sensor {NAME} D-Bus interfaces don't exist.",
+ "NAME", sensorName);
+ return;
+ }
+ operationalStatusIntf->functional(false);
+ valueIntf->value(std::numeric_limits<double>::quiet_NaN());
+}
+
+bool NumericSensor::checkThreshold(bool alarm, bool direction, double value,
+ double threshold, double hyst)
+{
+ if (direction)
+ {
+ if (value >= threshold)
+ {
+ return true;
+ }
+ if (value < (threshold - hyst))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (value <= threshold)
+ {
+ return true;
+ }
+ if (value > (threshold + hyst))
+ {
+ return false;
+ }
+ }
+ return alarm;
+}
+
+void NumericSensor::updateThresholds()
+{
+ if (!valueIntf)
+ {
+ lg2::error(
+ "Failed to update thresholds sensor {NAME} D-Bus interfaces don't exist.",
+ "NAME", sensorName);
+ return;
+ }
+
+ auto value = valueIntf->value();
+
+ if (thresholdWarningIntf &&
+ !std::isnan(thresholdWarningIntf->warningHigh()))
+ {
+ auto threshold = thresholdWarningIntf->warningHigh();
+ auto alarm = thresholdWarningIntf->warningAlarmHigh();
+ auto newAlarm =
+ checkThreshold(alarm, true, value, threshold, hysteresis);
+ if (alarm != newAlarm)
+ {
+ thresholdWarningIntf->warningAlarmHigh(newAlarm);
+ if (newAlarm)
+ {
+ thresholdWarningIntf->warningHighAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdWarningIntf->warningHighAlarmDeasserted(value);
+ }
+ }
+ }
+
+ if (thresholdWarningIntf && !std::isnan(thresholdWarningIntf->warningLow()))
+ {
+ auto threshold = thresholdWarningIntf->warningLow();
+ auto alarm = thresholdWarningIntf->warningAlarmLow();
+ auto newAlarm =
+ checkThreshold(alarm, false, value, threshold, hysteresis);
+ if (alarm != newAlarm)
+ {
+ thresholdWarningIntf->warningAlarmLow(newAlarm);
+ if (newAlarm)
+ {
+ thresholdWarningIntf->warningLowAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdWarningIntf->warningLowAlarmDeasserted(value);
+ }
+ }
+ }
+
+ if (thresholdCriticalIntf &&
+ !std::isnan(thresholdCriticalIntf->criticalHigh()))
+ {
+ auto threshold = thresholdCriticalIntf->criticalHigh();
+ auto alarm = thresholdCriticalIntf->criticalAlarmHigh();
+ auto newAlarm =
+ checkThreshold(alarm, true, value, threshold, hysteresis);
+ if (alarm != newAlarm)
+ {
+ thresholdCriticalIntf->criticalAlarmHigh(newAlarm);
+ if (newAlarm)
+ {
+ thresholdCriticalIntf->criticalHighAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdCriticalIntf->criticalHighAlarmDeasserted(value);
+ }
+ }
+ }
+
+ if (thresholdCriticalIntf &&
+ !std::isnan(thresholdCriticalIntf->criticalLow()))
+ {
+ auto threshold = thresholdCriticalIntf->criticalLow();
+ auto alarm = thresholdCriticalIntf->criticalAlarmLow();
+ auto newAlarm =
+ checkThreshold(alarm, false, value, threshold, hysteresis);
+ if (alarm != newAlarm)
+ {
+ thresholdCriticalIntf->criticalAlarmLow(newAlarm);
+ if (newAlarm)
+ {
+ thresholdCriticalIntf->criticalLowAlarmAsserted(value);
+ }
+ else
+ {
+ thresholdCriticalIntf->criticalLowAlarmDeasserted(value);
+ }
+ }
+ }
+}
} // namespace platform_mc
} // namespace pldm