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