Implement LocationIndicatorActive for PowerSupplies
Implement LocationIndicatorActive for PowerSupplies schema to set/get
the status of the location LED for each power supply.[1] When working
with Redfish to get or set the "LocationIndicatorActive" property, the
initial step involves locating the corresponding LED group through the
"identifying" association.[2][3][4] Following this, we can proceed to
either get or set the "Asserted" property.[5]
[1] https://redfish.dmtf.org/schemas/v1/PowerSupply.v1_5_0.json
[2] https://github.com/openbmc/phosphor-dbus-interfaces/tree/master/yaml/xyz/openbmc_project/Led#dbus-interfaces-for-led-groups
[3] https://github.com/openbmc/docs/blob/master/architecture/LED-architecture.md#redfish
[4] https://gerrit.openbmc.org/c/openbmc/phosphor-dbus-interfaces/+/58299
[5] https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Led/Group.interface.yaml
Tested:
- Validator passes.
- Tested on p10bmc hardware simulator
1) Get LocationIndicatorActive
```
$ curl -k -H "X-Auth-Token: $token" -X GET https://${bmc}/redfish/v1/Chassis/chassis/PowerSubsystem/PowerSupplies/powersupply0
{
"@odata.id": "/redfish/v1/Chassis/chassis/PowerSubsystem/PowerSupplies/powersupply0",
"@odata.type": "#PowerSupply.v1_5_0.PowerSupply",
"LocationIndicatorActive": false,
...
}
```
We will see the powersupply0 identify led is false too.
```
$ busctl get-property xyz.openbmc_project.LED.GroupManager /xyz/openbmc_project/led/groups/powersupply0_identify xyz.openbmc_project.Led.Group Asserted
b false
```
2) Set LocationIndicatorActive to true
```
$ curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/json" -X PATCH -d '{"LocationIndicatorActive":true}' https://${bmc}/redfish/v1/Chassis/chassis/PowerSubsystem/PowerSupplies/powersupply0
```
Then we will see the powersupply0 location LED lit up, and the value
becomes true:
```
$ curl -k -H "X-Auth-Token: $token" -X GET https://${bmc}/redfish/v1/Chassis/chassis/PowerSubsystem/PowerSupplies/powersupply0
{
"@odata.id": "/redfish/v1/Chassis/chassis/PowerSubsystem/PowerSupplies/powersupply0",
"@odata.type": "#PowerSupply.v1_5_0.PowerSupply",
"LocationIndicatorActive": true,
...
}
$ busctl get-property xyz.openbmc_project.LED.GroupManager /xyz/openbmc_project/led/groups/powersupply0_identify xyz.openbmc_project.Led.Group Asserted
b true
```
3) Use set-property to change the value back to false
```
$ busctl set-property xyz.openbmc_project.LED.GroupManager /xyz/openbmc_project/led/groups/powersupply0_identify xyz.openbmc_project.Led.Group Asserted b false
$ busctl get-property xyz.openbmc_project.LED.GroupManager /xyz/openbmc_project/led/groups/powersupply0_identify xyz.openbmc_project.Led.Group Asserted
b false
```
Then we will see the value reflected in the Redfish query:
```
$ curl -k -H "X-Auth-Token: $token" -X GET https://${bmc}/redfish/v1/Chassis/chassis/PowerSubsystem/PowerSupplies/powersupply0
{
"@odata.id": "/redfish/v1/Chassis/chassis/PowerSubsystem/PowerSupplies/powersupply0",
"@odata.type": "#PowerSupply.v1_5_0.PowerSupply",
"LocationIndicatorActive": false,
...
}
```
4) Error returned when trying to set the value to non-boolean:
```
$ curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/json" -X PATCH -d '{"LocationIndicatorActive":"unknown"}' https://${bmc}/redfish/v1/Chassis/chassis/PowerSubsystem/PowerSupplies/powersupply0
{
"LocationIndicatorActive@Message.ExtendedInfo": [
{
"@odata.type": "#Message.v1_1_1.Message",
"Message": "The value '\"unknown\"' for the property LocationIndicatorActive is not a type that the property can accept.",
"MessageArgs": [
"\"unknown\"",
"LocationIndicatorActive"
],
"MessageId": "Base.1.19.PropertyValueTypeError",
"MessageSeverity": "Warning",
"Resolution": "Correct the value for the property in the request body and resubmit the request if the operation failed."
}
]
}
```
5) Error returned when specifying a unknown power supply:
```
$ curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/json" -X PATCH -d '{"LocationIndicatorActive":true}' https://${bmc}/redfish/v1/Chassis/chassis/PowerSubsystem/PowerSupplies/powersupplyBAD
{
"error": {
"@Message.ExtendedInfo": [
{
"@odata.type": "#Message.v1_1_1.Message",
"Message": "The requested resource of type PowerSupplies named 'powersupplyBAD' was not found.",
"MessageArgs": [
"PowerSupplies",
"powersupplyBAD"
],
"MessageId": "Base.1.19.ResourceNotFound",
"MessageSeverity": "Critical",
"Resolution": "Provide a valid resource identifier and resubmit the request."
}
],
"code": "Base.1.19.ResourceNotFound",
"message": "The requested resource of type PowerSupplies named 'powersupplyBAD' was not found."
}
}
6) Forced no LED group to test failure paths for GET/PATCH
/* GET succeeds with no LocationIndicatorActive */
$ curl -k -H "X-Auth-Token: $token" https://${bmc}/redfish/v1/Chassis/chassis/PowerSubsystem/PowerSupplies/powersupply0
{
"@odata.id": "/redfish/v1/Chassis/chassis/PowerSubsystem/PowerSupplies/powersupply0",
"@odata.type": "#PowerSupply.v1_5_0.PowerSupply",
"EfficiencyRatings": [
{
"EfficiencyPercent": 90
}
],
"FirmwareVersion": "313033323330",
"Id": "powersupply0",
"Location": {
"PartLocation": {
"ServiceLabel": "U78DA.ND0.1234567-E0"
}
},
"Manufacturer": "",
"Model": "51E9",
"Name": "Power Supply",
"PartNumber": "revisio",
"SerialNumber": "YL10K serial",
"SparePartNumber": "c ",
"Status": {
"Health": "OK",
"State": "Enabled"
}
}
/* PATCH fails when no LocationIndicatorActive property exists for
* object
*/
$ curl -k -H "X-Auth-Token: $token" -H "Content-Type: application/json" -X PATCH -d '{"LocationIndicatorActive":true}' https://${bmc}/redfish/v1/Chassis/chassis/PowerSubsystem/PowerSupplies/powersupply0
{
"error": {
"@Message.ExtendedInfo": [
{
"@odata.type": "#Message.v1_1_1.Message",
"Message": "The property LocationIndicatorActive is not in the list of valid properties for the resource.",
"MessageArgs": [
"LocationIndicatorActive"
],
"MessageId": "Base.1.19.PropertyUnknown",
"MessageSeverity": "Warning",
"Resolution": "Remove the unknown property from the request body and resubmit the request if the operation failed."
}
],
"code": "Base.1.19.PropertyUnknown",
"message": "The property LocationIndicatorActive is not in the list of valid properties for the resource."
}
}
```
Signed-off-by: Chicago Duan <duanzhijia01@inspur.com>
Change-Id: Id0c30fa3d7c1e7ed4ff7f8fd1d5951d24053fbde
Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
Signed-off-by: Myung Bae <myungbae@us.ibm.com>
Signed-off-by: Janet Adkins <janeta@us.ibm.com>
diff --git a/redfish-core/lib/power_supply.hpp b/redfish-core/lib/power_supply.hpp
index 7316b5f..89c84e1 100644
--- a/redfish-core/lib/power_supply.hpp
+++ b/redfish-core/lib/power_supply.hpp
@@ -8,11 +8,13 @@
#include "error_messages.hpp"
#include "generated/enums/resource.hpp"
#include "http_request.hpp"
+#include "led.hpp"
#include "logging.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/chassis_utils.hpp"
#include "utils/dbus_utils.hpp"
+#include "utils/json_utils.hpp"
#include "utils/time_utils.hpp"
#include <asm-generic/errno.h>
@@ -505,6 +507,7 @@
getPowerSupplyFirmwareVersion(asyncResp, service, powerSupplyPath);
getPowerSupplyLocation(asyncResp, service, powerSupplyPath);
getEfficiencyPercent(asyncResp);
+ getLocationIndicatorActive(asyncResp, powerSupplyPath);
}
inline void handlePowerSupplyHead(
@@ -549,6 +552,43 @@
std::bind_front(doPowerSupplyGet, asyncResp, chassisId, powerSupplyId));
}
+inline void doPatchPowerSupply(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const bool locationIndicatorActive, const std::string& powerSupplyPath,
+ const std::string& /*service*/)
+{
+ setLocationIndicatorActive(asyncResp, powerSupplyPath,
+ locationIndicatorActive);
+}
+
+inline void handlePowerSupplyPatch(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId, const std::string& powerSupplyId)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ std::optional<bool> locationIndicatorActive;
+ if (!json_util::readJsonPatch( //
+ req, asyncResp->res, //
+ "LocationIndicatorActive", locationIndicatorActive //
+ ))
+ {
+ return;
+ }
+
+ if (locationIndicatorActive)
+ {
+ // Get the correct power supply Path that match the input parameters
+ getValidPowerSupplyPath(asyncResp, chassisId, powerSupplyId,
+ std::bind_front(doPatchPowerSupply, asyncResp,
+ *locationIndicatorActive));
+ }
+}
+
inline void requestRoutesPowerSupply(App& app)
{
BMCWEB_ROUTE(
@@ -562,6 +602,12 @@
.privileges(redfish::privileges::getPowerSupply)
.methods(boost::beast::http::verb::get)(
std::bind_front(handlePowerSupplyGet, std::ref(app)));
+
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/")
+ .privileges(redfish::privileges::patchPowerSupply)
+ .methods(boost::beast::http::verb::patch)(
+ std::bind_front(handlePowerSupplyPatch, std::ref(app)));
}
} // namespace redfish