blob: 28dc3588f14eac55e80f617679093d57014e3e34 [file] [log] [blame]
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +01001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
18#include <math.h>
Ed Tanous1abe55e2018-09-05 08:30:59 -070019
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010020#include <boost/algorithm/string/predicate.hpp>
21#include <boost/algorithm/string/split.hpp>
22#include <boost/container/flat_map.hpp>
23#include <boost/range/algorithm/replace_copy_if.hpp>
Ed Tanous1abe55e2018-09-05 08:30:59 -070024#include <dbus_singleton.hpp>
Ed Tanousabf2add2019-01-22 16:40:12 -080025#include <variant>
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010026
Ed Tanous1abe55e2018-09-05 08:30:59 -070027namespace redfish
28{
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010029
Ed Tanousd76323e2018-08-07 14:35:40 -070030constexpr const char* dbusSensorPrefix = "/xyz/openbmc_project/sensors/";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010031
32using GetSubTreeType = std::vector<
33 std::pair<std::string,
34 std::vector<std::pair<std::string, std::vector<std::string>>>>>;
35
Ed Tanousabf2add2019-01-22 16:40:12 -080036using SensorVariant = std::variant<int64_t, double>;
Ed Tanousaa2e59c2018-04-12 12:17:20 -070037
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010038using ManagedObjectsVectorType = std::vector<std::pair<
Ed Tanousaa2e59c2018-04-12 12:17:20 -070039 sdbusplus::message::object_path,
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010040 boost::container::flat_map<
Ed Tanousaa2e59c2018-04-12 12:17:20 -070041 std::string, boost::container::flat_map<std::string, SensorVariant>>>>;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010042
43/**
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020044 * SensorsAsyncResp
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010045 * Gathers data needed for response processing after async calls are done
46 */
Ed Tanous1abe55e2018-09-05 08:30:59 -070047class SensorsAsyncResp
48{
49 public:
50 SensorsAsyncResp(crow::Response& response, const std::string& chassisId,
Ed Tanous2474adf2018-09-05 16:31:16 -070051 const std::initializer_list<const char*> types,
52 const std::string& subNode) :
53 chassisId(chassisId),
54 res(response), types(types), chassisSubNode(subNode)
Ed Tanous1abe55e2018-09-05 08:30:59 -070055 {
56 res.jsonValue["@odata.id"] =
57 "/redfish/v1/Chassis/" + chassisId + "/Thermal";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010058 }
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020059
Ed Tanous1abe55e2018-09-05 08:30:59 -070060 ~SensorsAsyncResp()
61 {
62 if (res.result() == boost::beast::http::status::internal_server_error)
63 {
64 // Reset the json object to clear out any data that made it in
65 // before the error happened todo(ed) handle error condition with
66 // proper code
67 res.jsonValue = nlohmann::json::object();
68 }
69 res.end();
70 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010071
Ed Tanous1abe55e2018-09-05 08:30:59 -070072 crow::Response& res;
73 std::string chassisId{};
74 const std::vector<const char*> types;
Ed Tanous2474adf2018-09-05 16:31:16 -070075 std::string chassisSubNode{};
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010076};
77
78/**
79 * @brief Creates connections necessary for chassis sensors
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020080 * @param SensorsAsyncResp Pointer to object holding response data
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010081 * @param sensorNames Sensors retrieved from chassis
82 * @param callback Callback for processing gathered connections
83 */
84template <typename Callback>
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020085void getConnections(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp,
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010086 const boost::container::flat_set<std::string>& sensorNames,
Ed Tanous1abe55e2018-09-05 08:30:59 -070087 Callback&& callback)
88{
89 BMCWEB_LOG_DEBUG << "getConnections enter";
90 const std::string path = "/xyz/openbmc_project/sensors";
91 const std::array<std::string, 1> interfaces = {
92 "xyz.openbmc_project.Sensor.Value"};
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010093
Ed Tanous1abe55e2018-09-05 08:30:59 -070094 // Response handler for parsing objects subtree
95 auto respHandler = [callback{std::move(callback)}, SensorsAsyncResp,
96 sensorNames](const boost::system::error_code ec,
97 const GetSubTreeType& subtree) {
98 BMCWEB_LOG_DEBUG << "getConnections resp_handler enter";
99 if (ec)
100 {
Ed Tanous5f7d88c2018-11-14 14:08:56 -0800101 messages::internalError(SensorsAsyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700102 BMCWEB_LOG_ERROR << "getConnections resp_handler: Dbus error "
103 << ec;
104 return;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100105 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100106
Ed Tanous1abe55e2018-09-05 08:30:59 -0700107 BMCWEB_LOG_DEBUG << "Found " << subtree.size() << " subtrees";
108
109 // Make unique list of connections only for requested sensor types and
110 // found in the chassis
111 boost::container::flat_set<std::string> connections;
112 // Intrinsic to avoid malloc. Most systems will have < 8 sensor
113 // producers
114 connections.reserve(8);
115
116 BMCWEB_LOG_DEBUG << "sensorNames list count: " << sensorNames.size();
117 for (const std::string& tsensor : sensorNames)
118 {
119 BMCWEB_LOG_DEBUG << "Sensor to find: " << tsensor;
120 }
121
122 for (const std::pair<
123 std::string,
124 std::vector<std::pair<std::string, std::vector<std::string>>>>&
125 object : subtree)
126 {
127 for (const char* type : SensorsAsyncResp->types)
128 {
129 if (boost::starts_with(object.first, type))
130 {
131 auto lastPos = object.first.rfind('/');
132 if (lastPos != std::string::npos)
133 {
134 std::string sensorName =
135 object.first.substr(lastPos + 1);
136
137 if (sensorNames.find(sensorName) != sensorNames.end())
138 {
139 // For each Connection name
140 for (const std::pair<std::string,
141 std::vector<std::string>>&
142 objData : object.second)
143 {
144 BMCWEB_LOG_DEBUG << "Adding connection: "
145 << objData.first;
146 connections.insert(objData.first);
147 }
148 }
149 }
150 break;
151 }
152 }
153 }
154 BMCWEB_LOG_DEBUG << "Found " << connections.size() << " connections";
155 callback(std::move(connections));
156 BMCWEB_LOG_DEBUG << "getConnections resp_handler exit";
157 };
158
159 // Make call to ObjectMapper to find all sensors objects
160 crow::connections::systemBus->async_method_call(
161 std::move(respHandler), "xyz.openbmc_project.ObjectMapper",
162 "/xyz/openbmc_project/object_mapper",
163 "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, 2, interfaces);
164 BMCWEB_LOG_DEBUG << "getConnections exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100165}
166
167/**
168 * @brief Retrieves requested chassis sensors and redundancy data from DBus .
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200169 * @param SensorsAsyncResp Pointer to object holding response data
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100170 * @param callback Callback for next step in gathered sensor processing
171 */
172template <typename Callback>
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200173void getChassis(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp,
Ed Tanous1abe55e2018-09-05 08:30:59 -0700174 Callback&& callback)
175{
176 BMCWEB_LOG_DEBUG << "getChassis enter";
177 // Process response from EntityManager and extract chassis data
178 auto respHandler = [callback{std::move(callback)},
179 SensorsAsyncResp](const boost::system::error_code ec,
180 ManagedObjectsVectorType& resp) {
181 BMCWEB_LOG_DEBUG << "getChassis respHandler enter";
182 if (ec)
183 {
184 BMCWEB_LOG_ERROR << "getChassis respHandler DBUS error: " << ec;
Ed Tanous5f7d88c2018-11-14 14:08:56 -0800185 messages::internalError(SensorsAsyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700186 return;
187 }
188 boost::container::flat_set<std::string> sensorNames;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100189
Ed Tanous1abe55e2018-09-05 08:30:59 -0700190 // SensorsAsyncResp->chassisId
191 bool foundChassis = false;
192 std::vector<std::string> split;
193 // Reserve space for
194 // /xyz/openbmc_project/inventory/<name>/<subname> + 3 subnames
195 split.reserve(8);
Ed Tanousdaf36e22018-04-20 16:01:36 -0700196
Ed Tanous1abe55e2018-09-05 08:30:59 -0700197 for (const auto& objDictEntry : resp)
198 {
199 const std::string& objectPath =
200 static_cast<const std::string&>(objDictEntry.first);
201 boost::algorithm::split(split, objectPath, boost::is_any_of("/"));
202 if (split.size() < 2)
203 {
204 BMCWEB_LOG_ERROR << "Got path that isn't long enough "
205 << objectPath;
206 split.clear();
207 continue;
208 }
209 const std::string& sensorName = split.end()[-1];
210 const std::string& chassisName = split.end()[-2];
Ed Tanousdaf36e22018-04-20 16:01:36 -0700211
Ed Tanous1abe55e2018-09-05 08:30:59 -0700212 if (chassisName != SensorsAsyncResp->chassisId)
213 {
214 split.clear();
215 continue;
216 }
217 BMCWEB_LOG_DEBUG << "New sensor: " << sensorName;
218 foundChassis = true;
219 sensorNames.emplace(sensorName);
220 split.clear();
221 };
222 BMCWEB_LOG_DEBUG << "Found " << sensorNames.size() << " Sensor names";
223
224 if (!foundChassis)
225 {
226 BMCWEB_LOG_INFO << "Unable to find chassis named "
227 << SensorsAsyncResp->chassisId;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700228 messages::resourceNotFound(SensorsAsyncResp->res, "Chassis",
229 SensorsAsyncResp->chassisId);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700230 }
231 else
232 {
233 callback(sensorNames);
234 }
235 BMCWEB_LOG_DEBUG << "getChassis respHandler exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100236 };
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100237
Ed Tanous1abe55e2018-09-05 08:30:59 -0700238 // Make call to EntityManager to find all chassis objects
239 crow::connections::systemBus->async_method_call(
240 respHandler, "xyz.openbmc_project.EntityManager", "/",
241 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
242 BMCWEB_LOG_DEBUG << "getChassis exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100243}
244
245/**
246 * @brief Builds a json sensor representation of a sensor.
247 * @param sensorName The name of the sensor to be built
Gunnar Mills274fad52018-06-13 15:45:36 -0500248 * @param sensorType The type (temperature, fan_tach, etc) of the sensor to
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100249 * build
250 * @param interfacesDict A dictionary of the interfaces and properties of said
251 * interfaces to be built from
252 * @param sensor_json The json object to fill
253 */
254void objectInterfacesToJson(
255 const std::string& sensorName, const std::string& sensorType,
256 const boost::container::flat_map<
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700257 std::string, boost::container::flat_map<std::string, SensorVariant>>&
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100258 interfacesDict,
Ed Tanous1abe55e2018-09-05 08:30:59 -0700259 nlohmann::json& sensor_json)
260{
261 // We need a value interface before we can do anything with it
262 auto valueIt = interfacesDict.find("xyz.openbmc_project.Sensor.Value");
263 if (valueIt == interfacesDict.end())
264 {
265 BMCWEB_LOG_ERROR << "Sensor doesn't have a value interface";
266 return;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100267 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100268
Ed Tanous1abe55e2018-09-05 08:30:59 -0700269 // Assume values exist as is (10^0 == 1) if no scale exists
270 int64_t scaleMultiplier = 0;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100271
Ed Tanous1abe55e2018-09-05 08:30:59 -0700272 auto scaleIt = valueIt->second.find("Scale");
273 // If a scale exists, pull value as int64, and use the scaling.
274 if (scaleIt != valueIt->second.end())
275 {
Ed Tanousabf2add2019-01-22 16:40:12 -0800276 const int64_t* int64Value = std::get_if<int64_t>(&scaleIt->second);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700277 if (int64Value != nullptr)
278 {
279 scaleMultiplier = *int64Value;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100280 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100281 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700282
283 sensor_json["MemberId"] = sensorName;
284 sensor_json["Name"] = sensorName;
285 sensor_json["Status"]["State"] = "Enabled";
286 sensor_json["Status"]["Health"] = "OK";
287
288 // Parameter to set to override the type we get from dbus, and force it to
289 // int, regardless of what is available. This is used for schemas like fan,
290 // that require integers, not floats.
291 bool forceToInt = false;
292
293 const char* unit = "Reading";
294 if (sensorType == "temperature")
295 {
296 unit = "ReadingCelsius";
297 sensor_json["@odata.type"] = "#Thermal.v1_3_0.Temperature";
298 // TODO(ed) Documentation says that path should be type fan_tach,
299 // implementation seems to implement fan
300 }
301 else if (sensorType == "fan" || sensorType == "fan_tach")
302 {
303 unit = "Reading";
304 sensor_json["ReadingUnits"] = "RPM";
305 sensor_json["@odata.type"] = "#Thermal.v1_3_0.Fan";
306 forceToInt = true;
307 }
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700308 else if (sensorType == "fan_pwm")
309 {
310 unit = "Reading";
311 sensor_json["ReadingUnits"] = "Percent";
312 sensor_json["@odata.type"] = "#Thermal.v1_3_0.Fan";
313 forceToInt = true;
314 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700315 else if (sensorType == "voltage")
316 {
317 unit = "ReadingVolts";
318 sensor_json["@odata.type"] = "#Power.v1_0_0.Voltage";
319 }
Ed Tanous2474adf2018-09-05 16:31:16 -0700320 else if (sensorType == "power")
321 {
322 unit = "LastPowerOutputWatts";
323 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700324 else
325 {
326 BMCWEB_LOG_ERROR << "Redfish cannot map object type for " << sensorName;
327 return;
328 }
329 // Map of dbus interface name, dbus property name and redfish property_name
330 std::vector<std::tuple<const char*, const char*, const char*>> properties;
331 properties.reserve(7);
332
333 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit);
334 properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
335 "WarningHigh", "UpperThresholdNonCritical");
336 properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
337 "WarningLow", "LowerThresholdNonCritical");
338 properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
339 "CriticalHigh", "UpperThresholdCritical");
340 properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
341 "CriticalLow", "LowerThresholdCritical");
342
Ed Tanous2474adf2018-09-05 16:31:16 -0700343 // TODO Need to get UpperThresholdFatal and LowerThresholdFatal
344
Ed Tanous1abe55e2018-09-05 08:30:59 -0700345 if (sensorType == "temperature")
346 {
347 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
348 "MinReadingRangeTemp");
349 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
350 "MaxReadingRangeTemp");
351 }
352 else
353 {
354 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
355 "MinReadingRange");
356 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
357 "MaxReadingRange");
358 }
359
360 for (const std::tuple<const char*, const char*, const char*>& p :
361 properties)
362 {
363 auto interfaceProperties = interfacesDict.find(std::get<0>(p));
364 if (interfaceProperties != interfacesDict.end())
365 {
366 auto valueIt = interfaceProperties->second.find(std::get<1>(p));
367 if (valueIt != interfaceProperties->second.end())
368 {
369 const SensorVariant& valueVariant = valueIt->second;
370 nlohmann::json& valueIt = sensor_json[std::get<2>(p)];
Ed Tanous1abe55e2018-09-05 08:30:59 -0700371 // Attempt to pull the int64 directly
Ed Tanousabf2add2019-01-22 16:40:12 -0800372 const int64_t* int64Value = std::get_if<int64_t>(&valueVariant);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700373
Ed Tanousabf2add2019-01-22 16:40:12 -0800374 const double* doubleValue = std::get_if<double>(&valueVariant);
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700375 double temp = 0.0;
376 if (int64Value != nullptr)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700377 {
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700378 temp = *int64Value;
379 }
380 else if (doubleValue != nullptr)
381 {
382 temp = *doubleValue;
383 }
384 else
385 {
386 BMCWEB_LOG_ERROR
387 << "Got value interface that wasn't int or double";
388 continue;
389 }
390 temp = temp * std::pow(10, scaleMultiplier);
391 if (forceToInt)
392 {
393 valueIt = static_cast<int64_t>(temp);
394 }
395 else
396 {
397 valueIt = temp;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700398 }
399 }
400 }
401 }
402 BMCWEB_LOG_DEBUG << "Added sensor " << sensorName;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100403}
404
405/**
406 * @brief Entry point for retrieving sensors data related to requested
407 * chassis.
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200408 * @param SensorsAsyncResp Pointer to object holding response data
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100409 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700410void getChassisData(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp)
411{
412 BMCWEB_LOG_DEBUG << "getChassisData enter";
413 auto getChassisCb = [&, SensorsAsyncResp](
414 boost::container::flat_set<std::string>&
415 sensorNames) {
416 BMCWEB_LOG_DEBUG << "getChassisCb enter";
417 auto getConnectionCb =
418 [&, SensorsAsyncResp, sensorNames](
419 const boost::container::flat_set<std::string>& connections) {
420 BMCWEB_LOG_DEBUG << "getConnectionCb enter";
421 // Get managed objects from all services exposing sensors
422 for (const std::string& connection : connections)
423 {
424 // Response handler to process managed objects
425 auto getManagedObjectsCb =
426 [&, SensorsAsyncResp,
427 sensorNames](const boost::system::error_code ec,
428 ManagedObjectsVectorType& resp) {
429 BMCWEB_LOG_DEBUG << "getManagedObjectsCb enter";
430 if (ec)
431 {
432 BMCWEB_LOG_ERROR
433 << "getManagedObjectsCb DBUS error: " << ec;
Ed Tanous5f7d88c2018-11-14 14:08:56 -0800434 messages::internalError(SensorsAsyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700435 return;
436 }
437 // Go through all objects and update response with
438 // sensor data
439 for (const auto& objDictEntry : resp)
440 {
441 const std::string& objPath =
442 static_cast<const std::string&>(
443 objDictEntry.first);
444 BMCWEB_LOG_DEBUG
445 << "getManagedObjectsCb parsing object "
446 << objPath;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100447
Ed Tanous1abe55e2018-09-05 08:30:59 -0700448 std::vector<std::string> split;
449 // Reserve space for
450 // /xyz/openbmc_project/sensors/<name>/<subname>
451 split.reserve(6);
452 boost::algorithm::split(split, objPath,
453 boost::is_any_of("/"));
454 if (split.size() < 6)
455 {
456 BMCWEB_LOG_ERROR
457 << "Got path that isn't long enough "
458 << objPath;
459 continue;
460 }
461 // These indexes aren't intuitive, as
462 // boost::split puts an empty string at the
463 // beggining
464 const std::string& sensorType = split[4];
465 const std::string& sensorName = split[5];
466 BMCWEB_LOG_DEBUG << "sensorName " << sensorName
467 << " sensorType "
468 << sensorType;
469 if (sensorNames.find(sensorName) ==
470 sensorNames.end())
471 {
472 BMCWEB_LOG_ERROR << sensorName
473 << " not in sensor list ";
474 continue;
475 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100476
Ed Tanous1abe55e2018-09-05 08:30:59 -0700477 const char* fieldName = nullptr;
478 if (sensorType == "temperature")
479 {
480 fieldName = "Temperatures";
481 }
482 else if (sensorType == "fan" ||
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700483 sensorType == "fan_tach" ||
484 sensorType == "fan_pwm")
Ed Tanous1abe55e2018-09-05 08:30:59 -0700485 {
486 fieldName = "Fans";
487 }
488 else if (sensorType == "voltage")
489 {
490 fieldName = "Voltages";
491 }
492 else if (sensorType == "current")
493 {
494 fieldName = "PowerSupply";
495 }
496 else if (sensorType == "power")
497 {
498 fieldName = "PowerSupply";
499 }
500 else
501 {
502 BMCWEB_LOG_ERROR
503 << "Unsure how to handle sensorType "
504 << sensorType;
505 continue;
506 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100507
Ed Tanous1abe55e2018-09-05 08:30:59 -0700508 nlohmann::json& tempArray =
509 SensorsAsyncResp->res.jsonValue[fieldName];
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100510
Ed Tanous1abe55e2018-09-05 08:30:59 -0700511 tempArray.push_back(
512 {{"@odata.id",
513 "/redfish/v1/Chassis/" +
Ed Tanous2474adf2018-09-05 16:31:16 -0700514 SensorsAsyncResp->chassisId + "/" +
515 SensorsAsyncResp->chassisSubNode +
516 "#/" + fieldName + "/" +
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700517 std::to_string(tempArray.size())}});
Ed Tanous1abe55e2018-09-05 08:30:59 -0700518 nlohmann::json& sensorJson = tempArray.back();
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700519
Ed Tanous1abe55e2018-09-05 08:30:59 -0700520 objectInterfacesToJson(sensorName, sensorType,
521 objDictEntry.second,
522 sensorJson);
523 }
524 BMCWEB_LOG_DEBUG << "getManagedObjectsCb exit";
525 };
526 crow::connections::systemBus->async_method_call(
527 getManagedObjectsCb, connection, "/",
528 "org.freedesktop.DBus.ObjectManager",
529 "GetManagedObjects");
530 };
531 BMCWEB_LOG_DEBUG << "getConnectionCb exit";
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200532 };
Ed Tanous1abe55e2018-09-05 08:30:59 -0700533 // get connections and then pass it to get sensors
534 getConnections(SensorsAsyncResp, sensorNames,
535 std::move(getConnectionCb));
536 BMCWEB_LOG_DEBUG << "getChassisCb exit";
537 };
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100538
Ed Tanous1abe55e2018-09-05 08:30:59 -0700539 // get chassis information related to sensors
540 getChassis(SensorsAsyncResp, std::move(getChassisCb));
541 BMCWEB_LOG_DEBUG << "getChassisData exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100542};
543
Ed Tanous1abe55e2018-09-05 08:30:59 -0700544} // namespace redfish