summaryrefslogtreecommitdiffstats
path: root/sensor.cpp
diff options
context:
space:
mode:
authorMatthew Barth <msbarth@us.ibm.com>2018-05-07 15:03:16 -0500
committerMatthew Barth <msbarth@us.ibm.com>2018-05-24 10:25:32 -0500
commitcb3daafb5681ef8359563fb04d8545f2ecb83c92 (patch)
treef971131502deaece0a26c9444c7ece911f7834a8 /sensor.cpp
parent2e41b13f9ea27976a85abbbc5e3028fa258d16d2 (diff)
downloadphosphor-hwmon-cb3daafb5681ef8359563fb04d8545f2ecb83c92.tar.gz
phosphor-hwmon-cb3daafb5681ef8359563fb04d8545f2ecb83c92.zip
Move value iface creation into sensor object
Create the Sensor.Value interface for a sensor within the sensor object. Each sensor must have an input sysfs file to get a Value property on the Sensor.Value interface and be included by hwmon. Tested: No change in value interface creation for sensors Change-Id: I09b1c79142ba2a34424f5ec29f41d19a987c84e7 Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
Diffstat (limited to 'sensor.cpp')
-rw-r--r--sensor.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/sensor.cpp b/sensor.cpp
index 3a1ed73..155b8bd 100644
--- a/sensor.cpp
+++ b/sensor.cpp
@@ -1,16 +1,21 @@
+#include <cstring>
#include <experimental/filesystem>
#include <phosphor-logging/elog-errors.hpp>
#include <xyz/openbmc_project/Sensor/Device/error.hpp>
+#include "config.h"
#include "sensor.hpp"
#include "sensorset.hpp"
#include "hwmon.hpp"
+#include "env.hpp"
#include "sysfs.hpp"
namespace sensor
{
+using namespace phosphor::logging;
+
Sensor::Sensor(const SensorSet::key_type& sensor,
const hwmonio::HwmonIO& ioAccess,
const std::string& devPath) :
@@ -20,6 +25,116 @@ Sensor::Sensor(const SensorSet::key_type& sensor,
{
}
+void Sensor::addRemoveRCs(const std::string& rcList)
+{
+ if (rcList.empty())
+ {
+ return;
+ }
+
+ // Convert to a char* for strtok
+ std::vector<char> rmRCs(rcList.c_str(),
+ rcList.c_str() + rcList.size() + 1);
+ auto rmRC = std::strtok(&rmRCs[0], ", ");
+ while (rmRC != nullptr)
+ {
+ try
+ {
+ sensorAdjusts.rmRCs.insert(std::stoi(rmRC));
+ }
+ catch (const std::logic_error& le)
+ {
+ // Unable to convert to int, continue to next token
+ std::string name = sensor.first + "_" + sensor.second;
+ log<level::INFO>("Unable to convert sensor removal return code",
+ entry("SENSOR=%s", name.c_str()),
+ entry("RC=%s", rmRC),
+ entry("EXCEPTION=%s", le.what()));
+ }
+ rmRC = std::strtok(nullptr, ", ");
+ }
+}
+
+int64_t Sensor::adjustValue(int64_t value)
+{
+// Because read doesn't have an out pointer to store errors.
+// let's assume negative values are errors if they have this
+// set.
+#ifdef NEGATIVE_ERRNO_ON_FAIL
+ if (value < 0)
+ {
+ return value;
+ }
+#endif
+
+ // Adjust based on gain and offset
+ value = static_cast<decltype(value)>(
+ static_cast<double>(value) * sensorAdjusts.gain
+ + sensorAdjusts.offset);
+
+ return value;
+}
+
+std::shared_ptr<ValueObject> Sensor::addValue(
+ const RetryIO& retryIO,
+ ObjectInfo& info)
+{
+ static constexpr bool deferSignals = true;
+
+ // Get the initial value for the value interface.
+ auto& bus = *std::get<sdbusplus::bus::bus*>(info);
+ auto& obj = std::get<Object>(info);
+ auto& objPath = std::get<std::string>(info);
+
+ 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));
+ val = adjustValue(val);
+ }
+
+ auto iface = std::make_shared<ValueObject>(bus, objPath.c_str(), deferSignals);
+ iface->value(val);
+
+ hwmon::Attributes attrs;
+ if (hwmon::getAttributes(sensor.first, attrs))
+ {
+ iface->unit(hwmon::getUnit(attrs));
+ iface->scale(hwmon::getScale(attrs));
+ }
+
+ auto maxValue = env::getEnv("MAXVALUE", sensor);
+ if(!maxValue.empty())
+ {
+ iface->maxValue(std::stoll(maxValue));
+ }
+ auto minValue = env::getEnv("MINVALUE", sensor);
+ if(!minValue.empty())
+ {
+ iface->minValue(std::stoll(minValue));
+ }
+
+ obj[InterfaceType::VALUE] = iface;
+ return iface;
+}
+
std::shared_ptr<StatusObject> Sensor::addStatus(ObjectInfo& info)
{
namespace fs = std::experimental::filesystem;
OpenPOWER on IntegriCloud