blob: 07b4b384fd0e461ce35c06edc30eebe9ee89e6d8 [file] [log] [blame]
Ed Tanous2474adf2018-09-05 16:31:16 -07001/*
2// Copyright (c) 2018 Intel Corporation
3// Copyright (c) 2018 Ampere Computing LLC
4/
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16*/
17#pragma once
18
19#include "node.hpp"
20#include "sensors.hpp"
21
22namespace redfish
23{
24
25class Power : public Node
26{
27 public:
28 Power(CrowApp& app) :
29 Node((app), "/redfish/v1/Chassis/<str>/Power/", std::string())
30 {
Ed Tanous2474adf2018-09-05 16:31:16 -070031 entityPrivileges = {
32 {boost::beast::http::verb::get, {{"Login"}}},
33 {boost::beast::http::verb::head, {{"Login"}}},
Richard Marian Thomaiyar6f4fd472019-02-13 10:10:59 +053034 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
Ed Tanous2474adf2018-09-05 16:31:16 -070035 {boost::beast::http::verb::put, {{"ConfigureManager"}}},
36 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
37 {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
38 }
39
40 private:
Ed Tanousb01bf292019-03-25 19:25:26 +000041 std::initializer_list<const char*> typeList = {
42 "/xyz/openbmc_project/sensors/voltage",
43 "/xyz/openbmc_project/sensors/power"};
Ed Tanous2474adf2018-09-05 16:31:16 -070044 void doGet(crow::Response& res, const crow::Request& req,
45 const std::vector<std::string>& params) override
46 {
47 if (params.size() != 1)
48 {
49 res.result(boost::beast::http::status::internal_server_error);
50 res.end();
51 return;
52 }
53 const std::string& chassis_name = params[0];
54
Jennifer Leec5d03ff2019-03-08 15:42:58 -080055 res.jsonValue["PowerControl"] = nlohmann::json::array();
56
Ed Tanous2474adf2018-09-05 16:31:16 -070057 auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
Richard Marian Thomaiyar413961d2019-02-01 00:43:39 +053058 res, chassis_name, typeList, "Power");
Eddie James028f7eb2019-05-17 21:24:36 +000059
Ed Tanous2474adf2018-09-05 16:31:16 -070060 getChassisData(sensorAsyncResp);
Eddie James028f7eb2019-05-17 21:24:36 +000061
62 // This callback verifies that the power limit is only provided for the
63 // chassis that implements the Chassis inventory item. This prevents
64 // things like power supplies providing the chassis power limit
65 auto chassisHandler = [sensorAsyncResp](
66 const boost::system::error_code ec,
67 const std::vector<std::string>&
68 chassisPaths) {
69 if (ec)
70 {
71 BMCWEB_LOG_ERROR
72 << "Power Limit GetSubTreePaths handler Dbus error " << ec;
73 return;
74 }
75
76 bool found = false;
77 for (const std::string& chassis : chassisPaths)
78 {
79 size_t len = std::string::npos;
80 size_t lastPos = chassis.rfind("/");
81 if (lastPos == std::string::npos)
82 {
83 continue;
84 }
85
86 if (lastPos == chassis.size() - 1)
87 {
88 size_t end = lastPos;
89 lastPos = chassis.rfind("/", lastPos - 1);
90 if (lastPos == std::string::npos)
91 {
92 continue;
93 }
94
95 len = end - (lastPos + 1);
96 }
97
98 std::string interfaceChassisName =
99 chassis.substr(lastPos + 1, len);
100 if (!interfaceChassisName.compare(sensorAsyncResp->chassisId))
101 {
102 found = true;
103 break;
104 }
105 }
106
107 if (!found)
108 {
109 BMCWEB_LOG_DEBUG << "Power Limit not present for "
110 << sensorAsyncResp->chassisId;
111 return;
112 }
113
114 auto valueHandler =
115 [sensorAsyncResp](
116 const boost::system::error_code ec,
117 const std::vector<std::pair<std::string, SensorVariant>>&
118 properties) {
119 if (ec)
120 {
121 messages::internalError(sensorAsyncResp->res);
122 BMCWEB_LOG_ERROR
123 << "Power Limit GetAll handler: Dbus error " << ec;
124 return;
125 }
126
127 nlohmann::json& tempArray =
128 sensorAsyncResp->res.jsonValue["PowerLimit"];
129
130 if (tempArray.empty())
131 {
132 tempArray.push_back({});
133 }
134
135 nlohmann::json& sensorJson = tempArray.back();
136 bool enabled = false;
137 double powerCap = 0.0;
138 int64_t scale = 0;
139
140 for (const std::pair<std::string, SensorVariant>& property :
141 properties)
142 {
143 if (!property.first.compare("Scale"))
144 {
145 const int64_t* i =
146 sdbusplus::message::variant_ns::get_if<int64_t>(
147 &property.second);
148
149 if (i)
150 {
151 scale = *i;
152 }
153 }
154 else if (!property.first.compare("PowerCap"))
155 {
156 const double* d =
157 sdbusplus::message::variant_ns::get_if<double>(
158 &property.second);
159 const int64_t* i =
160 sdbusplus::message::variant_ns::get_if<int64_t>(
161 &property.second);
162 const uint32_t* u =
163 sdbusplus::message::variant_ns::get_if<
164 uint32_t>(&property.second);
165
166 if (d)
167 {
168 powerCap = *d;
169 }
170 else if (i)
171 {
172 powerCap = *i;
173 }
174 else if (u)
175 {
176 powerCap = *u;
177 }
178 }
179 else if (!property.first.compare("PowerCapEnable"))
180 {
181 const bool* b =
182 sdbusplus::message::variant_ns::get_if<bool>(
183 &property.second);
184
185 if (b)
186 {
187 enabled = *b;
188 }
189 }
190 }
191
192 nlohmann::json& value = sensorJson["LimitInWatts"];
193
194 if (enabled)
195 {
196 // Redfish specification indicates PowerLimit should be
197 // null if the limit is not enabled.
198 value = powerCap * std::pow(10, scale);
199 }
200 };
201
202 crow::connections::systemBus->async_method_call(
203 std::move(valueHandler), "xyz.openbmc_project.Settings",
204 "/xyz/openbmc_project/control/host0/power_cap",
205 "org.freedesktop.DBus.Properties", "GetAll",
206 "xyz.openbmc_project.Control.Power.Cap");
207 };
208
209 crow::connections::systemBus->async_method_call(
210 std::move(chassisHandler), "xyz.openbmc_project.ObjectMapper",
211 "/xyz/openbmc_project/object_mapper",
212 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
213 "/xyz/openbmc_project/inventory", int32_t(0),
214 std::array<const char*, 1>{
215 "xyz.openbmc_project.Inventory.Item.Chassis"});
Ed Tanous2474adf2018-09-05 16:31:16 -0700216 }
Richard Marian Thomaiyar413961d2019-02-01 00:43:39 +0530217 void doPatch(crow::Response& res, const crow::Request& req,
218 const std::vector<std::string>& params) override
219 {
220 setSensorOverride(res, req, params, typeList, "Power");
221 }
Ed Tanous2474adf2018-09-05 16:31:16 -0700222};
223
224} // namespace redfish