summaryrefslogtreecommitdiff
path: root/redfish-core/lib/sensors.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'redfish-core/lib/sensors.hpp')
-rw-r--r--redfish-core/lib/sensors.hpp231
1 files changed, 224 insertions, 7 deletions
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index 12657835d8..628e6ff6b6 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -93,8 +93,8 @@ class InventoryItem
public:
InventoryItem(const std::string& objPath) :
objectPath(objPath), name(), isPresent(true), isFunctional(true),
- isPowerSupply(false), manufacturer(), model(), partNumber(),
- serialNumber(), sensors(), ledObjectPath(""),
+ isPowerSupply(false), powerSupplyEfficiencyPercent(-1), manufacturer(),
+ model(), partNumber(), serialNumber(), sensors(), ledObjectPath(""),
ledState(LedState::UNKNOWN)
{
// Set inventory item name to last node of object path
@@ -110,6 +110,7 @@ class InventoryItem
bool isPresent;
bool isFunctional;
bool isPowerSupply;
+ int powerSupplyEfficiencyPercent;
std::string manufacturer;
std::string model;
std::string partNumber;
@@ -1758,7 +1759,7 @@ static void getInventoryItemAssociations(
*
* The callback must have the following signature:
* @code
- * callback(std::shared_ptr<std::vector<InventoryItem>> inventoryItems)
+ * callback()
* @endcode
*
* This function is called recursively, obtaining data asynchronously from one
@@ -1785,7 +1786,7 @@ void getInventoryLedData(
// If no more connections left, call callback
if (ledConnectionsIndex >= ledConnections->size())
{
- callback(inventoryItems);
+ callback();
BMCWEB_LOG_DEBUG << "getInventoryLedData exit";
return;
}
@@ -1878,7 +1879,7 @@ void getInventoryLedData(
*
* The callback must have the following signature:
* @code
- * callback(std::shared_ptr<std::vector<InventoryItem>> inventoryItems)
+ * callback()
* @endcode
*
* @param sensorsAsyncResp Pointer to object holding response data.
@@ -1947,6 +1948,203 @@ void getInventoryLeds(
}
/**
+ * @brief Gets D-Bus data for Power Supply Attributes such as EfficiencyPercent
+ *
+ * Uses the specified connections (services) (currently assumes just one) to
+ * obtain D-Bus data for Power Supply Attributes. Stores the resulting data in
+ * the inventoryItems vector. Only stores data in Power Supply inventoryItems.
+ *
+ * This data is later used to provide sensor property values in the JSON
+ * response.
+ *
+ * Finds the Power Supply Attributes data asynchronously. Invokes callback
+ * when data has been obtained.
+ *
+ * The callback must have the following signature:
+ * @code
+ * callback(std::shared_ptr<std::vector<InventoryItem>> inventoryItems)
+ * @endcode
+ *
+ * @param sensorsAsyncResp Pointer to object holding response data.
+ * @param inventoryItems D-Bus inventory items associated with sensors.
+ * @param psAttributesConnections Connections that provide data for the Power
+ * Supply Attributes
+ * @param callback Callback to invoke when data has been obtained.
+ */
+template <typename Callback>
+void getPowerSupplyAttributesData(
+ std::shared_ptr<SensorsAsyncResp> sensorsAsyncResp,
+ std::shared_ptr<std::vector<InventoryItem>> inventoryItems,
+ const boost::container::flat_map<std::string, std::string>&
+ psAttributesConnections,
+ Callback&& callback)
+{
+ BMCWEB_LOG_DEBUG << "getPowerSupplyAttributesData enter";
+
+ if (psAttributesConnections.empty())
+ {
+ BMCWEB_LOG_DEBUG << "Can't find PowerSupplyAttributes, no connections!";
+ callback(inventoryItems);
+ return;
+ }
+
+ // Assuming just one connection (service) for now
+ auto it = psAttributesConnections.nth(0);
+
+ const std::string& psAttributesPath = (*it).first;
+ const std::string& psAttributesConnection = (*it).second;
+
+ // Response handler for Get DeratingFactor property
+ auto respHandler = [sensorsAsyncResp, inventoryItems,
+ callback{std::move(callback)}](
+ const boost::system::error_code ec,
+ const std::variant<uint32_t>& deratingFactor) {
+ BMCWEB_LOG_DEBUG << "getPowerSupplyAttributesData respHandler enter";
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR
+ << "getPowerSupplyAttributesData respHandler DBus error " << ec;
+ messages::internalError(sensorsAsyncResp->res);
+ return;
+ }
+
+ const uint32_t* value = std::get_if<uint32_t>(&deratingFactor);
+ if (value != nullptr)
+ {
+ BMCWEB_LOG_DEBUG << "PS EfficiencyPercent value: " << *value;
+ // Store value in Power Supply Inventory Items
+ for (InventoryItem& inventoryItem : *inventoryItems)
+ {
+ if (inventoryItem.isPowerSupply == true)
+ {
+ inventoryItem.powerSupplyEfficiencyPercent =
+ static_cast<int>(*value);
+ }
+ }
+ }
+ else
+ {
+ BMCWEB_LOG_DEBUG
+ << "Failed to find EfficiencyPercent value for PowerSupplies";
+ }
+
+ BMCWEB_LOG_DEBUG << "getPowerSupplyAttributesData respHandler exit";
+ callback(inventoryItems);
+ };
+
+ // Get the DeratingFactor property for the PowerSupplyAttributes
+ // Currently only property on the interface/only one we care about
+ crow::connections::systemBus->async_method_call(
+ std::move(respHandler), psAttributesConnection, psAttributesPath,
+ "org.freedesktop.DBus.Properties", "Get",
+ "xyz.openbmc_project.Control.PowerSupplyAttributes", "DeratingFactor");
+
+ BMCWEB_LOG_DEBUG << "getPowerSupplyAttributesData exit";
+}
+
+/**
+ * @brief Gets the Power Supply Attributes such as EfficiencyPercent
+ *
+ * Gets the D-Bus connection (service) that provides Power Supply Attributes
+ * data. Then gets the Power Supply Attributes data from the connection
+ * (currently just assumes 1 connection) and stores the data in the inventory
+ * item.
+ *
+ * This data is later used to provide sensor property values in the JSON
+ * response. DeratingFactor on D-Bus is mapped to EfficiencyPercent on Redfish.
+ *
+ * Finds the Power Supply Attributes data asynchronously. Invokes callback
+ * when information has been obtained.
+ *
+ * The callback must have the following signature:
+ * @code
+ * callback(std::shared_ptr<std::vector<InventoryItem>> inventoryItems)
+ * @endcode
+ *
+ * @param sensorsAsyncResp Pointer to object holding response data.
+ * @param inventoryItems D-Bus inventory items associated with sensors.
+ * @param callback Callback to invoke when data has been obtained.
+ */
+template <typename Callback>
+void getPowerSupplyAttributes(
+ std::shared_ptr<SensorsAsyncResp> sensorsAsyncResp,
+ std::shared_ptr<std::vector<InventoryItem>> inventoryItems,
+ Callback&& callback)
+{
+ BMCWEB_LOG_DEBUG << "getPowerSupplyAttributes enter";
+
+ // Only need the power supply attributes when the Power Schema
+ if (sensorsAsyncResp->chassisSubNode != "Power")
+ {
+ BMCWEB_LOG_DEBUG << "getPowerSupplyAttributes exit since not Power";
+ callback(inventoryItems);
+ return;
+ }
+
+ const std::array<std::string, 1> interfaces = {
+ "xyz.openbmc_project.Control.PowerSupplyAttributes"};
+
+ // Response handler for parsing output from GetSubTree
+ auto respHandler = [callback{std::move(callback)}, sensorsAsyncResp,
+ inventoryItems](const boost::system::error_code ec,
+ const GetSubTreeType& subtree) {
+ BMCWEB_LOG_DEBUG << "getPowerSupplyAttributes respHandler enter";
+ if (ec)
+ {
+ messages::internalError(sensorsAsyncResp->res);
+ BMCWEB_LOG_ERROR
+ << "getPowerSupplyAttributes respHandler DBus error " << ec;
+ return;
+ }
+ if (subtree.size() == 0)
+ {
+ BMCWEB_LOG_DEBUG << "Can't find Power Supply Attributes!";
+ callback(inventoryItems);
+ return;
+ }
+
+ // Currently we only support 1 power supply attribute, use this for
+ // all the power supplies. Build map of object path to connection.
+ // Assume just 1 connection and 1 path for now.
+ boost::container::flat_map<std::string, std::string>
+ psAttributesConnections;
+
+ if (subtree[0].first.empty() || subtree[0].second.empty())
+ {
+ BMCWEB_LOG_DEBUG << "Power Supply Attributes mapper error!";
+ callback(inventoryItems);
+ return;
+ }
+
+ const std::string& psAttributesPath = subtree[0].first;
+ const std::string& connection = subtree[0].second.begin()->first;
+
+ if (connection.empty())
+ {
+ BMCWEB_LOG_DEBUG << "Power Supply Attributes mapper error!";
+ callback(inventoryItems);
+ return;
+ }
+
+ psAttributesConnections[psAttributesPath] = connection;
+ BMCWEB_LOG_DEBUG << "Added mapping " << psAttributesPath << " -> "
+ << connection;
+
+ getPowerSupplyAttributesData(sensorsAsyncResp, inventoryItems,
+ psAttributesConnections,
+ std::move(callback));
+ BMCWEB_LOG_DEBUG << "getPowerSupplyAttributes respHandler exit";
+ };
+ // Make call to ObjectMapper to find the PowerSupplyAttributes service
+ crow::connections::systemBus->async_method_call(
+ std::move(respHandler), "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+ "/xyz/openbmc_project", 0, interfaces);
+ BMCWEB_LOG_DEBUG << "getPowerSupplyAttributes exit";
+}
+
+/**
* @brief Gets inventory items associated with sensors.
*
* Finds the inventory items that are associated with the specified sensors.
@@ -1992,9 +2190,22 @@ static void getInventoryItems(
[sensorsAsyncResp, inventoryItems,
callback{std::move(callback)}]() {
BMCWEB_LOG_DEBUG << "getInventoryItemsDataCb enter";
+
+ auto getInventoryLedsCb = [sensorsAsyncResp,
+ inventoryItems,
+ callback{std::move(
+ callback)}]() {
+ BMCWEB_LOG_DEBUG << "getInventoryLedsCb enter";
+ // Find Power Supply Attributes and get the data
+ getPowerSupplyAttributes(sensorsAsyncResp,
+ inventoryItems,
+ std::move(callback));
+ BMCWEB_LOG_DEBUG << "getInventoryLedsCb exit";
+ };
+
// Find led connections and get the data
getInventoryLeds(sensorsAsyncResp, inventoryItems,
- std::move(callback));
+ std::move(getInventoryLedsCb));
BMCWEB_LOG_DEBUG << "getInventoryItemsDataCb exit";
};
@@ -2059,8 +2270,14 @@ static nlohmann::json& getPowerSupply(nlohmann::json& powerSupplyArray,
powerSupply["PartNumber"] = inventoryItem.partNumber;
powerSupply["SerialNumber"] = inventoryItem.serialNumber;
setLedState(powerSupply, &inventoryItem);
- powerSupply["Status"]["State"] = getState(&inventoryItem);
+ if (inventoryItem.powerSupplyEfficiencyPercent >= 0)
+ {
+ powerSupply["EfficiencyPercent"] =
+ inventoryItem.powerSupplyEfficiencyPercent;
+ }
+
+ powerSupply["Status"]["State"] = getState(&inventoryItem);
const char* health = inventoryItem.isFunctional ? "OK" : "Critical";
powerSupply["Status"]["Health"] = health;