blob: b689f09664975c4fa2ecd388dbbee088ece16647 [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 crow::Response& res;
72 std::string chassisId{};
73 const std::vector<const char*> types;
Ed Tanous2474adf2018-09-05 16:31:16 -070074 std::string chassisSubNode{};
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010075};
76
77/**
78 * @brief Creates connections necessary for chassis sensors
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020079 * @param SensorsAsyncResp Pointer to object holding response data
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010080 * @param sensorNames Sensors retrieved from chassis
81 * @param callback Callback for processing gathered connections
82 */
83template <typename Callback>
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020084void getConnections(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp,
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010085 const boost::container::flat_set<std::string>& sensorNames,
Ed Tanous1abe55e2018-09-05 08:30:59 -070086 Callback&& callback)
87{
88 BMCWEB_LOG_DEBUG << "getConnections enter";
89 const std::string path = "/xyz/openbmc_project/sensors";
90 const std::array<std::string, 1> interfaces = {
91 "xyz.openbmc_project.Sensor.Value"};
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010092
Ed Tanous1abe55e2018-09-05 08:30:59 -070093 // Response handler for parsing objects subtree
94 auto respHandler = [callback{std::move(callback)}, SensorsAsyncResp,
95 sensorNames](const boost::system::error_code ec,
96 const GetSubTreeType& subtree) {
97 BMCWEB_LOG_DEBUG << "getConnections resp_handler enter";
98 if (ec)
99 {
Ed Tanous5f7d88c2018-11-14 14:08:56 -0800100 messages::internalError(SensorsAsyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700101 BMCWEB_LOG_ERROR << "getConnections resp_handler: Dbus error "
102 << ec;
103 return;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100104 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100105
Ed Tanous1abe55e2018-09-05 08:30:59 -0700106 BMCWEB_LOG_DEBUG << "Found " << subtree.size() << " subtrees";
107
108 // Make unique list of connections only for requested sensor types and
109 // found in the chassis
110 boost::container::flat_set<std::string> connections;
111 // Intrinsic to avoid malloc. Most systems will have < 8 sensor
112 // producers
113 connections.reserve(8);
114
115 BMCWEB_LOG_DEBUG << "sensorNames list count: " << sensorNames.size();
116 for (const std::string& tsensor : sensorNames)
117 {
118 BMCWEB_LOG_DEBUG << "Sensor to find: " << tsensor;
119 }
120
121 for (const std::pair<
122 std::string,
123 std::vector<std::pair<std::string, std::vector<std::string>>>>&
124 object : subtree)
125 {
126 for (const char* type : SensorsAsyncResp->types)
127 {
128 if (boost::starts_with(object.first, type))
129 {
130 auto lastPos = object.first.rfind('/');
131 if (lastPos != std::string::npos)
132 {
133 std::string sensorName =
134 object.first.substr(lastPos + 1);
135
136 if (sensorNames.find(sensorName) != sensorNames.end())
137 {
138 // For each Connection name
139 for (const std::pair<std::string,
140 std::vector<std::string>>&
141 objData : object.second)
142 {
143 BMCWEB_LOG_DEBUG << "Adding connection: "
144 << objData.first;
145 connections.insert(objData.first);
146 }
147 }
148 }
149 break;
150 }
151 }
152 }
153 BMCWEB_LOG_DEBUG << "Found " << connections.size() << " connections";
154 callback(std::move(connections));
155 BMCWEB_LOG_DEBUG << "getConnections resp_handler exit";
156 };
157
158 // Make call to ObjectMapper to find all sensors objects
159 crow::connections::systemBus->async_method_call(
160 std::move(respHandler), "xyz.openbmc_project.ObjectMapper",
161 "/xyz/openbmc_project/object_mapper",
162 "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, 2, interfaces);
163 BMCWEB_LOG_DEBUG << "getConnections exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100164}
165
166/**
167 * @brief Retrieves requested chassis sensors and redundancy data from DBus .
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200168 * @param SensorsAsyncResp Pointer to object holding response data
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100169 * @param callback Callback for next step in gathered sensor processing
170 */
171template <typename Callback>
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200172void getChassis(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp,
Ed Tanous1abe55e2018-09-05 08:30:59 -0700173 Callback&& callback)
174{
175 BMCWEB_LOG_DEBUG << "getChassis enter";
176 // Process response from EntityManager and extract chassis data
177 auto respHandler = [callback{std::move(callback)},
178 SensorsAsyncResp](const boost::system::error_code ec,
179 ManagedObjectsVectorType& resp) {
180 BMCWEB_LOG_DEBUG << "getChassis respHandler enter";
181 if (ec)
182 {
183 BMCWEB_LOG_ERROR << "getChassis respHandler DBUS error: " << ec;
Ed Tanous5f7d88c2018-11-14 14:08:56 -0800184 messages::internalError(SensorsAsyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700185 return;
186 }
187 boost::container::flat_set<std::string> sensorNames;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100188
Ed Tanous1abe55e2018-09-05 08:30:59 -0700189 // SensorsAsyncResp->chassisId
190 bool foundChassis = false;
191 std::vector<std::string> split;
192 // Reserve space for
193 // /xyz/openbmc_project/inventory/<name>/<subname> + 3 subnames
194 split.reserve(8);
Ed Tanousdaf36e22018-04-20 16:01:36 -0700195
Ed Tanous1abe55e2018-09-05 08:30:59 -0700196 for (const auto& objDictEntry : resp)
197 {
198 const std::string& objectPath =
199 static_cast<const std::string&>(objDictEntry.first);
200 boost::algorithm::split(split, objectPath, boost::is_any_of("/"));
201 if (split.size() < 2)
202 {
203 BMCWEB_LOG_ERROR << "Got path that isn't long enough "
204 << objectPath;
205 split.clear();
206 continue;
207 }
208 const std::string& sensorName = split.end()[-1];
209 const std::string& chassisName = split.end()[-2];
Ed Tanousdaf36e22018-04-20 16:01:36 -0700210
Ed Tanous1abe55e2018-09-05 08:30:59 -0700211 if (chassisName != SensorsAsyncResp->chassisId)
212 {
213 split.clear();
214 continue;
215 }
216 BMCWEB_LOG_DEBUG << "New sensor: " << sensorName;
217 foundChassis = true;
218 sensorNames.emplace(sensorName);
219 split.clear();
220 };
221 BMCWEB_LOG_DEBUG << "Found " << sensorNames.size() << " Sensor names";
222
223 if (!foundChassis)
224 {
225 BMCWEB_LOG_INFO << "Unable to find chassis named "
226 << SensorsAsyncResp->chassisId;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700227 messages::resourceNotFound(SensorsAsyncResp->res, "Chassis",
228 SensorsAsyncResp->chassisId);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700229 }
230 else
231 {
232 callback(sensorNames);
233 }
234 BMCWEB_LOG_DEBUG << "getChassis respHandler exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100235 };
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100236
Ed Tanous1abe55e2018-09-05 08:30:59 -0700237 // Make call to EntityManager to find all chassis objects
238 crow::connections::systemBus->async_method_call(
239 respHandler, "xyz.openbmc_project.EntityManager", "/",
240 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
241 BMCWEB_LOG_DEBUG << "getChassis exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100242}
243
244/**
245 * @brief Builds a json sensor representation of a sensor.
246 * @param sensorName The name of the sensor to be built
Gunnar Mills274fad52018-06-13 15:45:36 -0500247 * @param sensorType The type (temperature, fan_tach, etc) of the sensor to
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100248 * build
249 * @param interfacesDict A dictionary of the interfaces and properties of said
250 * interfaces to be built from
251 * @param sensor_json The json object to fill
252 */
253void objectInterfacesToJson(
254 const std::string& sensorName, const std::string& sensorType,
255 const boost::container::flat_map<
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700256 std::string, boost::container::flat_map<std::string, SensorVariant>>&
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100257 interfacesDict,
Ed Tanous1abe55e2018-09-05 08:30:59 -0700258 nlohmann::json& sensor_json)
259{
260 // We need a value interface before we can do anything with it
261 auto valueIt = interfacesDict.find("xyz.openbmc_project.Sensor.Value");
262 if (valueIt == interfacesDict.end())
263 {
264 BMCWEB_LOG_ERROR << "Sensor doesn't have a value interface";
265 return;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100266 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100267
Ed Tanous1abe55e2018-09-05 08:30:59 -0700268 // Assume values exist as is (10^0 == 1) if no scale exists
269 int64_t scaleMultiplier = 0;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100270
Ed Tanous1abe55e2018-09-05 08:30:59 -0700271 auto scaleIt = valueIt->second.find("Scale");
272 // If a scale exists, pull value as int64, and use the scaling.
273 if (scaleIt != valueIt->second.end())
274 {
275 const int64_t* int64Value =
276 mapbox::getPtr<const int64_t>(scaleIt->second);
277 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
372 const int64_t* int64Value =
373 mapbox::getPtr<const int64_t>(valueVariant);
374
Ed Tanous1abe55e2018-09-05 08:30:59 -0700375 const double* doubleValue =
376 mapbox::getPtr<const double>(valueVariant);
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700377 double temp = 0.0;
378 if (int64Value != nullptr)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700379 {
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700380 temp = *int64Value;
381 }
382 else if (doubleValue != nullptr)
383 {
384 temp = *doubleValue;
385 }
386 else
387 {
388 BMCWEB_LOG_ERROR
389 << "Got value interface that wasn't int or double";
390 continue;
391 }
392 temp = temp * std::pow(10, scaleMultiplier);
393 if (forceToInt)
394 {
395 valueIt = static_cast<int64_t>(temp);
396 }
397 else
398 {
399 valueIt = temp;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700400 }
401 }
402 }
403 }
404 BMCWEB_LOG_DEBUG << "Added sensor " << sensorName;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100405}
406
407/**
408 * @brief Entry point for retrieving sensors data related to requested
409 * chassis.
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200410 * @param SensorsAsyncResp Pointer to object holding response data
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100411 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700412void getChassisData(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp)
413{
414 BMCWEB_LOG_DEBUG << "getChassisData enter";
415 auto getChassisCb = [&, SensorsAsyncResp](
416 boost::container::flat_set<std::string>&
417 sensorNames) {
418 BMCWEB_LOG_DEBUG << "getChassisCb enter";
419 auto getConnectionCb =
420 [&, SensorsAsyncResp, sensorNames](
421 const boost::container::flat_set<std::string>& connections) {
422 BMCWEB_LOG_DEBUG << "getConnectionCb enter";
423 // Get managed objects from all services exposing sensors
424 for (const std::string& connection : connections)
425 {
426 // Response handler to process managed objects
427 auto getManagedObjectsCb =
428 [&, SensorsAsyncResp,
429 sensorNames](const boost::system::error_code ec,
430 ManagedObjectsVectorType& resp) {
431 BMCWEB_LOG_DEBUG << "getManagedObjectsCb enter";
432 if (ec)
433 {
434 BMCWEB_LOG_ERROR
435 << "getManagedObjectsCb DBUS error: " << ec;
Ed Tanous5f7d88c2018-11-14 14:08:56 -0800436 messages::internalError(SensorsAsyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700437 return;
438 }
439 // Go through all objects and update response with
440 // sensor data
441 for (const auto& objDictEntry : resp)
442 {
443 const std::string& objPath =
444 static_cast<const std::string&>(
445 objDictEntry.first);
446 BMCWEB_LOG_DEBUG
447 << "getManagedObjectsCb parsing object "
448 << objPath;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100449
Ed Tanous1abe55e2018-09-05 08:30:59 -0700450 std::vector<std::string> split;
451 // Reserve space for
452 // /xyz/openbmc_project/sensors/<name>/<subname>
453 split.reserve(6);
454 boost::algorithm::split(split, objPath,
455 boost::is_any_of("/"));
456 if (split.size() < 6)
457 {
458 BMCWEB_LOG_ERROR
459 << "Got path that isn't long enough "
460 << objPath;
461 continue;
462 }
463 // These indexes aren't intuitive, as
464 // boost::split puts an empty string at the
465 // beggining
466 const std::string& sensorType = split[4];
467 const std::string& sensorName = split[5];
468 BMCWEB_LOG_DEBUG << "sensorName " << sensorName
469 << " sensorType "
470 << sensorType;
471 if (sensorNames.find(sensorName) ==
472 sensorNames.end())
473 {
474 BMCWEB_LOG_ERROR << sensorName
475 << " not in sensor list ";
476 continue;
477 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100478
Ed Tanous1abe55e2018-09-05 08:30:59 -0700479 const char* fieldName = nullptr;
480 if (sensorType == "temperature")
481 {
482 fieldName = "Temperatures";
483 }
484 else if (sensorType == "fan" ||
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700485 sensorType == "fan_tach" ||
486 sensorType == "fan_pwm")
Ed Tanous1abe55e2018-09-05 08:30:59 -0700487 {
488 fieldName = "Fans";
489 }
490 else if (sensorType == "voltage")
491 {
492 fieldName = "Voltages";
493 }
494 else if (sensorType == "current")
495 {
496 fieldName = "PowerSupply";
497 }
498 else if (sensorType == "power")
499 {
500 fieldName = "PowerSupply";
501 }
502 else
503 {
504 BMCWEB_LOG_ERROR
505 << "Unsure how to handle sensorType "
506 << sensorType;
507 continue;
508 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100509
Ed Tanous1abe55e2018-09-05 08:30:59 -0700510 nlohmann::json& tempArray =
511 SensorsAsyncResp->res.jsonValue[fieldName];
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100512
Ed Tanous1abe55e2018-09-05 08:30:59 -0700513 tempArray.push_back(
514 {{"@odata.id",
515 "/redfish/v1/Chassis/" +
Ed Tanous2474adf2018-09-05 16:31:16 -0700516 SensorsAsyncResp->chassisId + "/" +
517 SensorsAsyncResp->chassisSubNode +
518 "#/" + fieldName + "/" +
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700519 std::to_string(tempArray.size())}});
Ed Tanous1abe55e2018-09-05 08:30:59 -0700520 nlohmann::json& sensorJson = tempArray.back();
Ed Tanous6f6d0d32018-10-12 11:16:43 -0700521
Ed Tanous1abe55e2018-09-05 08:30:59 -0700522 objectInterfacesToJson(sensorName, sensorType,
523 objDictEntry.second,
524 sensorJson);
525 }
526 BMCWEB_LOG_DEBUG << "getManagedObjectsCb exit";
527 };
528 crow::connections::systemBus->async_method_call(
529 getManagedObjectsCb, connection, "/",
530 "org.freedesktop.DBus.ObjectManager",
531 "GetManagedObjects");
532 };
533 BMCWEB_LOG_DEBUG << "getConnectionCb exit";
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200534 };
Ed Tanous1abe55e2018-09-05 08:30:59 -0700535 // get connections and then pass it to get sensors
536 getConnections(SensorsAsyncResp, sensorNames,
537 std::move(getConnectionCb));
538 BMCWEB_LOG_DEBUG << "getChassisCb exit";
539 };
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100540
Ed Tanous1abe55e2018-09-05 08:30:59 -0700541 // get chassis information related to sensors
542 getChassis(SensorsAsyncResp, std::move(getChassisCb));
543 BMCWEB_LOG_DEBUG << "getChassisData exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100544};
545
Ed Tanous1abe55e2018-09-05 08:30:59 -0700546} // namespace redfish