#include "psu_manager.hpp" #include "utility.hpp" using namespace phosphor::logging; namespace phosphor { namespace power { namespace manager { PSUManager::PSUManager(sdbusplus::bus::bus& bus, const sdeventplus::Event& e, const std::string& configfile) : bus(bus) { // Parse out the JSON properties sys_properties properties; getJSONProperties(configfile, bus, properties, psus); using namespace sdeventplus; auto interval = std::chrono::milliseconds(1000); timer = std::make_unique>( e, std::bind(&PSUManager::analyze, this), interval); minPSUs = {properties.minPowerSupplies}; maxPSUs = {properties.maxPowerSupplies}; // Subscribe to power state changes powerService = util::getService(POWER_OBJ_PATH, POWER_IFACE, bus); powerOnMatch = std::make_unique( bus, sdbusplus::bus::match::rules::propertiesChanged(POWER_OBJ_PATH, POWER_IFACE), [this](auto& msg) { this->powerStateChanged(msg); }); initialize(); } void PSUManager::getJSONProperties( const std::string& path, sdbusplus::bus::bus& bus, sys_properties& p, std::vector>& psus) { nlohmann::json configFileJSON = util::loadJSONFromFile(path.c_str()); if (configFileJSON == nullptr) { throw std::runtime_error("Failed to load JSON configuration file"); } if (!configFileJSON.contains("SystemProperties")) { throw std::runtime_error("Missing required SystemProperties"); } if (!configFileJSON.contains("PowerSupplies")) { throw std::runtime_error("Missing required PowerSupplies"); } auto sysProps = configFileJSON["SystemProperties"]; if (sysProps.contains("MinPowerSupplies")) { p.minPowerSupplies = sysProps["MinPowerSupplies"]; } else { p.minPowerSupplies = 0; } if (sysProps.contains("MaxPowerSupplies")) { p.maxPowerSupplies = sysProps["MaxPowerSupplies"]; } else { p.maxPowerSupplies = 0; } for (auto psuJSON : configFileJSON["PowerSupplies"]) { if (psuJSON.contains("Inventory") && psuJSON.contains("Bus") && psuJSON.contains("Address")) { std::string invpath = psuJSON["Inventory"]; std::uint8_t i2cbus = psuJSON["Bus"]; std::string i2caddr = psuJSON["Address"]; auto psu = std::make_unique(bus, invpath, i2cbus, i2caddr); psus.emplace_back(std::move(psu)); } else { log("Insufficient PowerSupply properties"); } } if (psus.empty()) { throw std::runtime_error("No power supplies to monitor"); } } void PSUManager::powerStateChanged(sdbusplus::message::message& msg) { int32_t state = 0; std::string msgSensor; std::map> msgData; msg.read(msgSensor, msgData); // Check if it was the Present property that changed. auto valPropMap = msgData.find("state"); if (valPropMap != msgData.end()) { state = std::get(valPropMap->second); // Power is on when state=1. Clear faults. if (state) { powerOn = true; clearFaults(); } else { powerOn = false; } } } } // namespace manager } // namespace power } // namespace phosphor