diff options
author | Eddie James <eajames@linux.ibm.com> | 2019-05-18 00:24:36 +0300 |
---|---|---|
committer | Edward A. James <eajames@us.ibm.com> | 2019-06-05 18:57:53 +0300 |
commit | 028f7ebc6626f6b95251ce52a9ed9ed053e48a3e (patch) | |
tree | 9f41c94dc27c4d036b36a5917b11d1451ffef226 /redfish-core/lib/power.hpp | |
parent | 57bff08a75362a05d36354918195c5b7c82006f1 (diff) | |
download | bmcweb-028f7ebc6626f6b95251ce52a9ed9ed053e48a3e.tar.xz |
Add basic PowerControl and PowerLimit properties
Add code in the power-specific response handler to fetch the Power Limit
value for the chassis that implements the Chassis inventory item. Add a
special case to the generic sensor handling code to place the
total_power value into the PowerControl PowerConsumedWatts field.
curl -k https://${bmc}/redfish/v1/Chassis/chassis/Power
{
"@odata.context": "/redfish/v1/$metadata#Power.Power",
"@odata.id": "/redfish/v1/Chassis/chassis/Power",
"@odata.type": "#Power.v1_5_2.Power",
"Id": "Power",
"Name": "Power",
"PowerControl": [
{
"@odata.id": "/redfish/v1/Chassis/chassis/Power#/PowerControl/",
"MemberId": "total_power",
"Name": "total power",
"PowerConsumedWatts": 269.0,
"Status": {
"Health": "OK",
"State": "Enabled"
}
}
],
"PowerLimit": [
{
"LimitInWatts": null
}
],
Signed-off-by: Eddie James <eajames@linux.ibm.com>
Change-Id: I447de59fb44a4ecbe7b47610d915ac22aef90250
Diffstat (limited to 'redfish-core/lib/power.hpp')
-rw-r--r-- | redfish-core/lib/power.hpp | 157 |
1 files changed, 156 insertions, 1 deletions
diff --git a/redfish-core/lib/power.hpp b/redfish-core/lib/power.hpp index 218411424d..b5951d5a73 100644 --- a/redfish-core/lib/power.hpp +++ b/redfish-core/lib/power.hpp @@ -54,8 +54,163 @@ class Power : public Node auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>( res, chassis_name, typeList, "Power"); - // TODO Need to retrieve Power Control information. + getChassisData(sensorAsyncResp); + + // This callback verifies that the power limit is only provided for the + // chassis that implements the Chassis inventory item. This prevents + // things like power supplies providing the chassis power limit + auto chassisHandler = [sensorAsyncResp]( + const boost::system::error_code ec, + const std::vector<std::string>& + chassisPaths) { + if (ec) + { + BMCWEB_LOG_ERROR + << "Power Limit GetSubTreePaths handler Dbus error " << ec; + return; + } + + bool found = false; + for (const std::string& chassis : chassisPaths) + { + size_t len = std::string::npos; + size_t lastPos = chassis.rfind("/"); + if (lastPos == std::string::npos) + { + continue; + } + + if (lastPos == chassis.size() - 1) + { + size_t end = lastPos; + lastPos = chassis.rfind("/", lastPos - 1); + if (lastPos == std::string::npos) + { + continue; + } + + len = end - (lastPos + 1); + } + + std::string interfaceChassisName = + chassis.substr(lastPos + 1, len); + if (!interfaceChassisName.compare(sensorAsyncResp->chassisId)) + { + found = true; + break; + } + } + + if (!found) + { + BMCWEB_LOG_DEBUG << "Power Limit not present for " + << sensorAsyncResp->chassisId; + return; + } + + auto valueHandler = + [sensorAsyncResp]( + const boost::system::error_code ec, + const std::vector<std::pair<std::string, SensorVariant>>& + properties) { + if (ec) + { + messages::internalError(sensorAsyncResp->res); + BMCWEB_LOG_ERROR + << "Power Limit GetAll handler: Dbus error " << ec; + return; + } + + nlohmann::json& tempArray = + sensorAsyncResp->res.jsonValue["PowerLimit"]; + + if (tempArray.empty()) + { + tempArray.push_back({}); + } + + nlohmann::json& sensorJson = tempArray.back(); + bool enabled = false; + double powerCap = 0.0; + int64_t scale = 0; + + for (const std::pair<std::string, SensorVariant>& property : + properties) + { + if (!property.first.compare("Scale")) + { + const int64_t* i = + sdbusplus::message::variant_ns::get_if<int64_t>( + &property.second); + + if (i) + { + scale = *i; + } + } + else if (!property.first.compare("PowerCap")) + { + const double* d = + sdbusplus::message::variant_ns::get_if<double>( + &property.second); + const int64_t* i = + sdbusplus::message::variant_ns::get_if<int64_t>( + &property.second); + const uint32_t* u = + sdbusplus::message::variant_ns::get_if< + uint32_t>(&property.second); + + if (d) + { + powerCap = *d; + } + else if (i) + { + powerCap = *i; + } + else if (u) + { + powerCap = *u; + } + } + else if (!property.first.compare("PowerCapEnable")) + { + const bool* b = + sdbusplus::message::variant_ns::get_if<bool>( + &property.second); + + if (b) + { + enabled = *b; + } + } + } + + nlohmann::json& value = sensorJson["LimitInWatts"]; + + if (enabled) + { + // Redfish specification indicates PowerLimit should be + // null if the limit is not enabled. + value = powerCap * std::pow(10, scale); + } + }; + + crow::connections::systemBus->async_method_call( + std::move(valueHandler), "xyz.openbmc_project.Settings", + "/xyz/openbmc_project/control/host0/power_cap", + "org.freedesktop.DBus.Properties", "GetAll", + "xyz.openbmc_project.Control.Power.Cap"); + }; + + crow::connections::systemBus->async_method_call( + std::move(chassisHandler), "xyz.openbmc_project.ObjectMapper", + "/xyz/openbmc_project/object_mapper", + "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", + "/xyz/openbmc_project/inventory", int32_t(0), + std::array<const char*, 1>{ + "xyz.openbmc_project.Inventory.Item.Chassis"}); } void doPatch(crow::Response& res, const crow::Request& req, const std::vector<std::string>& params) override |