Support sensor value property to type double
Constructed an intermediate function that is used to apply a visitor
against the `xyz.openbmc_project.Sensor.Value` interface's `Value`
property. This function is called to apply the visitor at each point the
internally cached sensor value is updated and stores it as the data type
that is given for this property within the configured yaml.
The visitor provides storing the sensor value directly where the data
type configured matches the data type of the `Value` property on dbus.
However, in the case where the configured data type is the original
int64 and the data type on dbus is double, the visitor will scale the
value from dbus to millidegree C(as it was when stored as an int64 on
dbus) and cast it to the configured int64 data type. This resulting cast
value is stored within the internal cache now as an int64 until the
machine configuration yaml file is updated to reflect the change in the
sensor's value data type to be a double.
Tested:
No change with use of sensor value as int64 and configured as int64
No change with use of sensor value as double and configured as int64
Witherspoon fan control functions correctly with use of sensor value
as double and configuration updated to utilize as a double
Change-Id: Ieb0a646ea37bf7991b9b1f94a85977d9e8984e60
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/zone.hpp b/control/zone.hpp
index 6982508..36fdb54 100644
--- a/control/zone.hpp
+++ b/control/zone.hpp
@@ -221,6 +221,64 @@
};
/**
+ * @brief Get a property's value after applying a set of visitors
+ * to translate the property value's type change to keep from
+ * affecting the configured use of the property.
+ *
+ * @param[in] intf = Interface name containing the property
+ * @param[in] prop = Property name
+ * @param[in] variant = Variant containing the property's value from
+ * the supported property types.
+ */
+ template <typename T>
+ inline auto getPropertyValueVisitor(
+ const char* intf,
+ const char* prop,
+ PropertyVariantType& variant)
+ {
+ T value;
+
+ // Handle the transition of the dbus sensor value type from
+ // int64 to double which also removed the scale property.
+ // https://gerrit.openbmc-project.xyz/11739
+ if (strcmp(intf, "xyz.openbmc_project.Sensor.Value") == 0 &&
+ strcmp(prop, "Value") == 0)
+ {
+ std::visit([&value](auto&& val)
+ {
+ // If the type configured is int64, but the sensor value
+ // property's type is double, scale it by 1000 and return
+ // the value as an int64 as configured.
+ using V = std::decay_t<decltype(val)>;
+ if constexpr(std::is_same_v<T, int64_t> &&
+ std::is_same_v<V, double>)
+ {
+ val = val * 1000;
+ value = static_cast<T>(val);
+ }
+ // If the type configured matches the sensor value
+ // property's type, just return the value as its
+ // given type.
+ else if constexpr((std::is_same_v<T, int64_t> &&
+ std::is_same_v<V, int64_t>) ||
+ (std::is_same_v<T, double> &&
+ std::is_same_v<V, double>))
+ {
+ value = val;
+ }
+ }, variant);
+
+ return value;
+ }
+
+ // Default to return the property's value by the data type
+ // configured, applying no visitors to the variant.
+ value = std::get<T>(variant);
+
+ return value;
+ };
+
+ /**
* @brief Remove an object's interface
*
* @param[in] object - Name of the object with the interface
@@ -598,12 +656,13 @@
}
}
+ // Retrieve the property's value applying any visitors necessary
auto service = getService(path, intf);
- value = util::SDBusPlus::getProperty<T>(_bus,
- service,
- path,
- intf,
- prop);
+ auto variant =
+ util::SDBusPlus::getPropertyVariant<PropertyVariantType>(
+ _bus, service, path, intf, prop);
+ value = getPropertyValueVisitor<T>(
+ intf.c_str(), prop.c_str(), variant);
return value;
};