diff options
author | Matthew Barth <msbarth@us.ibm.com> | 2018-05-07 15:03:16 -0500 |
---|---|---|
committer | Matthew Barth <msbarth@us.ibm.com> | 2018-05-24 10:25:32 -0500 |
commit | cb3daafb5681ef8359563fb04d8545f2ecb83c92 (patch) | |
tree | f971131502deaece0a26c9444c7ece911f7834a8 /sensor.cpp | |
parent | 2e41b13f9ea27976a85abbbc5e3028fa258d16d2 (diff) | |
download | phosphor-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.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
@@ -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; |