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 | |
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>
-rw-r--r-- | mainloop.cpp | 138 | ||||
-rw-r--r-- | sensor.cpp | 115 | ||||
-rw-r--r-- | sensor.hpp | 47 |
3 files changed, 165 insertions, 135 deletions
diff --git a/mainloop.cpp b/mainloop.cpp index be9b680..595432d 100644 --- a/mainloop.cpp +++ b/mainloop.cpp @@ -17,7 +17,6 @@ #include <iostream> #include <memory> #include <cstdlib> -#include <cstring> #include <string> #include <unordered_set> #include <sstream> @@ -79,137 +78,6 @@ struct valueAdjust // Store the valueAdjust for sensors std::map<SensorSet::key_type, valueAdjust> sensorAdjusts; -void addRemoveRCs(const SensorSet::key_type& sensor, - 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[sensor].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 adjustValue(const SensorSet::key_type& sensor, 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 - - const auto& it = sensorAdjusts.find(sensor); - if (it != sensorAdjusts.end()) - { - // Adjust based on gain and offset - value = static_cast<decltype(value)>( - static_cast<double>(value) * it->second.gain - + it->second.offset); - } - return value; -} - -auto addValue(const SensorSet::key_type& sensor, - const RetryIO& retryIO, - hwmonio::HwmonIO& ioAccess, - 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); - - auto senRmRCs = env::getEnv("REMOVERCS", sensor); - // Add sensor removal return codes defined per sensor - addRemoveRCs(sensor, senRmRCs); - - auto gain = env::getEnv("GAIN", sensor); - if (!gain.empty()) - { - sensorAdjusts[sensor].gain = std::stod(gain); - } - - auto offset = env::getEnv("OFFSET", sensor); - if (!offset.empty()) - { - sensorAdjusts[sensor].offset = std::stoi(offset); - } - - 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(sensor, 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::string MainLoop::getID(SensorSet::container_t::const_reference sensor) { std::string id; @@ -295,7 +163,7 @@ optional_ns::optional<ObjectStateData> MainLoop::getObject( // Get list of return codes for removing sensors on device auto devRmRCs = env::getEnv("REMOVERCS"); // Add sensor removal return codes defined at the device level - addRemoveRCs(sensor.first, devRmRCs); + sensorObj->addRemoveRCs(devRmRCs); std::string objectPath{_root}; objectPath.append(1, '/'); @@ -317,7 +185,7 @@ optional_ns::optional<ObjectStateData> MainLoop::getObject( { // Add status interface based on _fault file being present sensorObj->addStatus(info); - valueInterface = addValue(sensor.first, retryIO, ioAccess, info); + valueInterface = sensorObj->addValue(retryIO, info); } catch (const std::system_error& e) { @@ -566,7 +434,7 @@ void MainLoop::read() hwmonio::retries, hwmonio::delay); - value = adjustValue(i.first, value); + value = sensorObjects[i.first]->adjustValue(value); for (auto& iface : obj) { @@ -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; @@ -1,5 +1,6 @@ #pragma once +#include <unordered_set> #include "types.hpp" #include "sensorset.hpp" #include "hwmonio.hpp" @@ -7,6 +8,13 @@ namespace sensor { +struct valueAdjust +{ + double gain = 1.0; + int offset = 0; + std::unordered_set<int> rmRCs; +}; + /** @class Sensor * @brief Sensor object based on a SensorSet container's key type * @details Sensor object to create and modify an associated device's sensor @@ -35,6 +43,42 @@ class Sensor const std::string& devPath); /** + * @brief Adds any sensor removal return codes for the sensor + * @details Add all return codes defined within a device's config file + * for the entire device or for the specific sensor. + * + * @param[in] rcList - List of return codes found for the sensor + */ + void addRemoveRCs(const std::string& rcList); + + /** + * @brief Adjusts a sensor value + * @details Adjusts the value given by any gain and/or offset defined + * for this sensor object and returns that adjusted value. + * + * @param[in] value - Value to be adjusted + * + * @return - Adjusted sensor value + */ + int64_t adjustValue(int64_t value); + + /** + * @brief Add value interface and value property for sensor + * @details When a sensor has an associated input file, the Sensor.Value + * interface is added along with setting the Value property to the + * corresponding value found in the input file. + * + * @param[in] retryIO - Hwmon sysfs file retry constraints + * (number of and delay between) + * @param[in] info - Sensor object information + * + * @return - Shared pointer to the value object + */ + std::shared_ptr<ValueObject> addValue( + const RetryIO& retryIO, + ObjectInfo& info); + + /** * @brief Add status interface and functional property for sensor * @details When a sensor has an associated fault file, the * OperationalStatus interface is added along with setting the @@ -57,6 +101,9 @@ class Sensor /** @brief Physical device sysfs path. */ const std::string& devPath; + + /** @brief Structure for storing sensor adjustments */ + valueAdjust sensorAdjusts; }; } // namespace sensor |