blob: a6c5fbd48f8edc73de004500c80728af881a5c30 [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>
19#include <dbus_singleton.hpp>
20#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>
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010024
25namespace redfish {
26
27constexpr const char* DBUS_SENSOR_PREFIX = "/xyz/openbmc_project/Sensors/";
28
29using GetSubTreeType = std::vector<
30 std::pair<std::string,
31 std::vector<std::pair<std::string, std::vector<std::string>>>>>;
32
Ed Tanousaa2e59c2018-04-12 12:17:20 -070033using SensorVariant = sdbusplus::message::variant<int64_t, double>;
34
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010035using ManagedObjectsVectorType = std::vector<std::pair<
Ed Tanousaa2e59c2018-04-12 12:17:20 -070036 sdbusplus::message::object_path,
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010037 boost::container::flat_map<
Ed Tanousaa2e59c2018-04-12 12:17:20 -070038 std::string, boost::container::flat_map<std::string, SensorVariant>>>>;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010039
40/**
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020041 * SensorsAsyncResp
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010042 * Gathers data needed for response processing after async calls are done
43 */
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020044class SensorsAsyncResp {
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010045 public:
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020046 SensorsAsyncResp(crow::response& response, const std::string& chassisId,
47 const std::initializer_list<const char*> types)
48 : res(response), chassisId(chassisId), types(types) {
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010049 res.json_value["@odata.id"] =
50 "/redfish/v1/Chassis/" + chassisId + "/Thermal";
51 }
52
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020053 ~SensorsAsyncResp() {
Ed Tanouse0d918b2018-03-27 17:41:04 -070054 if (res.result() == boost::beast::http::status::internal_server_error) {
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010055 // Reset the json object to clear out any data that made it in before the
56 // error happened
57 // todo(ed) handle error condition with proper code
58 res.json_value = nlohmann::json::object();
59 }
60 res.end();
61 }
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020062
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010063 void setErrorStatus() {
Ed Tanouse0d918b2018-03-27 17:41:04 -070064 res.result(boost::beast::http::status::internal_server_error);
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010065 }
66
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010067 crow::response& res;
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020068 std::string chassisId{};
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010069 const std::vector<const char*> types;
70};
71
72/**
73 * @brief Creates connections necessary for chassis sensors
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020074 * @param SensorsAsyncResp Pointer to object holding response data
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010075 * @param sensorNames Sensors retrieved from chassis
76 * @param callback Callback for processing gathered connections
77 */
78template <typename Callback>
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020079void getConnections(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp,
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010080 const boost::container::flat_set<std::string>& sensorNames,
81 Callback&& callback) {
Lewanczyk, Dawid78859542018-06-11 16:58:40 +020082 CROW_LOG_DEBUG << "getConnections enter";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010083 const std::string path = "/xyz/openbmc_project/Sensors";
84 const std::array<std::string, 1> interfaces = {
85 "xyz.openbmc_project.Sensor.Value"};
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010086
87 // Response handler for parsing objects subtree
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020088 auto resp_handler =
89 [ callback{std::move(callback)}, SensorsAsyncResp, sensorNames ](
90 const boost::system::error_code ec, const GetSubTreeType& subtree) {
Lewanczyk, Dawid78859542018-06-11 16:58:40 +020091 CROW_LOG_DEBUG << "getConnections resp_handler enter";
Ed Tanouse0d918b2018-03-27 17:41:04 -070092 if (ec) {
Kowalski, Kamil588c3f02018-04-03 14:55:27 +020093 SensorsAsyncResp->setErrorStatus();
Lewanczyk, Dawid78859542018-06-11 16:58:40 +020094 CROW_LOG_ERROR << "getConnections resp_handler: Dbus error " << ec;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +010095 return;
96 }
97
98 CROW_LOG_DEBUG << "Found " << subtree.size() << " subtrees";
99
100 // Make unique list of connections only for requested sensor types and
101 // found in the chassis
102 boost::container::flat_set<std::string> connections;
103 // Intrinsic to avoid malloc. Most systems will have < 8 sensor producers
104 connections.reserve(8);
105
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200106 CROW_LOG_DEBUG << "sensorNames list count: " << sensorNames.size();
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100107 for (const std::string& tsensor : sensorNames) {
108 CROW_LOG_DEBUG << "Sensor to find: " << tsensor;
109 }
110
111 for (const std::pair<
112 std::string,
113 std::vector<std::pair<std::string, std::vector<std::string>>>>&
114 object : subtree) {
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200115 for (const char* type : SensorsAsyncResp->types) {
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100116 if (boost::starts_with(object.first, type)) {
117 auto lastPos = object.first.rfind('/');
118 if (lastPos != std::string::npos) {
119 std::string sensorName = object.first.substr(lastPos + 1);
120
121 if (sensorNames.find(sensorName) != sensorNames.end()) {
122 // For each connection name
123 for (const std::pair<std::string, std::vector<std::string>>&
124 objData : object.second) {
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200125 CROW_LOG_DEBUG << "Adding connection: " << objData.first;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100126 connections.insert(objData.first);
127 }
128 }
129 }
130 break;
131 }
132 }
133 }
134 CROW_LOG_DEBUG << "Found " << connections.size() << " connections";
135 callback(std::move(connections));
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200136 CROW_LOG_DEBUG << "getConnections resp_handler exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100137 };
138
139 // Make call to ObjectMapper to find all sensors objects
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700140 crow::connections::system_bus->async_method_call(
Ed Tanousdaf36e22018-04-20 16:01:36 -0700141 std::move(resp_handler), "xyz.openbmc_project.ObjectMapper",
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700142 "/xyz/openbmc_project/object_mapper", "xyz.openbmc_project.ObjectMapper",
143 "GetSubTree", path, 2, interfaces);
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200144 CROW_LOG_DEBUG << "getConnections exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100145}
146
147/**
148 * @brief Retrieves requested chassis sensors and redundancy data from DBus .
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200149 * @param SensorsAsyncResp Pointer to object holding response data
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100150 * @param callback Callback for next step in gathered sensor processing
151 */
152template <typename Callback>
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200153void getChassis(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp,
154 Callback&& callback) {
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200155 CROW_LOG_DEBUG << "getChassis enter";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100156 // Process response from EntityManager and extract chassis data
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200157 auto resp_handler = [ callback{std::move(callback)}, SensorsAsyncResp ](
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100158 const boost::system::error_code ec, ManagedObjectsVectorType& resp) {
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200159 CROW_LOG_DEBUG << "getChassis resp_handler enter";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100160 if (ec) {
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200161 CROW_LOG_ERROR << "getChassis resp_handler DBUS error: " << ec;
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200162 SensorsAsyncResp->setErrorStatus();
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100163 return;
164 }
165 boost::container::flat_set<std::string> sensorNames;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100166
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200167 // SensorsAsyncResp->chassisId
Ed Tanousdaf36e22018-04-20 16:01:36 -0700168 bool foundChassis = false;
169 std::vector<std::string> split;
170 // Reserve space for
171 // /xyz/openbmc_project/inventory/<name>/<subname> + 3 subnames
172 split.reserve(8);
173
174 for (const auto& objDictEntry : resp) {
175 const std::string& objectPath =
176 static_cast<const std::string&>(objDictEntry.first);
177 boost::algorithm::split(split, objectPath, boost::is_any_of("/"));
178 if (split.size() < 2) {
179 CROW_LOG_ERROR << "Got path that isn't long enough " << objectPath;
180 split.clear();
181 continue;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100182 }
Ed Tanousdaf36e22018-04-20 16:01:36 -0700183 const std::string& sensorName = split.end()[-1];
184 const std::string& chassisName = split.end()[-2];
185
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200186 if (chassisName != SensorsAsyncResp->chassisId) {
Ed Tanousdaf36e22018-04-20 16:01:36 -0700187 split.clear();
188 continue;
189 }
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200190 CROW_LOG_DEBUG << "New sensor: " << sensorName;
Ed Tanousdaf36e22018-04-20 16:01:36 -0700191 foundChassis = true;
192 sensorNames.emplace(sensorName);
193 split.clear();
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100194 };
195 CROW_LOG_DEBUG << "Found " << sensorNames.size() << " Sensor names";
196
197 if (!foundChassis) {
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200198 CROW_LOG_INFO << "Unable to find chassis named "
199 << SensorsAsyncResp->chassisId;
200 SensorsAsyncResp->res.result(boost::beast::http::status::not_found);
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100201 } else {
202 callback(sensorNames);
203 }
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200204 CROW_LOG_DEBUG << "getChassis resp_handler exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100205 };
206
207 // Make call to EntityManager to find all chassis objects
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700208 crow::connections::system_bus->async_method_call(
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200209 resp_handler, "xyz.openbmc_project.EntityManager", "/",
210 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
211 CROW_LOG_DEBUG << "getChassis exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100212}
213
214/**
215 * @brief Builds a json sensor representation of a sensor.
216 * @param sensorName The name of the sensor to be built
Gunnar Mills274fad52018-06-13 15:45:36 -0500217 * @param sensorType The type (temperature, fan_tach, etc) of the sensor to
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100218 * build
219 * @param interfacesDict A dictionary of the interfaces and properties of said
220 * interfaces to be built from
221 * @param sensor_json The json object to fill
222 */
223void objectInterfacesToJson(
224 const std::string& sensorName, const std::string& sensorType,
225 const boost::container::flat_map<
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700226 std::string, boost::container::flat_map<std::string, SensorVariant>>&
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100227 interfacesDict,
228 nlohmann::json& sensor_json) {
229 // We need a value interface before we can do anything with it
230 auto value_it = interfacesDict.find("xyz.openbmc_project.Sensor.Value");
231 if (value_it == interfacesDict.end()) {
232 CROW_LOG_ERROR << "Sensor doesn't have a value interface";
233 return;
234 }
235
236 // Assume values exist as is (10^0 == 1) if no scale exists
237 int64_t scaleMultiplier = 0;
238
239 auto scale_it = value_it->second.find("Scale");
240 // If a scale exists, pull value as int64, and use the scaling.
241 if (scale_it != value_it->second.end()) {
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700242 const int64_t* int64Value =
243 mapbox::get_ptr<const int64_t>(scale_it->second);
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100244 if (int64Value != nullptr) {
245 scaleMultiplier = *int64Value;
246 }
247 }
248
249 sensor_json["MemberId"] = sensorName;
250 sensor_json["Name"] = sensorName;
251 sensor_json["Status"]["State"] = "Enabled";
252 sensor_json["Status"]["Health"] = "OK";
253
254 // Parameter to set to override the type we get from dbus, and force it to
255 // int, regardless of what is available. This is used for schemas like fan,
256 // that require integers, not floats.
257 bool forceToInt = false;
258
259 const char* unit = "Reading";
260 if (sensorType == "temperature") {
261 unit = "ReadingCelsius";
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200262 sensor_json["@odata.type"] = "#Thermal.v1_3_0.Temperature";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100263 // TODO(ed) Documentation says that path should be type fan_tach,
264 // implementation seems to implement fan
Ed Tanousdaf36e22018-04-20 16:01:36 -0700265 } else if (sensorType == "fan" || sensorType == "fan_type") {
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100266 unit = "Reading";
267 sensor_json["ReadingUnits"] = "RPM";
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200268 sensor_json["@odata.type"] = "#Thermal.v1_3_0.Fan";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100269 forceToInt = true;
270 } else if (sensorType == "voltage") {
271 unit = "ReadingVolts";
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200272 sensor_json["@odata.type"] = "#Power.v1_0_0.Voltage";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100273 } else {
274 CROW_LOG_ERROR << "Redfish cannot map object type for " << sensorName;
275 return;
276 }
277 // Map of dbus interface name, dbus property name and redfish property_name
278 std::vector<std::tuple<const char*, const char*, const char*>> properties;
279 properties.reserve(7);
280
281 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit);
282 properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
283 "WarningHigh", "UpperThresholdNonCritical");
284 properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
285 "WarningLow", "LowerThresholdNonCritical");
286 properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
287 "CriticalHigh", "UpperThresholdCritical");
288 properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
289 "CriticalLow", "LowerThresholdCritical");
290
291 if (sensorType == "temperature") {
292 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
293 "MinReadingRangeTemp");
294 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
295 "MaxReadingRangeTemp");
296 } else {
297 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
298 "MinReadingRange");
299 properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
300 "MaxReadingRange");
301 }
302
303 for (const std::tuple<const char*, const char*, const char*>& p :
304 properties) {
305 auto interfaceProperties = interfacesDict.find(std::get<0>(p));
306 if (interfaceProperties != interfacesDict.end()) {
307 auto value_it = interfaceProperties->second.find(std::get<1>(p));
308 if (value_it != interfaceProperties->second.end()) {
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700309 const SensorVariant& valueVariant = value_it->second;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100310 nlohmann::json& value_it = sensor_json[std::get<2>(p)];
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700311
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100312 // Attempt to pull the int64 directly
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700313 const int64_t* int64Value =
314 mapbox::get_ptr<const int64_t>(valueVariant);
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100315
316 if (int64Value != nullptr) {
317 if (forceToInt || scaleMultiplier >= 0) {
318 value_it = *int64Value * std::pow(10, scaleMultiplier);
319 } else {
320 value_it = *int64Value *
321 std::pow(10, static_cast<double>(scaleMultiplier));
322 }
323 }
324 // Attempt to pull the float directly
Ed Tanousaa2e59c2018-04-12 12:17:20 -0700325 const double* doubleValue = mapbox::get_ptr<const double>(valueVariant);
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100326
327 if (doubleValue != nullptr) {
328 if (!forceToInt) {
329 value_it = *doubleValue *
330 std::pow(10, static_cast<double>(scaleMultiplier));
331 } else {
332 value_it = static_cast<int64_t>(*doubleValue *
333 std::pow(10, scaleMultiplier));
334 }
335 }
336 }
337 }
338 }
Ed Tanouse0d918b2018-03-27 17:41:04 -0700339 CROW_LOG_DEBUG << "Added sensor " << sensorName;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100340}
341
342/**
343 * @brief Entry point for retrieving sensors data related to requested
344 * chassis.
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200345 * @param SensorsAsyncResp Pointer to object holding response data
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100346 */
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200347void getChassisData(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp) {
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200348 CROW_LOG_DEBUG << "getChassisData enter";
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200349 auto getChassisCb = [&, SensorsAsyncResp](
350 boost::container::flat_set<std::string>&
351 sensorNames) {
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200352 CROW_LOG_DEBUG << "getChassisCb enter";
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200353 auto getConnectionCb =
354 [&, SensorsAsyncResp, sensorNames](
355 const boost::container::flat_set<std::string>& connections) {
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200356 CROW_LOG_DEBUG << "getConnectionCb enter";
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200357 // Get managed objects from all services exposing sensors
358 for (const std::string& connection : connections) {
359 // Response handler to process managed objects
360 auto getManagedObjectsCb = [&, SensorsAsyncResp, sensorNames](
361 const boost::system::error_code ec,
362 ManagedObjectsVectorType& resp) {
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200363 CROW_LOG_DEBUG << "getManagedObjectsCb enter";
364 if (ec) {
365 CROW_LOG_ERROR << "getManagedObjectsCb DBUS error: " << ec;
366 SensorsAsyncResp->setErrorStatus();
367 return;
368 }
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200369 // Go through all objects and update response with
370 // sensor data
371 for (const auto& objDictEntry : resp) {
372 const std::string& objPath =
373 static_cast<const std::string&>(objDictEntry.first);
374 CROW_LOG_DEBUG << "getManagedObjectsCb parsing object "
375 << objPath;
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100376
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200377 std::vector<std::string> split;
378 // Reserve space for
379 // /xyz/openbmc_project/Sensors/<name>/<subname>
380 split.reserve(6);
381 boost::algorithm::split(split, objPath, boost::is_any_of("/"));
382 if (split.size() < 6) {
383 CROW_LOG_ERROR << "Got path that isn't long enough "
384 << objPath;
385 continue;
386 }
387 // These indexes aren't intuitive, as boost::split puts an empty
388 // string at the beggining
389 const std::string& sensorType = split[4];
390 const std::string& sensorName = split[5];
391 CROW_LOG_DEBUG << "sensorName " << sensorName << " sensorType "
392 << sensorType;
393 if (sensorNames.find(sensorName) == sensorNames.end()) {
394 CROW_LOG_ERROR << sensorName << " not in sensor list ";
395 continue;
396 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100397
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200398 const char* fieldName = nullptr;
399 if (sensorType == "temperature") {
400 fieldName = "Temperatures";
401 } else if (sensorType == "fan" || sensorType == "fan_tach") {
402 fieldName = "Fans";
403 } else if (sensorType == "voltage") {
404 fieldName = "Voltages";
405 } else if (sensorType == "current") {
406 fieldName = "PowerSupply";
407 } else if (sensorType == "power") {
408 fieldName = "PowerSupply";
409 } else {
410 CROW_LOG_ERROR << "Unsure how to handle sensorType "
411 << sensorType;
412 continue;
413 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100414
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200415 nlohmann::json& temp_array =
416 SensorsAsyncResp->res.json_value[fieldName];
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100417
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200418 // Create the array if it doesn't yet exist
419 if (temp_array.is_array() == false) {
420 temp_array = nlohmann::json::array();
421 }
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100422
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200423 temp_array.push_back(
424 {{"@odata.id", "/redfish/v1/Chassis/" +
425 SensorsAsyncResp->chassisId +
426 "/Thermal#/" + sensorName}});
427 nlohmann::json& sensor_json = temp_array.back();
428 objectInterfacesToJson(sensorName, sensorType,
429 objDictEntry.second, sensor_json);
430 }
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200431 CROW_LOG_DEBUG << "getManagedObjectsCb exit";
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200432 };
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200433 crow::connections::system_bus->async_method_call(
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200434 getManagedObjectsCb, connection, "/",
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200435 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
436 };
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200437 CROW_LOG_DEBUG << "getConnectionCb exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100438 };
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100439 // Get connections and then pass it to get sensors
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200440 getConnections(SensorsAsyncResp, sensorNames, std::move(getConnectionCb));
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200441 CROW_LOG_DEBUG << "getChassisCb exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100442 };
443
444 // Get chassis information related to sensors
Kowalski, Kamil588c3f02018-04-03 14:55:27 +0200445 getChassis(SensorsAsyncResp, std::move(getChassisCb));
Lewanczyk, Dawid78859542018-06-11 16:58:40 +0200446 CROW_LOG_DEBUG << "getChassisData exit";
Lewanczyk, Dawid08777fb2018-03-22 23:33:49 +0100447};
448
449} // namespace redfish