Fault status check before reading sensor value
Checking for the fault sysfs file should be done prior to reading the
input value when creating the sensor's dbus object. A sensor providing a
fault sysfs file will have a status interface functional property
created with its initial functional state. A sensor in a nonfunctional
state when the object is created, will have an initial value of 0.
The hwmon documentation states that when a sensor input channel presents
an associated fault file, the measurement value provided for that
channel should not be trusted when the fault boolean has a value of 1.
Using an initial value of 0 follows this specification and allows the
corresponding dbus object to be created.
Tested:
Faulted sensor at hwmon start shows functional status of false.
Faulted sensor at hwmon start contains a sensor value of 0.
Change-Id: I6388a3f84f638360b03e557aadc6de8331e67a69
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/mainloop.cpp b/mainloop.cpp
index a9898b7..ad73df7 100644
--- a/mainloop.cpp
+++ b/mainloop.cpp
@@ -149,16 +149,6 @@
// Add sensor removal return codes defined per sensor
addRemoveRCs(sensor, senRmRCs);
- // Retry for up to a second if device is busy
- // or has a transient error.
- int64_t val = ioAccess.read(
- sensor.first,
- sensor.second,
- hwmon::entry::cinput,
- std::get<size_t>(retryIO),
- std::get<std::chrono::milliseconds>(retryIO),
- isOCC);
-
auto gain = env::getEnv("GAIN", sensor);
if (!gain.empty())
{
@@ -171,7 +161,30 @@
sensorAdjusts[sensor].offset = std::stoi(offset);
}
- val = adjustValue(sensor, val);
+ int64_t val = 0;
+ std::shared_ptr<StatusObject> statusIface = nullptr;
+ auto it = obj.find(InterfaceType::STATUS);
+ if (it != obj.end())
+ {
+ statusIface = std::experimental::any_cast<
+ std::shared_ptr<StatusObject>>(it->second);
+ }
+
+ // If there's no fault file or the sensor has a fault file and
+ // its status is functional, read the input value.
+ if (!statusIface || (statusIface && statusIface->functional()))
+ {
+ // Retry for up to a second if device is busy
+ // or has a transient error.
+ val = ioAccess.read(
+ sensor.first,
+ sensor.second,
+ hwmon::entry::cinput,
+ std::get<size_t>(retryIO),
+ std::get<std::chrono::milliseconds>(retryIO),
+ isOCC);
+ val = adjustValue(sensor, val);
+ }
auto iface = std::make_shared<ValueObject>(bus, objPath.c_str(), deferSignals);
iface->value(val);
@@ -292,6 +305,8 @@
std::shared_ptr<ValueObject>>(nullptr);
try
{
+ // Add status interface based on _fault file being present
+ sensor::addStatus(sensor.first, ioAccess, _devPath, info);
valueInterface = addValue(sensor.first, retryIO, ioAccess, info,
_isOCC);
}
@@ -358,9 +373,6 @@
}
addTarget<hwmon::FanPwm>(sensor.first, ioAccess, _devPath, info);
- // Add status interface based on _fault file being present
- sensor::addStatus(sensor.first, ioAccess, _devPath, info);
-
// All the interfaces have been created. Go ahead
// and emit InterfacesAdded.
valueInterface->emit_object_added();