summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Feist <james.feist@linux.intel.com>2018-08-01 16:31:42 -0700
committerJames Feist <james.feist@linux.intel.com>2018-10-22 09:18:28 -0700
commitee73f5bdd1996ee9d4f65ddbc69804ea0b1b59e9 (patch)
tree6563db6a97d9d3354aaffee8a0bcee6e9882e723
parent0fe4cb34b5292a559693407ebc0b38645c6c19d6 (diff)
downloadphosphor-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.hpp5
-rw-r--r--mainloop.cpp16
-rw-r--r--sensor.cpp28
-rw-r--r--sensor.hpp15
-rw-r--r--thresholds.hpp27
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);
diff --git a/sensor.cpp b/sensor.cpp
index 0a0971f..5c97e0c 100644
--- a/sensor.cpp
+++ b/sensor.cpp
@@ -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);
diff --git a/sensor.hpp b/sensor.hpp
index 3f38c33..37cf035 100644
--- a/sensor.hpp
+++ b/sensor.hpp
@@ -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);
OpenPOWER on IntegriCloud