diff options
author | James Feist <james.feist@linux.intel.com> | 2018-08-01 16:31:42 -0700 |
---|---|---|
committer | James Feist <james.feist@linux.intel.com> | 2018-10-22 09:18:28 -0700 |
commit | ee73f5bdd1996ee9d4f65ddbc69804ea0b1b59e9 (patch) | |
tree | 6563db6a97d9d3354aaffee8a0bcee6e9882e723 | |
parent | 0fe4cb34b5292a559693407ebc0b38645c6c19d6 (diff) | |
download | phosphor-hwmon-ee73f5bdd1996ee9d4f65ddbc69804ea0b1b59e9.tar.gz phosphor-hwmon-ee73f5bdd1996ee9d4f65ddbc69804ea0b1b59e9.zip |
Make hwmon work with double or int64 interface
Deduce type based on interface using decltype
and if it is double apply scale to the value.
Tested-by: Noticed that on dbus using busctl and debug
server that doubles were produced and scaled.
Also verifed that hwmon still produced int64_t values when
building with current phosphor-dbus-interfaces.
Change-Id: I00e21d5ef0ea6cee0eb30baa0b39cde95e7f4a86
Signed-off-by: James Feist <james.feist@linux.intel.com>
-rw-r--r-- | interface.hpp | 5 | ||||
-rw-r--r-- | mainloop.cpp | 16 | ||||
-rw-r--r-- | sensor.cpp | 28 | ||||
-rw-r--r-- | sensor.hpp | 15 | ||||
-rw-r--r-- | thresholds.hpp | 27 |
5 files changed, 71 insertions, 20 deletions
diff --git a/interface.hpp b/interface.hpp index e8ec28e..4b157dc 100644 --- a/interface.hpp +++ b/interface.hpp @@ -29,6 +29,11 @@ using StatusInterface = sdbusplus::xyz::openbmc_project::State::Decorator:: server::OperationalStatus; using StatusObject = ServerObject<StatusInterface>; +// I understand this seems like magic, but since decltype doesn't evaluate you +// can call nullptr https://stackoverflow.com/a/5580411/2784885 +using SensorValueType = + decltype((static_cast<ValueInterface*>(nullptr))->value()); + enum class InterfaceType { VALUE, diff --git a/mainloop.cpp b/mainloop.cpp index 3c6d232..81faa9b 100644 --- a/mainloop.cpp +++ b/mainloop.cpp @@ -214,10 +214,18 @@ std::optional<ObjectStateData> #endif } auto sensorValue = valueInterface->value(); - addThreshold<WarningObject>( - sensor.first.first, std::get<sensorID>(properties), sensorValue, info); - addThreshold<CriticalObject>( - sensor.first.first, std::get<sensorID>(properties), sensorValue, info); + int64_t scale = 0; + // scale the thresholds only if we're using doubles + if constexpr (std::is_same<SensorValueType, double>::value) + { + scale = sensorObj->getScale(); + } + addThreshold<WarningObject>(sensor.first.first, + std::get<sensorID>(properties), sensorValue, + info, scale); + addThreshold<CriticalObject>(sensor.first.first, + std::get<sensorID>(properties), sensorValue, + info, scale); auto target = addTarget<hwmon::FanSpeed>(sensor.first, ioAccess, _devPath, info); @@ -8,6 +8,7 @@ #include "sensorset.hpp" #include "sysfs.hpp" +#include <cmath> #include <cstring> #include <experimental/filesystem> #include <phosphor-logging/elog-errors.hpp> @@ -21,6 +22,19 @@ namespace sensor using namespace phosphor::logging; using namespace sdbusplus::xyz::openbmc_project::Common::Error; +// todo: this can be deleted once we move to double +// helper class to set the scale on the value iface only when it's available +template <typename T> +void setScale(T& iface, int64_t value, double) +{ +} +template <typename T> +void setScale(T& iface, int64_t value, int64_t) +{ + iface->scale(value); +} + +// todo: this can be simplified once we move to the double interface Sensor::Sensor(const SensorSet::key_type& sensor, const hwmonio::HwmonIO& ioAccess, const std::string& devPath) : sensor(sensor), @@ -84,7 +98,7 @@ void Sensor::addRemoveRCs(const std::string& rcList) } } -int64_t Sensor::adjustValue(int64_t value) +SensorValueType Sensor::adjustValue(SensorValueType value) { // Because read doesn't have an out pointer to store errors. // let's assume negative values are errors if they have this @@ -100,6 +114,11 @@ int64_t Sensor::adjustValue(int64_t value) value = static_cast<decltype(value)>( static_cast<double>(value) * sensorAdjusts.gain + sensorAdjusts.offset); + if constexpr (std::is_same<SensorValueType, double>::value) + { + value *= std::pow(10, scale); + } + return value; } @@ -113,7 +132,7 @@ std::shared_ptr<ValueObject> Sensor::addValue(const RetryIO& retryIO, auto& obj = std::get<Object>(info); auto& objPath = std::get<std::string>(info); - int64_t val = 0; + SensorValueType val = 0; std::shared_ptr<StatusObject> statusIface = nullptr; auto it = obj.find(InterfaceType::STATUS); if (it != obj.end()) @@ -145,7 +164,10 @@ std::shared_ptr<ValueObject> Sensor::addValue(const RetryIO& retryIO, if (hwmon::getAttributes(sensor.first, attrs)) { iface->unit(hwmon::getUnit(attrs)); - iface->scale(hwmon::getScale(attrs)); + + setScale(iface, hwmon::getScale(attrs), val); + + scale = hwmon::getScale(attrs); } auto maxValue = env::getEnv("MAXVALUE", sensor); @@ -73,7 +73,7 @@ class Sensor * * @return - Adjusted sensor value */ - int64_t adjustValue(int64_t value); + SensorValueType adjustValue(SensorValueType value); /** * @brief Add value interface and value property for sensor @@ -113,6 +113,16 @@ class Sensor */ void lockGpio(); + /** + * @brief Get the scale from the sensor. + * + * @return - Scale value + */ + inline int64_t getScale(void) + { + return scale; + } + private: /** @brief Sensor object's identifiers */ SensorSet::key_type sensor; @@ -131,6 +141,9 @@ class Sensor /** @brief default pause after unlocking gpio. */ static constexpr std::chrono::milliseconds pause{500}; + + /** @brief sensor scale from configuration. */ + int64_t scale; }; } // namespace sensor diff --git a/thresholds.hpp b/thresholds.hpp index 7e8dbf5..188dc76 100644 --- a/thresholds.hpp +++ b/thresholds.hpp @@ -1,6 +1,9 @@ #pragma once #include "env.hpp" +#include "interface.hpp" + +#include <cmath> /** @class Thresholds * @brief Threshold type traits. @@ -23,10 +26,10 @@ struct Thresholds<WarningObject> static constexpr InterfaceType type = InterfaceType::WARN; static constexpr const char* envLo = "WARNLO"; static constexpr const char* envHi = "WARNHI"; - static int64_t (WarningObject::*const setLo)(int64_t); - static int64_t (WarningObject::*const setHi)(int64_t); - static int64_t (WarningObject::*const getLo)() const; - static int64_t (WarningObject::*const getHi)() const; + static SensorValueType (WarningObject::*const setLo)(SensorValueType); + static SensorValueType (WarningObject::*const setHi)(SensorValueType); + static SensorValueType (WarningObject::*const getLo)() const; + static SensorValueType (WarningObject::*const getHi)() const; static bool (WarningObject::*const alarmLo)(bool); static bool (WarningObject::*const alarmHi)(bool); }; @@ -38,10 +41,10 @@ struct Thresholds<CriticalObject> static constexpr InterfaceType type = InterfaceType::CRIT; static constexpr const char* envLo = "CRITLO"; static constexpr const char* envHi = "CRITHI"; - static int64_t (CriticalObject::*const setLo)(int64_t); - static int64_t (CriticalObject::*const setHi)(int64_t); - static int64_t (CriticalObject::*const getLo)() const; - static int64_t (CriticalObject::*const getHi)() const; + static SensorValueType (CriticalObject::*const setLo)(SensorValueType); + static SensorValueType (CriticalObject::*const setHi)(SensorValueType); + static SensorValueType (CriticalObject::*const getLo)() const; + static SensorValueType (CriticalObject::*const getHi)() const; static bool (CriticalObject::*const alarmLo)(bool); static bool (CriticalObject::*const alarmHi)(bool); }; @@ -57,7 +60,7 @@ struct Thresholds<CriticalObject> * @param[in] value - The sensor reading to compare to thresholds. */ template <typename T> -void checkThresholds(std::any& iface, int64_t value) +void checkThresholds(std::any& iface, SensorValueType value) { auto realIface = std::any_cast<std::shared_ptr<T>>(iface); auto lo = (*realIface.*Thresholds<T>::getLo)(); @@ -80,7 +83,7 @@ void checkThresholds(std::any& iface, int64_t value) */ template <typename T> auto addThreshold(const std::string& sensorType, const std::string& sensorID, - int64_t value, ObjectInfo& info) + int64_t value, ObjectInfo& info, int64_t scale) { auto& objPath = std::get<std::string>(info); auto& obj = std::get<Object>(info); @@ -94,8 +97,8 @@ auto addThreshold(const std::string& sensorType, const std::string& sensorID, auto& bus = *std::get<sdbusplus::bus::bus*>(info); iface = std::make_shared<T>(bus, objPath.c_str(), deferSignals); - auto lo = stoll(tLo); - auto hi = stoll(tHi); + auto lo = stod(tLo) * std::pow(10, scale); + auto hi = stod(tHi) * std::pow(10, scale); (*iface.*Thresholds<T>::setLo)(lo); (*iface.*Thresholds<T>::setHi)(hi); (*iface.*Thresholds<T>::alarmLo)(value <= lo); |