Use exprtk expression parser
Using expression parser tool exprtk to calculate sensor value
from given expression from config file.
Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
Change-Id: Ie765748374a2c7a82ab9689b57c63fce7b015364
diff --git a/meson.build b/meson.build
index 4258e5e..6de3ea0 100644
--- a/meson.build
+++ b/meson.build
@@ -7,6 +7,17 @@
],
)
+cpp = meson.get_compiler('cpp')
+if cpp.has_header('exprtk.hpp')
+ exprtk = declare_dependency()
+else
+ subproject('exprtk', required: false)
+ exprtk = declare_dependency(
+ include_directories: 'subprojects/exprtk'
+ )
+endif
+
+
executable(
'virtual-sensor',
[
@@ -17,6 +28,7 @@
dependency('sdbusplus'),
dependency('phosphor-dbus-interfaces'),
dependency('sdeventplus'),
+ exprtk,
],
install: true,
install_dir: get_option('bindir')
diff --git a/subprojects/exprtk.wrap b/subprojects/exprtk.wrap
new file mode 100644
index 0000000..4143d1f
--- /dev/null
+++ b/subprojects/exprtk.wrap
@@ -0,0 +1,3 @@
+[wrap-git]
+revision = 281c2ccc65b8f91c012ea3725ebcef406378a225
+url = https://github.com/ArashPartow/exprtk.git
diff --git a/virtualSensor.cpp b/virtualSensor.cpp
index 501d9cd..ac5e123 100644
--- a/virtualSensor.cpp
+++ b/virtualSensor.cpp
@@ -84,7 +84,9 @@
if (j.find("ParamName") != j.end())
{
auto paramPtr = std::make_unique<SensorParam>(j["Value"]);
- paramMap.emplace(j["ParamName"], std::move(paramPtr));
+ std::string name = j["ParamName"];
+ symbols.create_variable(name);
+ paramMap.emplace(std::move(name), std::move(paramPtr));
}
else
{
@@ -114,12 +116,21 @@
objPath += sensorType + "/" + name;
auto paramPtr = std::make_unique<SensorParam>(bus, objPath);
- paramMap.emplace(j["ParamName"], std::move(paramPtr));
+ std::string name = j["ParamName"];
+ symbols.create_variable(name);
+ paramMap.emplace(std::move(name), std::move(paramPtr));
}
}
}
}
+ symbols.add_constants();
+ expression.register_symbol_table(symbols);
+
+ /* parser from exprtk */
+ exprtk::parser<double> parser{};
+ parser.compile(exprStr, expression);
+
/* Print all parameters for debug purpose only */
if (DEBUG)
printParams(paramMap);
@@ -138,9 +149,27 @@
WarningInterface::warningLow(sensorThreshold.warningLow);
}
-/* TBD */
void VirtualSensor::updateVirtualSensor()
-{}
+{
+ for (auto& param : paramMap)
+ {
+ auto& name = param.first;
+ auto& data = param.second;
+ if (auto var = symbols.get_variable(name))
+ {
+ var->ref() = data->getParamValue();
+ }
+ else
+ {
+ /* Invalid parameter */
+ throw std::invalid_argument("ParamName not found in symbols");
+ }
+ }
+ double val = expression.value();
+ setSensorValue(val);
+ if (DEBUG)
+ std::cout << "Sensor value is " << val << "\n";
+}
/** @brief Parsing Virtual Sensor config JSON file */
Json VirtualSensors::parseConfigFile(const std::string configFile)
@@ -189,10 +218,12 @@
auto virtualSensorPtr =
std::make_unique<VirtualSensor>(bus, objPath.c_str(), j);
- virtualSensorsMap.emplace(name, std::move(virtualSensorPtr));
log<level::INFO>("Added a new virtual sensor",
entry("NAME = %s", name.c_str()));
+ virtualSensorPtr->updateVirtualSensor();
+ virtualSensorsMap.emplace(std::move(name),
+ std::move(virtualSensorPtr));
}
else
{
diff --git a/virtualSensor.hpp b/virtualSensor.hpp
index 6b11eb4..b632e15 100644
--- a/virtualSensor.hpp
+++ b/virtualSensor.hpp
@@ -1,4 +1,5 @@
#include "dbusSensor.hpp"
+#include "exprtk.hpp"
#include <nlohmann/json.hpp>
#include <sdbusplus/bus.hpp>
@@ -95,6 +96,8 @@
/** @brief Set sensor value */
void setSensorValue(double value);
+ /** @brief Update sensor at regular intrval */
+ void updateVirtualSensor();
/** @brief Map of list of parameters */
using ParamMap =
@@ -108,6 +111,10 @@
std::string exprStr;
/** @brief Sensor Threshold config values */
struct Threshold sensorThreshold;
+ /** @brief symbol table from exprtk */
+ exprtk::symbol_table<double> symbols{};
+ /** @brief expression from exprtk to calculate sensor value */
+ exprtk::expression<double> expression{};
/** @brief Read config from json object and initialize sensor data
* for each virtual sensor
@@ -115,8 +122,6 @@
void initVirtualSensor(const Json& sensorConfig);
/** @brief Set Sensor Threshold to D-bus at beginning */
void setSensorThreshold();
- /** @brief Update sensor at regular intrval */
- void updateVirtualSensor();
};
class VirtualSensors