blob: 8b829be079654bb5453d3915ed3c17d0c1feb350 [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>
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010025
Ed Tanous1abe55e2018-09-05 08:30:59 -070026namespace redfish
27{
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010028
Ed Tanousd76323e2018-08-07 14:35:40 -070029constexpr const char* dbusSensorPrefix = "/xyz/openbmc_project/sensors/";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010030
31using GetSubTreeType = std::vector<
32 std::pair<std::string,
33 std::vector<std::pair<std::string, std::vector<std::string>>>>>;
34
Ed Tanousaa2e59c2018-04-12 12:17:20 -070035using SensorVariant = sdbusplus::message::variant<int64_t, double>;
36
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010037using ManagedObjectsVectorType = std::vector<std::pair<
Ed Tanousaa2e59c2018-04-12 12:17:20 -070038 sdbusplus::message::object_path,
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010039 boost::container::flat_map<
Ed Tanousaa2e59c2018-04-12 12:17:20 -070040 std::string, boost::container::flat_map<std::string, SensorVariant>>>>;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010041
42/**
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020043 * SensorsAsyncResp
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010044 * Gathers data needed for response processing after async calls are done
45 */
Ed Tanous1abe55e2018-09-05 08:30:59 -070046class SensorsAsyncResp
47{
48 public:
49 SensorsAsyncResp(crow::Response& response, const std::string& chassisId,
Ed Tanous2474adf2018-09-05 16:31:16 -070050 const std::initializer_list<const char*> types,
51 const std::string& subNode) :
52 chassisId(chassisId),
53 res(response), types(types), chassisSubNode(subNode)
Ed Tanous1abe55e2018-09-05 08:30:59 -070054 {
55 res.jsonValue["@odata.id"] =
56 "/redfish/v1/Chassis/" + chassisId + "/Thermal";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010057 }
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020058
Ed Tanous1abe55e2018-09-05 08:30:59 -070059 ~SensorsAsyncResp()
60 {
61 if (res.result() == boost::beast::http::status::internal_server_error)
62 {
63 // Reset the json object to clear out any data that made it in
64 // before the error happened todo(ed) handle error condition with
65 // proper code
66 res.jsonValue = nlohmann::json::object();
67 }
68 res.end();
69 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010070
Ed Tanous1abe55e2018-09-05 08:30:59 -070071 void setErrorStatus()
72 {
73 res.result(boost::beast::http::status::internal_server_error);
74 }
75
76 crow::Response& res;
77 std::string chassisId{};
78 const std::vector<const char*> types;
Ed Tanous2474adf2018-09-05 16:31:16 -070079 std::string chassisSubNode{};
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010080};
81
82/**
83 * @brief Creates connections necessary for chassis sensors
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020084 * @param SensorsAsyncResp Pointer to object holding response data
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010085 * @param sensorNames Sensors retrieved from chassis
86 * @param callback Callback for processing gathered connections
87 */
88template <typename Callback>
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020089void getConnections(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp,
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010090 const boost::container::flat_set<std::string>& sensorNames,
Ed Tanous1abe55e2018-09-05 08:30:59 -070091 Callback&& callback)
92{
93 BMCWEB_LOG_DEBUG << "getConnections enter";
94 const std::string path = "/xyz/openbmc_project/sensors";
95 const std::array<std::string, 1> interfaces = {
96 "xyz.openbmc_project.Sensor.Value"};
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010097
Ed Tanous1abe55e2018-09-05 08:30:59 -070098 // Response handler for parsing objects subtree
99 auto respHandler = [callback{std::move(callback)}, SensorsAsyncResp,
100 sensorNames](const boost::system::error_code ec,
101 const GetSubTreeType& subtree) {
102 BMCWEB_LOG_DEBUG << "getConnections resp_handler enter";
103 if (ec)
104 {
105 SensorsAsyncResp->setErrorStatus();
106 BMCWEB_LOG_ERROR << "getConnections resp_handler: Dbus error "
107 << ec;
108 return;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100109 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100110
Ed Tanous1abe55e2018-09-05 08:30:59 -0700111 BMCWEB_LOG_DEBUG << "Found " << subtree.size() << " subtrees";
112
113 // Make unique list of connections only for requested sensor types and
114 // found in the chassis
115 boost::container::flat_set<std::string> connections;
116 // Intrinsic to avoid malloc. Most systems will have < 8 sensor
117 // producers
118 connections.reserve(8);
119
120 BMCWEB_LOG_DEBUG << "sensorNames list count: " << sensorNames.size();
121 for (const std::string& tsensor : sensorNames)
122 {
123 BMCWEB_LOG_DEBUG << "Sensor to find: " << tsensor;
124 }
125
126 for (const std::pair<
127 std::string,
128 std::vector<std::pair<std::string, std::vector<std::string>>>>&
129 object : subtree)
130 {
131 for (const char* type : SensorsAsyncResp->types)
132 {
133 if (boost::starts_with(object.first, type))
134 {
135 auto lastPos = object.first.rfind('/');
136 if (lastPos != std::string::npos)
137 {
138 std::string sensorName =
139 object.first.substr(lastPos + 1);
140
141 if (sensorNames.find(sensorName) != sensorNames.end())
142 {
143 // For each Connection name
144 for (const std::pair<std::string,
145 std::vector<std::string>>&
146 objData : object.second)
147 {
148 BMCWEB_LOG_DEBUG << "Adding connection: "
149 << objData.first;
150 connections.insert(objData.first);
151 }
152 }
153 }
154 break;
155 }
156 }
157 }
158 BMCWEB_LOG_DEBUG << "Found " << connections.size() << " connections";
159 callback(std::move(connections));
160 BMCWEB_LOG_DEBUG << "getConnections resp_handler exit";
161 };
162
163 // Make call to ObjectMapper to find all sensors objects
164 crow::connections::systemBus->async_method_call(
165 std::move(respHandler), "xyz.openbmc_project.ObjectMapper",
166 "/xyz/openbmc_project/object_mapper",
167 "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, 2, interfaces);
168 BMCWEB_LOG_DEBUG << "getConnections exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100169}
170
171/**
172 * @brief Retrieves requested chassis sensors and redundancy data from DBus .
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200173 * @param SensorsAsyncResp Pointer to object holding response data
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100174 * @param callback Callback for next step in gathered sensor processing
175 */
176template <typename Callback>
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200177void getChassis(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp,
Ed Tanous1abe55e2018-09-05 08:30:59 -0700178 Callback&& callback)
179{
180 BMCWEB_LOG_DEBUG << "getChassis enter";
181 // Process response from EntityManager and extract chassis data
182 auto respHandler = [callback{std::move(callback)},
183 SensorsAsyncResp](const boost::system::error_code ec,
184 ManagedObjectsVectorType& resp) {
185 BMCWEB_LOG_DEBUG << "getChassis respHandler enter";
186 if (ec)
187 {
188 BMCWEB_LOG_ERROR << "getChassis respHandler DBUS error: " << ec;
189 SensorsAsyncResp->setErrorStatus();
190 return;
191 }
192 boost::container::flat_set<std::string> sensorNames;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100193
Ed Tanous1abe55e2018-09-05 08:30:59 -0700194 // SensorsAsyncResp->chassisId
195 bool foundChassis = false;
196 std::vector<std::string> split;
197 // Reserve space for
198 // /xyz/openbmc_project/inventory/<name>/<subname> + 3 subnames
199 split.reserve(8);
Ed Tanousdaf36e22018-04-20 16:01:36 -0700200
Ed Tanous1abe55e2018-09-05 08:30:59 -0700201 for (const auto& objDictEntry : resp)
202 {
203 const std::string& objectPath =
204 static_cast<const std::string&>(objDictEntry.first);
205 boost::algorithm::split(split, objectPath, boost::is_any_of("/"));
206 if (split.size() < 2)
207 {
208 BMCWEB_LOG_ERROR << "Got path that isn't long enough "
209 << objectPath;
210 split.clear();
211 continue;
212 }
213 const std::string& sensorName = split.end()[-1];
214 const std::string& chassisName = split.end()[-2];
Ed Tanousdaf36e22018-04-20 16:01:36 -0700215
Ed Tanous1abe55e2018-09-05 08:30:59 -0700216 if (chassisName != SensorsAsyncResp->chassisId)
217 {
218 split.clear();
219 continue;
220 }
221 BMCWEB_LOG_DEBUG << "New sensor: " << sensorName;
222 foundChassis = true;
223 sensorNames.emplace(sensorName);
224 split.clear();
225 };
226 BMCWEB_LOG_DEBUG << "Found " << sensorNames.size() << " Sensor names";
227
228 if (!foundChassis)
229 {
230 BMCWEB_LOG_INFO << "Unable to find chassis named "
231 << SensorsAsyncResp->chassisId;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700232 messages::resourceNotFound(SensorsAsyncResp->res, "Chassis",
233 SensorsAsyncResp->chassisId);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700234 }
235 else
236 {
237 callback(sensorNames);
238 }
239 BMCWEB_LOG_DEBUG << "getChassis respHandler exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100240 };
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100241
Ed Tanous1abe55e2018-09-05 08:30:59 -0700242 // Make call to EntityManager to find all chassis objects
243 crow::connections::systemBus->async_method_call(
244 respHandler, "xyz.openbmc_project.EntityManager", "/",
245 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
246 BMCWEB_LOG_DEBUG << "getChassis exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100247}
248
249/**
250 * @brief Builds a json sensor representation of a sensor.
251 * @param sensorName The name of the sensor to be built
Gunnar Mills274fad52018-06-13 15:45:36 -0500252 * @param sensorType The type (temperature, fan_tach, etc) of the sensor to
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100253 * build
254 * @param interfacesDict A dictionary of the interfaces and properties of said
255 * interfaces to be built from
256 * @param sensor_json The json object to fill
257 */
258void objectInterfacesToJson(
259 const std::string& sensorName, const std::string& sensorType,
260 const boost::container::flat_map<
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700261 std::string, boost::container::flat_map<std::string, SensorVariant>>&
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100262 interfacesDict,
Ed Tanous1abe55e2018-09-05 08:30:59 -0700263 nlohmann::json& sensor_json)
264{
265 // We need a value interface before we can do anything with it
266 auto valueIt = interfacesDict.find("xyz.openbmc_project.Sensor.Value");
267 if (valueIt == interfacesDict.end())
268 {
269 BMCWEB_LOG_ERROR << "Sensor doesn't have a value interface";
270 return;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100271 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100272
Ed Tanous1abe55e2018-09-05 08:30:59 -0700273 // Assume values exist as is (10^0 == 1) if no scale exists
274 int64_t scaleMultiplier = 0;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100275
Ed Tanous1abe55e2018-09-05 08:30:59 -0700276 auto scaleIt = valueIt->second.find("Scale");
277 // If a scale exists, pull value as int64, and use the scaling.
278 if (scaleIt != valueIt->second.end())
279 {
280 const int64_t* int64Value =
281 mapbox::getPtr<const int64_t>(scaleIt->second);
282 if (int64Value != nullptr)
283 {
284 scaleMultiplier = *int64Value;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100285 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100286 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700287
288 sensor_json["MemberId"] = sensorName;
289 sensor_json["Name"] = sensorName;
290 sensor_json["Status"]["State"] = "Enabled";
291 sensor_json["Status"]["Health"] = "OK";
292
293 // Parameter to set to override the type we get from dbus, and force it to
294 // int, regardless of what is available. This is used for schemas like fan,
295 // that require integers, not floats.
296 bool forceToInt = false;
297
298 const char* unit = "Reading";
299 if (sensorType == "temperature")
300 {
301 unit = "ReadingCelsius";
302 sensor_json["@odata.type"] = "#Thermal.v1_3_0.Temperature";
303 // TODO(ed) Documentation says that path should be type fan_tach,
304 // implementation seems to implement fan
305 }
306 else if (sensorType == "fan" || sensorType == "fan_tach")
307 {
308 unit = "Reading";
309 sensor_json["ReadingUnits"] = "RPM";
310 sensor_json["@odata.type"] = "#Thermal.v1_3_0.Fan";
311 forceToInt = true;
312 }
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700313 else if (sensorType == "fan_pwm")
314 {
315 unit = "Reading";
316 sensor_json["ReadingUnits"] = "Percent";
317 sensor_json["@odata.type"] = "#Thermal.v1_3_0.Fan";
318 forceToInt = true;
319 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700320 else if (sensorType == "voltage")
321 {
322 unit = "ReadingVolts";
323 sensor_json["@odata.type"] = "#Power.v1_0_0.Voltage";
324 }
Ed Tanous2474adf2018-09-05 16:31:16 -0700325 else if (sensorType == "power")
326 {
327 unit = "LastPowerOutputWatts";
328 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700329 else
330 {
331 BMCWEB_LOG_ERROR << "Redfish cannot map object type for " << sensorName;
332 return;
333 }
334 // Map of dbus interface name, dbus property name and redfish property_name
335 std::vector<std::tuple<const char*, const char*, const char*>> properties;
336 properties.reserve(7);
337
338 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit);
339 properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
340 "WarningHigh", "UpperThresholdNonCritical");
341 properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
342 "WarningLow", "LowerThresholdNonCritical");
343 properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
344 "CriticalHigh", "UpperThresholdCritical");
345 properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
346 "CriticalLow", "LowerThresholdCritical");
347
Ed Tanous2474adf2018-09-05 16:31:16 -0700348 // TODO Need to get UpperThresholdFatal and LowerThresholdFatal
349
Ed Tanous1abe55e2018-09-05 08:30:59 -0700350 if (sensorType == "temperature")
351 {
352 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
353 "MinReadingRangeTemp");
354 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
355 "MaxReadingRangeTemp");
356 }
357 else
358 {
359 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
360 "MinReadingRange");
361 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
362 "MaxReadingRange");
363 }
364
365 for (const std::tuple<const char*, const char*, const char*>& p :
366 properties)
367 {
368 auto interfaceProperties = interfacesDict.find(std::get<0>(p));
369 if (interfaceProperties != interfacesDict.end())
370 {
371 auto valueIt = interfaceProperties->second.find(std::get<1>(p));
372 if (valueIt != interfaceProperties->second.end())
373 {
374 const SensorVariant& valueVariant = valueIt->second;
375 nlohmann::json& valueIt = sensor_json[std::get<2>(p)];
Ed Tanous1abe55e2018-09-05 08:30:59 -0700376 // Attempt to pull the int64 directly
377 const int64_t* int64Value =
378 mapbox::getPtr<const int64_t>(valueVariant);
379
Ed Tanous1abe55e2018-09-05 08:30:59 -0700380 const double* doubleValue =
381 mapbox::getPtr<const double>(valueVariant);
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700382 double temp = 0.0;
383 if (int64Value != nullptr)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700384 {
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700385 temp = *int64Value;
386 }
387 else if (doubleValue != nullptr)
388 {
389 temp = *doubleValue;
390 }
391 else
392 {
393 BMCWEB_LOG_ERROR
394 << "Got value interface that wasn't int or double";
395 continue;
396 }
397 temp = temp * std::pow(10, scaleMultiplier);
398 if (forceToInt)
399 {
400 valueIt = static_cast<int64_t>(temp);
401 }
402 else
403 {
404 valueIt = temp;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700405 }
406 }
407 }
408 }
409 BMCWEB_LOG_DEBUG << "Added sensor " << sensorName;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100410}
411
412/**
413 * @brief Entry point for retrieving sensors data related to requested
414 * chassis.
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200415 * @param SensorsAsyncResp Pointer to object holding response data
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100416 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700417void getChassisData(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp)
418{
419 BMCWEB_LOG_DEBUG << "getChassisData enter";
420 auto getChassisCb = [&, SensorsAsyncResp](
421 boost::container::flat_set<std::string>&
422 sensorNames) {
423 BMCWEB_LOG_DEBUG << "getChassisCb enter";
424 auto getConnectionCb =
425 [&, SensorsAsyncResp, sensorNames](
426 const boost::container::flat_set<std::string>& connections) {
427 BMCWEB_LOG_DEBUG << "getConnectionCb enter";
428 // Get managed objects from all services exposing sensors
429 for (const std::string& connection : connections)
430 {
431 // Response handler to process managed objects
432 auto getManagedObjectsCb =
433 [&, SensorsAsyncResp,
434 sensorNames](const boost::system::error_code ec,
435 ManagedObjectsVectorType& resp) {
436 BMCWEB_LOG_DEBUG << "getManagedObjectsCb enter";
437 if (ec)
438 {
439 BMCWEB_LOG_ERROR
440 << "getManagedObjectsCb DBUS error: " << ec;
441 SensorsAsyncResp->setErrorStatus();
442 return;
443 }
444 // Go through all objects and update response with
445 // sensor data
446 for (const auto& objDictEntry : resp)
447 {
448 const std::string& objPath =
449 static_cast<const std::string&>(
450 objDictEntry.first);
451 BMCWEB_LOG_DEBUG
452 << "getManagedObjectsCb parsing object "
453 << objPath;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100454
Ed Tanous1abe55e2018-09-05 08:30:59 -0700455 std::vector<std::string> split;
456 // Reserve space for
457 // /xyz/openbmc_project/sensors/<name>/<subname>
458 split.reserve(6);
459 boost::algorithm::split(split, objPath,
460 boost::is_any_of("/"));
461 if (split.size() < 6)
462 {
463 BMCWEB_LOG_ERROR
464 << "Got path that isn't long enough "
465 << objPath;
466 continue;
467 }
468 // These indexes aren't intuitive, as
469 // boost::split puts an empty string at the
470 // beggining
471 const std::string& sensorType = split[4];
472 const std::string& sensorName = split[5];
473 BMCWEB_LOG_DEBUG << "sensorName " << sensorName
474 << " sensorType "
475 << sensorType;
476 if (sensorNames.find(sensorName) ==
477 sensorNames.end())
478 {
479 BMCWEB_LOG_ERROR << sensorName
480 << " not in sensor list ";
481 continue;
482 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100483
Ed Tanous1abe55e2018-09-05 08:30:59 -0700484 const char* fieldName = nullptr;
485 if (sensorType == "temperature")
486 {
487 fieldName = "Temperatures";
488 }
489 else if (sensorType == "fan" ||
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700490 sensorType == "fan_tach" ||
491 sensorType == "fan_pwm")
Ed Tanous1abe55e2018-09-05 08:30:59 -0700492 {
493 fieldName = "Fans";
494 }
495 else if (sensorType == "voltage")
496 {
497 fieldName = "Voltages";
498 }
499 else if (sensorType == "current")
500 {
501 fieldName = "PowerSupply";
502 }
503 else if (sensorType == "power")
504 {
505 fieldName = "PowerSupply";
506 }
507 else
508 {
509 BMCWEB_LOG_ERROR
510 << "Unsure how to handle sensorType "
511 << sensorType;
512 continue;
513 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100514
Ed Tanous1abe55e2018-09-05 08:30:59 -0700515 nlohmann::json& tempArray =
516 SensorsAsyncResp->res.jsonValue[fieldName];
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100517
Ed Tanous1abe55e2018-09-05 08:30:59 -0700518 tempArray.push_back(
519 {{"@odata.id",
520 "/redfish/v1/Chassis/" +
Ed Tanous2474adf2018-09-05 16:31:16 -0700521 SensorsAsyncResp->chassisId + "/" +
522 SensorsAsyncResp->chassisSubNode +
523 "#/" + fieldName + "/" +
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700524 std::to_string(tempArray.size())}});
Ed Tanous1abe55e2018-09-05 08:30:59 -0700525 nlohmann::json& sensorJson = tempArray.back();
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700526
Ed Tanous1abe55e2018-09-05 08:30:59 -0700527 objectInterfacesToJson(sensorName, sensorType,
528 objDictEntry.second,
529 sensorJson);
530 }
531 BMCWEB_LOG_DEBUG << "getManagedObjectsCb exit";
532 };
533 crow::connections::systemBus->async_method_call(
534 getManagedObjectsCb, connection, "/",
535 "org.freedesktop.DBus.ObjectManager",
536 "GetManagedObjects");
537 };
538 BMCWEB_LOG_DEBUG << "getConnectionCb exit";
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200539 };
Ed Tanous1abe55e2018-09-05 08:30:59 -0700540 // get connections and then pass it to get sensors
541 getConnections(SensorsAsyncResp, sensorNames,
542 std::move(getConnectionCb));
543 BMCWEB_LOG_DEBUG << "getChassisCb exit";
544 };
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100545
Ed Tanous1abe55e2018-09-05 08:30:59 -0700546 // get chassis information related to sensors
547 getChassis(SensorsAsyncResp, std::move(getChassisCb));
548 BMCWEB_LOG_DEBUG << "getChassisData exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100549};
550
Ed Tanous1abe55e2018-09-05 08:30:59 -0700551} // namespace redfish