Add double support for sensor interface

Add support for reading sensors that produce a double
as the value. Use a visitor to pull out the sensor value
so type doesn't matter.

Change-Id: I37c05e7077ead6f3084ab9704a1b2c62becb5e19
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/dbus/dbuspassive.cpp b/dbus/dbuspassive.cpp
index daeef62..da9b387 100644
--- a/dbus/dbuspassive.cpp
+++ b/dbus/dbuspassive.cpp
@@ -97,7 +97,7 @@
 int HandleSensorValue(sdbusplus::message::message& msg, DbusPassive* owner)
 {
     std::string msgSensor;
-    std::map<std::string, sdbusplus::message::variant<int64_t>> msgData;
+    std::map<std::string, sdbusplus::message::variant<int64_t, double>> msgData;
 
     msg.read(msgSensor, msgData);
 
@@ -106,10 +106,10 @@
         auto valPropMap = msgData.find("Value");
         if (valPropMap != msgData.end())
         {
-            int64_t rawValue = sdbusplus::message::variant_ns::get<int64_t>(
-                valPropMap->second);
+            double value = mapbox::util::apply_visitor(VariantToDoubleVisitor(),
+                                                       valPropMap->second);
 
-            double value = rawValue * std::pow(10, owner->getScale());
+            value *= std::pow(10, owner->getScale());
 
             owner->setValue(value);
         }
diff --git a/dbus/util.cpp b/dbus/util.cpp
index 91cc840..ffdfe1f 100644
--- a/dbus/util.cpp
+++ b/dbus/util.cpp
@@ -4,7 +4,7 @@
 #include "dbus/util.hpp"
 
 using Property = std::string;
-using Value = sdbusplus::message::variant<int64_t, std::string>;
+using Value = sdbusplus::message::variant<int64_t, double, std::string>;
 using PropertyMap = std::map<Property, Value>;
 
 /* TODO(venture): Basically all phosphor apps need this, maybe it should be a
@@ -69,12 +69,25 @@
     valueResponseMsg.read(propMap);
 
     // If no error was set, the values should all be there.
-    prop->unit = sdbusplus::message::variant_ns::get<std::string>(
-        propMap["Unit"]);
-    prop->scale = sdbusplus::message::variant_ns::get<int64_t>(
-        propMap["Scale"]);
-    prop->value = sdbusplus::message::variant_ns::get<int64_t>(
-        propMap["Value"]);
+    auto findUnit = propMap.find("Unit");
+    if (findUnit != propMap.end())
+    {
+        prop->unit =
+            sdbusplus::message::variant_ns::get<std::string>(findUnit->second);
+    }
+    auto findScale = propMap.find("Scale");
+    if (findScale != propMap.end())
+    {
+        prop->scale =
+            sdbusplus::message::variant_ns::get<int64_t>(findScale->second);
+    }
+    else
+    {
+        prop->scale = 0;
+    }
+
+    prop->value =
+        mapbox::util::apply_visitor(VariantToDoubleVisitor(), propMap["Value"]);
 
     return;
 }
diff --git a/dbus/util.hpp b/dbus/util.hpp
index 72cf4e3..5b1522f 100644
--- a/dbus/util.hpp
+++ b/dbus/util.hpp
@@ -5,7 +5,7 @@
 struct SensorProperties
 {
     int64_t scale;
-    int64_t value;
+    double value;
     std::string unit;
 };
 
@@ -76,3 +76,20 @@
         throw std::invalid_argument("Cannot translate type to float");
     }
 };
+
+struct VariantToDoubleVisitor
+{
+    template <typename T>
+    std::enable_if_t<std::is_arithmetic<T>::value, double>
+    operator()(const T &t) const
+    {
+        return static_cast<double>(t);
+    }
+
+    template <typename T>
+    std::enable_if_t<!std::is_arithmetic<T>::value, double>
+    operator()(const T &t) const
+    {
+        throw std::invalid_argument("Cannot translate type to double");
+    }
+};