1abcc94faSVijay Khemka #include "virtualSensor.hpp"
2abcc94faSVijay Khemka 
3abcc94faSVijay Khemka #include "config.hpp"
4abcc94faSVijay Khemka 
5ddc6dcd6SMatt Spinler #include <fmt/format.h>
6ddc6dcd6SMatt Spinler 
7abcc94faSVijay Khemka #include <phosphor-logging/log.hpp>
8abcc94faSVijay Khemka #include <sdeventplus/event.hpp>
9abcc94faSVijay Khemka 
10abcc94faSVijay Khemka #include <fstream>
11abcc94faSVijay Khemka #include <iostream>
12abcc94faSVijay Khemka 
13abcc94faSVijay Khemka static constexpr bool DEBUG = false;
14abcc94faSVijay Khemka static constexpr auto busName = "xyz.openbmc_project.VirtualSensor";
15abcc94faSVijay Khemka static constexpr auto sensorDbusPath = "/xyz/openbmc_project/sensors/";
16abcc94faSVijay Khemka static constexpr uint8_t defaultHighThreshold = 100;
17abcc94faSVijay Khemka static constexpr uint8_t defaultLowThreshold = 0;
18abcc94faSVijay Khemka 
19abcc94faSVijay Khemka using namespace phosphor::logging;
20abcc94faSVijay Khemka 
2151f898e2SVijay Khemka int handleDbusSignal(sd_bus_message* msg, void* usrData, sd_bus_error*)
2251f898e2SVijay Khemka {
2351f898e2SVijay Khemka     if (usrData == nullptr)
2451f898e2SVijay Khemka     {
2551f898e2SVijay Khemka         throw std::runtime_error("Invalid match");
2651f898e2SVijay Khemka     }
2751f898e2SVijay Khemka 
2851f898e2SVijay Khemka     auto sdbpMsg = sdbusplus::message::message(msg);
2951f898e2SVijay Khemka     std::string msgIfce;
3051f898e2SVijay Khemka     std::map<std::string, std::variant<int64_t, double, bool>> msgData;
3151f898e2SVijay Khemka 
3251f898e2SVijay Khemka     sdbpMsg.read(msgIfce, msgData);
3351f898e2SVijay Khemka 
3451f898e2SVijay Khemka     if (msgData.find("Value") != msgData.end())
3551f898e2SVijay Khemka     {
3651f898e2SVijay Khemka         using namespace phosphor::virtualSensor;
3751f898e2SVijay Khemka         VirtualSensor* obj = static_cast<VirtualSensor*>(usrData);
3851f898e2SVijay Khemka         // TODO(openbmc/phosphor-virtual-sensor#1): updateVirtualSensor should
3951f898e2SVijay Khemka         // be changed to take the information we got from the signal, to avoid
4051f898e2SVijay Khemka         // having to do numerous dbus queries.
4151f898e2SVijay Khemka         obj->updateVirtualSensor();
4251f898e2SVijay Khemka     }
4351f898e2SVijay Khemka     return 0;
4451f898e2SVijay Khemka }
4551f898e2SVijay Khemka 
46abcc94faSVijay Khemka namespace phosphor
47abcc94faSVijay Khemka {
48abcc94faSVijay Khemka namespace virtualSensor
49abcc94faSVijay Khemka {
50abcc94faSVijay Khemka 
51abcc94faSVijay Khemka void printParams(const VirtualSensor::ParamMap& paramMap)
52abcc94faSVijay Khemka {
53abcc94faSVijay Khemka     for (const auto& p : paramMap)
54abcc94faSVijay Khemka     {
55abcc94faSVijay Khemka         const auto& p1 = p.first;
56abcc94faSVijay Khemka         const auto& p2 = p.second;
57abcc94faSVijay Khemka         auto val = p2->getParamValue();
58abcc94faSVijay Khemka         std::cout << p1 << " = " << val << "\n";
59abcc94faSVijay Khemka     }
60abcc94faSVijay Khemka }
61abcc94faSVijay Khemka 
62abcc94faSVijay Khemka double SensorParam::getParamValue()
63abcc94faSVijay Khemka {
64abcc94faSVijay Khemka     switch (paramType)
65abcc94faSVijay Khemka     {
66abcc94faSVijay Khemka         case constParam:
67abcc94faSVijay Khemka             return value;
68abcc94faSVijay Khemka             break;
697452a867SVijay Khemka         case dbusParam:
707452a867SVijay Khemka             return dbusSensor->getSensorValue();
717452a867SVijay Khemka             break;
72abcc94faSVijay Khemka         default:
73abcc94faSVijay Khemka             throw std::invalid_argument("param type not supported");
74abcc94faSVijay Khemka     }
75abcc94faSVijay Khemka }
76abcc94faSVijay Khemka 
77abcc94faSVijay Khemka void VirtualSensor::initVirtualSensor(const Json& sensorConfig)
78abcc94faSVijay Khemka {
79abcc94faSVijay Khemka 
80abcc94faSVijay Khemka     static const Json empty{};
81abcc94faSVijay Khemka 
82abcc94faSVijay Khemka     /* Get threshold values if defined in config */
83abcc94faSVijay Khemka     auto threshold = sensorConfig.value("Threshold", empty);
84abcc94faSVijay Khemka     if (!threshold.empty())
85abcc94faSVijay Khemka     {
86c62a5548SVijay Khemka         Threshold sensorThreshold;
87abcc94faSVijay Khemka         sensorThreshold.criticalHigh =
88abcc94faSVijay Khemka             threshold.value("CriticalHigh", defaultHighThreshold);
89abcc94faSVijay Khemka         sensorThreshold.criticalLow =
90abcc94faSVijay Khemka             threshold.value("CriticalLow", defaultLowThreshold);
91abcc94faSVijay Khemka         sensorThreshold.warningHigh =
92abcc94faSVijay Khemka             threshold.value("WarningHigh", defaultHighThreshold);
93abcc94faSVijay Khemka         sensorThreshold.warningLow =
94abcc94faSVijay Khemka             threshold.value("WarningLow", defaultLowThreshold);
95abcc94faSVijay Khemka 
96abcc94faSVijay Khemka         /* Set threshold value to dbus */
97c62a5548SVijay Khemka         setSensorThreshold(sensorThreshold);
98c62a5548SVijay Khemka     }
99abcc94faSVijay Khemka 
100abcc94faSVijay Khemka     /* Get expression string */
101abcc94faSVijay Khemka     exprStr = sensorConfig.value("Expression", "");
102abcc94faSVijay Khemka 
103abcc94faSVijay Khemka     /* Get all the parameter listed in configuration */
104abcc94faSVijay Khemka     auto params = sensorConfig.value("Params", empty);
105abcc94faSVijay Khemka 
106abcc94faSVijay Khemka     /* Check for constant parameter */
107abcc94faSVijay Khemka     const auto& consParams = params.value("ConstParam", empty);
108abcc94faSVijay Khemka     if (!consParams.empty())
109abcc94faSVijay Khemka     {
110abcc94faSVijay Khemka         for (auto& j : consParams)
111abcc94faSVijay Khemka         {
112abcc94faSVijay Khemka             if (j.find("ParamName") != j.end())
113abcc94faSVijay Khemka             {
114abcc94faSVijay Khemka                 auto paramPtr = std::make_unique<SensorParam>(j["Value"]);
1153ed9a516SVijay Khemka                 std::string name = j["ParamName"];
1163ed9a516SVijay Khemka                 symbols.create_variable(name);
1173ed9a516SVijay Khemka                 paramMap.emplace(std::move(name), std::move(paramPtr));
118abcc94faSVijay Khemka             }
119abcc94faSVijay Khemka             else
120abcc94faSVijay Khemka             {
121abcc94faSVijay Khemka                 /* Invalid configuration */
122abcc94faSVijay Khemka                 throw std::invalid_argument(
123abcc94faSVijay Khemka                     "ParamName not found in configuration");
124abcc94faSVijay Khemka             }
125abcc94faSVijay Khemka         }
126abcc94faSVijay Khemka     }
127abcc94faSVijay Khemka 
1287452a867SVijay Khemka     /* Check for dbus parameter */
1297452a867SVijay Khemka     auto dbusParams = params.value("DbusParam", empty);
1307452a867SVijay Khemka     if (!dbusParams.empty())
1317452a867SVijay Khemka     {
1327452a867SVijay Khemka         for (auto& j : dbusParams)
1337452a867SVijay Khemka         {
1347452a867SVijay Khemka             /* Get parameter dbus sensor descriptor */
1357452a867SVijay Khemka             auto desc = j.value("Desc", empty);
1367452a867SVijay Khemka             if ((!desc.empty()) && (j.find("ParamName") != j.end()))
1377452a867SVijay Khemka             {
1387452a867SVijay Khemka                 std::string sensorType = desc.value("SensorType", "");
1397452a867SVijay Khemka                 std::string name = desc.value("Name", "");
1407452a867SVijay Khemka 
1417452a867SVijay Khemka                 if (!sensorType.empty() && !name.empty())
1427452a867SVijay Khemka                 {
1437452a867SVijay Khemka                     std::string objPath(sensorDbusPath);
1447452a867SVijay Khemka                     objPath += sensorType + "/" + name;
1457452a867SVijay Khemka 
14651f898e2SVijay Khemka                     auto paramPtr =
14751f898e2SVijay Khemka                         std::make_unique<SensorParam>(bus, objPath, this);
1483ed9a516SVijay Khemka                     std::string name = j["ParamName"];
1493ed9a516SVijay Khemka                     symbols.create_variable(name);
1503ed9a516SVijay Khemka                     paramMap.emplace(std::move(name), std::move(paramPtr));
1517452a867SVijay Khemka                 }
1527452a867SVijay Khemka             }
1537452a867SVijay Khemka         }
1547452a867SVijay Khemka     }
155abcc94faSVijay Khemka 
1563ed9a516SVijay Khemka     symbols.add_constants();
157*9f1ef4f5SMatt Spinler     symbols.add_package(vecopsPackage);
1583ed9a516SVijay Khemka     expression.register_symbol_table(symbols);
1593ed9a516SVijay Khemka 
1603ed9a516SVijay Khemka     /* parser from exprtk */
1613ed9a516SVijay Khemka     exprtk::parser<double> parser{};
162ddc6dcd6SMatt Spinler     if (!parser.compile(exprStr, expression))
163ddc6dcd6SMatt Spinler     {
164ddc6dcd6SMatt Spinler         log<level::ERR>("Expression compilation failed");
165ddc6dcd6SMatt Spinler 
166ddc6dcd6SMatt Spinler         for (std::size_t i = 0; i < parser.error_count(); ++i)
167ddc6dcd6SMatt Spinler         {
168ddc6dcd6SMatt Spinler             auto error = parser.get_error(i);
169ddc6dcd6SMatt Spinler 
170ddc6dcd6SMatt Spinler             log<level::ERR>(
171ddc6dcd6SMatt Spinler                 fmt::format(
172ddc6dcd6SMatt Spinler                     "Position: {} Type: {} Message: {}", error.token.position,
173ddc6dcd6SMatt Spinler                     exprtk::parser_error::to_str(error.mode), error.diagnostic)
174ddc6dcd6SMatt Spinler                     .c_str());
175ddc6dcd6SMatt Spinler         }
176ddc6dcd6SMatt Spinler         throw std::runtime_error("Expression compilation failed");
177ddc6dcd6SMatt Spinler     }
1783ed9a516SVijay Khemka 
179abcc94faSVijay Khemka     /* Print all parameters for debug purpose only */
180abcc94faSVijay Khemka     if (DEBUG)
181abcc94faSVijay Khemka         printParams(paramMap);
182abcc94faSVijay Khemka }
183abcc94faSVijay Khemka 
184abcc94faSVijay Khemka void VirtualSensor::setSensorValue(double value)
185abcc94faSVijay Khemka {
186abcc94faSVijay Khemka     ValueIface::value(value);
187abcc94faSVijay Khemka }
188abcc94faSVijay Khemka 
189c62a5548SVijay Khemka void VirtualSensor::setSensorThreshold(Threshold& sensorThreshold)
190abcc94faSVijay Khemka {
191abcc94faSVijay Khemka     CriticalInterface::criticalHigh(sensorThreshold.criticalHigh);
192abcc94faSVijay Khemka     CriticalInterface::criticalLow(sensorThreshold.criticalLow);
193abcc94faSVijay Khemka     WarningInterface::warningHigh(sensorThreshold.warningHigh);
194abcc94faSVijay Khemka     WarningInterface::warningLow(sensorThreshold.warningLow);
195abcc94faSVijay Khemka }
196abcc94faSVijay Khemka 
19732a7156bSVijay Khemka void VirtualSensor::checkSensorThreshold(const double value)
19832a7156bSVijay Khemka {
19932a7156bSVijay Khemka     auto criticalHigh = CriticalInterface::criticalHigh();
20032a7156bSVijay Khemka     auto criticalLow = CriticalInterface::criticalLow();
20132a7156bSVijay Khemka     auto warningHigh = WarningInterface::warningHigh();
20232a7156bSVijay Khemka     auto warningLow = WarningInterface::warningLow();
20332a7156bSVijay Khemka 
20432a7156bSVijay Khemka     if (value > criticalHigh)
20532a7156bSVijay Khemka     {
20632a7156bSVijay Khemka         if (!CriticalInterface::criticalAlarmHigh())
20732a7156bSVijay Khemka         {
20832a7156bSVijay Khemka             CriticalInterface::criticalAlarmHigh(true);
20932a7156bSVijay Khemka             log<level::ERR>("ASSERT: Virtual Sensor has exceeded "
21032a7156bSVijay Khemka                             "critical high threshold",
21132a7156bSVijay Khemka                             entry("NAME = %s", name.c_str()));
21232a7156bSVijay Khemka         }
21332a7156bSVijay Khemka         return;
21432a7156bSVijay Khemka     }
21532a7156bSVijay Khemka 
21632a7156bSVijay Khemka     if (CriticalInterface::criticalAlarmHigh())
21732a7156bSVijay Khemka     {
21832a7156bSVijay Khemka         CriticalInterface::criticalAlarmHigh(false);
21932a7156bSVijay Khemka         log<level::INFO>("DEASSERT: Virtual Sensor is under "
22032a7156bSVijay Khemka                          "critical high threshold",
22132a7156bSVijay Khemka                          entry("NAME = %s", name.c_str()));
22232a7156bSVijay Khemka     }
22332a7156bSVijay Khemka 
22432a7156bSVijay Khemka     if (value > warningHigh)
22532a7156bSVijay Khemka     {
22632a7156bSVijay Khemka         if (!WarningInterface::warningAlarmHigh())
22732a7156bSVijay Khemka         {
22832a7156bSVijay Khemka             WarningInterface::warningAlarmHigh(true);
22932a7156bSVijay Khemka             log<level::ERR>("ASSERT: Virtual Sensor has exceeded "
23032a7156bSVijay Khemka                             "warning high threshold",
23132a7156bSVijay Khemka                             entry("NAME = %s", name.c_str()));
23232a7156bSVijay Khemka         }
23332a7156bSVijay Khemka         return;
23432a7156bSVijay Khemka     }
23532a7156bSVijay Khemka 
23632a7156bSVijay Khemka     if (WarningInterface::warningAlarmHigh())
23732a7156bSVijay Khemka     {
23832a7156bSVijay Khemka         WarningInterface::warningAlarmHigh(false);
23932a7156bSVijay Khemka         log<level::INFO>("DEASSERT: Virtual Sensor is under "
24032a7156bSVijay Khemka                          "warning high threshold",
24132a7156bSVijay Khemka                          entry("NAME = %s", name.c_str()));
24232a7156bSVijay Khemka     }
24332a7156bSVijay Khemka 
24432a7156bSVijay Khemka     if (value < criticalLow)
24532a7156bSVijay Khemka     {
24632a7156bSVijay Khemka         if (!CriticalInterface::criticalAlarmLow())
24732a7156bSVijay Khemka         {
24832a7156bSVijay Khemka             CriticalInterface::criticalAlarmLow(true);
24932a7156bSVijay Khemka             log<level::ERR>("ASSERT: Virtual Sensor is under "
25032a7156bSVijay Khemka                             "critical low threshold",
25132a7156bSVijay Khemka                             entry("NAME = %s", name.c_str()));
25232a7156bSVijay Khemka         }
25332a7156bSVijay Khemka         return;
25432a7156bSVijay Khemka     }
25532a7156bSVijay Khemka 
25632a7156bSVijay Khemka     if (CriticalInterface::criticalAlarmLow())
25732a7156bSVijay Khemka     {
25832a7156bSVijay Khemka         CriticalInterface::criticalAlarmLow(false);
25932a7156bSVijay Khemka         log<level::ERR>("DEASSERT: Virtual Sensor is above "
26032a7156bSVijay Khemka                         "critical low threshold",
26132a7156bSVijay Khemka                         entry("NAME = %s", name.c_str()));
26232a7156bSVijay Khemka     }
26332a7156bSVijay Khemka 
26432a7156bSVijay Khemka     if (value < warningLow)
26532a7156bSVijay Khemka     {
26632a7156bSVijay Khemka         if (!WarningInterface::warningAlarmLow())
26732a7156bSVijay Khemka         {
26832a7156bSVijay Khemka             WarningInterface::warningAlarmLow(true);
26932a7156bSVijay Khemka             log<level::ERR>("ASSERT: Virtual Sensor is under "
27032a7156bSVijay Khemka                             "warning low threshold",
27132a7156bSVijay Khemka                             entry("NAME = %s", name.c_str()));
27232a7156bSVijay Khemka         }
27332a7156bSVijay Khemka         return;
27432a7156bSVijay Khemka     }
27532a7156bSVijay Khemka 
27632a7156bSVijay Khemka     if (WarningInterface::warningAlarmLow())
27732a7156bSVijay Khemka     {
27832a7156bSVijay Khemka         WarningInterface::warningAlarmLow(false);
27932a7156bSVijay Khemka         log<level::ERR>("DEASSERT: Virtual Sensor is above "
28032a7156bSVijay Khemka                         "warning low threshold",
28132a7156bSVijay Khemka                         entry("NAME = %s", name.c_str()));
28232a7156bSVijay Khemka     }
28332a7156bSVijay Khemka }
28432a7156bSVijay Khemka 
285abcc94faSVijay Khemka void VirtualSensor::updateVirtualSensor()
2863ed9a516SVijay Khemka {
2873ed9a516SVijay Khemka     for (auto& param : paramMap)
2883ed9a516SVijay Khemka     {
2893ed9a516SVijay Khemka         auto& name = param.first;
2903ed9a516SVijay Khemka         auto& data = param.second;
2913ed9a516SVijay Khemka         if (auto var = symbols.get_variable(name))
2923ed9a516SVijay Khemka         {
2933ed9a516SVijay Khemka             var->ref() = data->getParamValue();
2943ed9a516SVijay Khemka         }
2953ed9a516SVijay Khemka         else
2963ed9a516SVijay Khemka         {
2973ed9a516SVijay Khemka             /* Invalid parameter */
2983ed9a516SVijay Khemka             throw std::invalid_argument("ParamName not found in symbols");
2993ed9a516SVijay Khemka         }
3003ed9a516SVijay Khemka     }
3013ed9a516SVijay Khemka     double val = expression.value();
30232a7156bSVijay Khemka 
30332a7156bSVijay Khemka     /* Set sensor value to dbus interface */
3043ed9a516SVijay Khemka     setSensorValue(val);
30532a7156bSVijay Khemka 
3063ed9a516SVijay Khemka     if (DEBUG)
3073ed9a516SVijay Khemka         std::cout << "Sensor value is " << val << "\n";
30832a7156bSVijay Khemka 
30932a7156bSVijay Khemka     /* Check sensor threshold and log required message */
31032a7156bSVijay Khemka     checkSensorThreshold(val);
3113ed9a516SVijay Khemka }
312abcc94faSVijay Khemka 
313abcc94faSVijay Khemka /** @brief Parsing Virtual Sensor config JSON file  */
314abcc94faSVijay Khemka Json VirtualSensors::parseConfigFile(const std::string configFile)
315abcc94faSVijay Khemka {
316abcc94faSVijay Khemka     std::ifstream jsonFile(configFile);
317abcc94faSVijay Khemka     if (!jsonFile.is_open())
318abcc94faSVijay Khemka     {
319abcc94faSVijay Khemka         log<level::ERR>("config JSON file not found",
320abcc94faSVijay Khemka                         entry("FILENAME = %s", configFile.c_str()));
321abcc94faSVijay Khemka         throw std::exception{};
322abcc94faSVijay Khemka     }
323abcc94faSVijay Khemka 
324abcc94faSVijay Khemka     auto data = Json::parse(jsonFile, nullptr, false);
325abcc94faSVijay Khemka     if (data.is_discarded())
326abcc94faSVijay Khemka     {
327abcc94faSVijay Khemka         log<level::ERR>("config readings JSON parser failure",
328abcc94faSVijay Khemka                         entry("FILENAME = %s", configFile.c_str()));
329abcc94faSVijay Khemka         throw std::exception{};
330abcc94faSVijay Khemka     }
331abcc94faSVijay Khemka 
332abcc94faSVijay Khemka     return data;
333abcc94faSVijay Khemka }
334abcc94faSVijay Khemka 
335e0d371e4SVijay Khemka std::map<std::string, ValueIface::Unit> unitMap = {
336e0d371e4SVijay Khemka     {"temperature", ValueIface::Unit::DegreesC},
337e0d371e4SVijay Khemka     {"fan_tach", ValueIface::Unit::RPMS},
338e0d371e4SVijay Khemka     {"voltage", ValueIface::Unit::Volts},
339e0d371e4SVijay Khemka     {"altitude", ValueIface::Unit::Meters},
340e0d371e4SVijay Khemka     {"current", ValueIface::Unit::Amperes},
341e0d371e4SVijay Khemka     {"power", ValueIface::Unit::Watts},
342e0d371e4SVijay Khemka     {"energy", ValueIface::Unit::Joules},
343e0d371e4SVijay Khemka     {"utilization", ValueIface::Unit::Percent}};
344e0d371e4SVijay Khemka 
345abcc94faSVijay Khemka void VirtualSensors::createVirtualSensors()
346abcc94faSVijay Khemka {
347abcc94faSVijay Khemka     static const Json empty{};
348abcc94faSVijay Khemka 
349abcc94faSVijay Khemka     auto data = parseConfigFile(VIRTUAL_SENSOR_CONFIG_FILE);
350abcc94faSVijay Khemka     // print values
351abcc94faSVijay Khemka     if (DEBUG)
352abcc94faSVijay Khemka         std::cout << "Config json data:\n" << data << "\n\n";
353abcc94faSVijay Khemka 
354abcc94faSVijay Khemka     /* Get virtual sensors  config data */
355abcc94faSVijay Khemka     for (const auto& j : data)
356abcc94faSVijay Khemka     {
357abcc94faSVijay Khemka         auto desc = j.value("Desc", empty);
358abcc94faSVijay Khemka         if (!desc.empty())
359abcc94faSVijay Khemka         {
360abcc94faSVijay Khemka             std::string sensorType = desc.value("SensorType", "");
361abcc94faSVijay Khemka             std::string name = desc.value("Name", "");
362abcc94faSVijay Khemka 
363abcc94faSVijay Khemka             if (!name.empty() && !sensorType.empty())
364abcc94faSVijay Khemka             {
365e0d371e4SVijay Khemka                 if (unitMap.find(sensorType) == unitMap.end())
366e0d371e4SVijay Khemka                 {
367e0d371e4SVijay Khemka                     log<level::ERR>("Sensor type is not supported",
368e0d371e4SVijay Khemka                                     entry("TYPE = %s", sensorType.c_str()));
369e0d371e4SVijay Khemka                 }
370e0d371e4SVijay Khemka                 else
371e0d371e4SVijay Khemka                 {
372abcc94faSVijay Khemka                     std::string objPath(sensorDbusPath);
373abcc94faSVijay Khemka                     objPath += sensorType + "/" + name;
374abcc94faSVijay Khemka 
37532a7156bSVijay Khemka                     auto virtualSensorPtr = std::make_unique<VirtualSensor>(
37632a7156bSVijay Khemka                         bus, objPath.c_str(), j, name);
377abcc94faSVijay Khemka 
378abcc94faSVijay Khemka                     log<level::INFO>("Added a new virtual sensor",
379abcc94faSVijay Khemka                                      entry("NAME = %s", name.c_str()));
3803ed9a516SVijay Khemka                     virtualSensorPtr->updateVirtualSensor();
381e0d371e4SVijay Khemka 
382e0d371e4SVijay Khemka                     /* Initialize unit value for virtual sensor */
383e0d371e4SVijay Khemka                     virtualSensorPtr->ValueIface::unit(unitMap[sensorType]);
384e0d371e4SVijay Khemka 
3853ed9a516SVijay Khemka                     virtualSensorsMap.emplace(std::move(name),
3863ed9a516SVijay Khemka                                               std::move(virtualSensorPtr));
387abcc94faSVijay Khemka                 }
388e0d371e4SVijay Khemka             }
389abcc94faSVijay Khemka             else
390abcc94faSVijay Khemka             {
391abcc94faSVijay Khemka                 log<level::ERR>("Sensor type or name not found in config file");
392abcc94faSVijay Khemka             }
393abcc94faSVijay Khemka         }
394abcc94faSVijay Khemka         else
395abcc94faSVijay Khemka         {
396abcc94faSVijay Khemka             log<level::ERR>(
397abcc94faSVijay Khemka                 "Descriptor for new virtual sensor not found in config file");
398abcc94faSVijay Khemka         }
399abcc94faSVijay Khemka     }
400abcc94faSVijay Khemka }
401abcc94faSVijay Khemka 
402abcc94faSVijay Khemka } // namespace virtualSensor
403abcc94faSVijay Khemka } // namespace phosphor
404abcc94faSVijay Khemka 
405abcc94faSVijay Khemka /**
406abcc94faSVijay Khemka  * @brief Main
407abcc94faSVijay Khemka  */
408abcc94faSVijay Khemka int main()
409abcc94faSVijay Khemka {
410abcc94faSVijay Khemka 
411abcc94faSVijay Khemka     // Get a default event loop
412abcc94faSVijay Khemka     auto event = sdeventplus::Event::get_default();
413abcc94faSVijay Khemka 
414abcc94faSVijay Khemka     // Get a handle to system dbus
415abcc94faSVijay Khemka     auto bus = sdbusplus::bus::new_default();
416abcc94faSVijay Khemka 
417abcc94faSVijay Khemka     // Create an virtual sensors object
418abcc94faSVijay Khemka     phosphor::virtualSensor::VirtualSensors virtualSensors(bus);
419abcc94faSVijay Khemka 
420abcc94faSVijay Khemka     // Request service bus name
421abcc94faSVijay Khemka     bus.request_name(busName);
422abcc94faSVijay Khemka 
423abcc94faSVijay Khemka     // Attach the bus to sd_event to service user requests
424abcc94faSVijay Khemka     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
425abcc94faSVijay Khemka     event.loop();
426abcc94faSVijay Khemka 
427abcc94faSVijay Khemka     return 0;
428abcc94faSVijay Khemka }
429