blob: 2eb280fa61b8ead2b48750c40ddf1e36803c667b [file] [log] [blame]
Cheng C Yang209ec562019-03-12 16:37:44 +08001/*
2// Copyright (c) 2019 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*/
Josh Lehan0830c7b2019-10-08 16:35:09 -070016
Cheng C Yang58b2b532019-05-31 00:19:45 +080017#include <PSUEvent.hpp>
Cheng C Yang209ec562019-03-12 16:37:44 +080018#include <PSUSensor.hpp>
19#include <Utils.hpp>
20#include <boost/algorithm/string/predicate.hpp>
21#include <boost/algorithm/string/replace.hpp>
22#include <boost/container/flat_set.hpp>
James Feist24f02f22019-04-15 11:05:39 -070023#include <filesystem>
Cheng C Yang209ec562019-03-12 16:37:44 +080024#include <fstream>
Cheng C Yang58b2b532019-05-31 00:19:45 +080025#include <iostream>
Cheng C Yang209ec562019-03-12 16:37:44 +080026#include <regex>
27#include <sdbusplus/asio/connection.hpp>
28#include <sdbusplus/asio/object_server.hpp>
29
Josh Lehan49cfba92019-10-08 16:50:42 -070030static constexpr bool DEBUG = false;
31
Josh Lehan0830c7b2019-10-08 16:35:09 -070032static constexpr std::array<const char*, 3> sensorTypes = {
Jason Ling5747fab2019-10-02 16:46:23 -070033 "xyz.openbmc_project.Configuration.pmbus",
Josh Lehan0830c7b2019-10-08 16:35:09 -070034 "xyz.openbmc_project.Configuration.MAX34451",
35 "xyz.openbmc_project.Configuration.ISL68137"};
Cheng C Yang209ec562019-03-12 16:37:44 +080036
Josh Lehan0830c7b2019-10-08 16:35:09 -070037static std::vector<std::string> pmbusNames = {"pmbus", "pxe1610", "ina219",
38 "ina230", "max34451", "isl68137"};
39
Cheng C Yang209ec562019-03-12 16:37:44 +080040namespace fs = std::filesystem;
41
Cheng C Yang916360b2019-05-07 18:47:16 +080042static boost::container::flat_map<std::string, std::unique_ptr<PSUSensor>>
43 sensors;
Cheng C Yang58b2b532019-05-31 00:19:45 +080044static boost::container::flat_map<std::string, std::unique_ptr<PSUCombineEvent>>
45 combineEvents;
Cheng C Yang916360b2019-05-07 18:47:16 +080046static boost::container::flat_map<std::string, std::unique_ptr<PwmSensor>>
47 pwmSensors;
48static boost::container::flat_map<std::string, std::string> sensorTable;
49static boost::container::flat_map<std::string, PSUProperty> labelMatch;
50static boost::container::flat_map<std::string, std::string> pwmTable;
Cheng C Yang58b2b532019-05-31 00:19:45 +080051static boost::container::flat_map<std::string, std::vector<std::string>>
52 eventMatch;
53static boost::container::flat_map<std::string, std::vector<std::string>>
54 limitEventMatch;
55
56// Function CheckEvent will check each attribute from eventMatch table in the
57// sysfs. If the attributes exists in sysfs, then store the complete path
58// of the attribute into eventPathList.
59void checkEvent(
60 const std::string& directory,
61 const boost::container::flat_map<std::string, std::vector<std::string>>&
62 eventMatch,
63 boost::container::flat_map<std::string, std::vector<std::string>>&
64 eventPathList)
65{
66 for (const auto& match : eventMatch)
67 {
68 const std::vector<std::string>& eventAttrs = match.second;
69 const std::string& eventName = match.first;
70 for (const auto& eventAttr : eventAttrs)
71 {
72 auto eventPath = directory + "/" + eventAttr;
73
74 std::ifstream eventFile(eventPath);
75 if (!eventFile.good())
76 {
77 continue;
78 }
79
80 eventPathList[eventName].push_back(eventPath);
81 }
82 }
83}
84
85// Function checkEventLimits will check all the psu related xxx_input attributes
86// in sysfs to see if xxx_crit_alarm xxx_lcrit_alarm xxx_max_alarm
87// xxx_min_alarm exist, then store the existing paths of the alarm attributes
88// to eventPathList.
89void checkEventLimits(
90 const std::string& sensorPathStr,
91 const boost::container::flat_map<std::string, std::vector<std::string>>&
92 limitEventMatch,
93 boost::container::flat_map<std::string, std::vector<std::string>>&
94 eventPathList)
95{
96 for (const auto& limitMatch : limitEventMatch)
97 {
98 const std::vector<std::string>& limitEventAttrs = limitMatch.second;
99 const std::string& eventName = limitMatch.first;
100 for (const auto& limitEventAttr : limitEventAttrs)
101 {
102 auto limitEventPath =
103 boost::replace_all_copy(sensorPathStr, "input", limitEventAttr);
104 std::ifstream eventFile(limitEventPath);
105 if (!eventFile.good())
106 {
107 continue;
108 }
109 eventPathList[eventName].push_back(limitEventPath);
110 }
111 }
112}
Cheng C Yang916360b2019-05-07 18:47:16 +0800113
114static void checkPWMSensor(const fs::path& sensorPath, std::string& labelHead,
115 const std::string& interfacePath,
116 sdbusplus::asio::object_server& objectServer,
Patrick Venturea2b2d842019-10-11 07:48:47 -0700117 const std::string& psuName)
Cheng C Yang916360b2019-05-07 18:47:16 +0800118{
119 for (const auto& pwmName : pwmTable)
120 {
121 if (pwmName.first != labelHead)
122 {
123 continue;
124 }
125
126 const std::string& sensorPathStr = sensorPath.string();
127 const std::string& pwmPathStr =
128 boost::replace_all_copy(sensorPathStr, "input", "target");
129 std::ifstream pwmFile(pwmPathStr);
130 if (!pwmFile.good())
131 {
132 continue;
133 }
134
135 auto findPWMSensor = pwmSensors.find(psuName + labelHead);
136 if (findPWMSensor != pwmSensors.end())
137 {
138 continue;
139 }
140
141 pwmSensors[psuName + labelHead] = std::make_unique<PwmSensor>(
142 "Pwm_" + psuName + "_" + pwmName.second, pwmPathStr, objectServer,
Cheng C Yang15266a92019-06-12 08:42:52 +0800143 interfacePath + "_" + pwmName.second);
Cheng C Yang916360b2019-05-07 18:47:16 +0800144 }
145}
146
147void createSensors(boost::asio::io_service& io,
148 sdbusplus::asio::object_server& objectServer,
149 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
Cheng C Yang209ec562019-03-12 16:37:44 +0800150{
151
152 ManagedObjectType sensorConfigs;
Josh Lehan49cfba92019-10-08 16:50:42 -0700153 int numCreated = 0;
Cheng C Yang209ec562019-03-12 16:37:44 +0800154 bool useCache = false;
155
Cheng C Yang58b2b532019-05-31 00:19:45 +0800156 // TODO may need only modify the ones that need to be changed.
157 sensors.clear();
Cheng C Yang92498eb2019-09-26 21:59:25 +0800158 combineEvents.clear();
Cheng C Yang209ec562019-03-12 16:37:44 +0800159 for (const char* type : sensorTypes)
160 {
161 if (!getSensorConfiguration(type, dbusConnection, sensorConfigs,
162 useCache))
163 {
164 std::cerr << "error get sensor config from entity manager\n";
165 return;
166 }
167 useCache = true;
168 }
169
170 std::vector<fs::path> pmbusPaths;
171 if (!findFiles(fs::path("/sys/class/hwmon"), "name", pmbusPaths))
172 {
173 std::cerr << "No PSU sensors in system\n";
174 return;
175 }
176
177 boost::container::flat_set<std::string> directories;
178 for (const auto& pmbusPath : pmbusPaths)
179 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800180 boost::container::flat_map<std::string, std::vector<std::string>>
181 eventPathList;
182
183 std::ifstream nameFile(pmbusPath);
184 if (!nameFile.good())
185 {
Josh Lehan49cfba92019-10-08 16:50:42 -0700186 std::cerr << "Failure finding pmbus path " << pmbusPath << "\n";
Cheng C Yang58b2b532019-05-31 00:19:45 +0800187 continue;
188 }
189
190 std::string pmbusName;
191 std::getline(nameFile, pmbusName);
192 nameFile.close();
Vijay Khemka996bad12019-05-28 15:15:16 -0700193
194 if (std::find(pmbusNames.begin(), pmbusNames.end(), pmbusName) ==
195 pmbusNames.end())
Cheng C Yang58b2b532019-05-31 00:19:45 +0800196 {
Josh Lehan49cfba92019-10-08 16:50:42 -0700197 // To avoid this error message, add your driver name to
198 // the pmbusNames vector at the top of this file.
199 std::cerr << "Driver name " << pmbusName
200 << " not found in sensor whitelist\n";
Cheng C Yang58b2b532019-05-31 00:19:45 +0800201 continue;
202 }
203
204 const std::string* psuName;
Cheng C Yang209ec562019-03-12 16:37:44 +0800205 auto directory = pmbusPath.parent_path();
206
207 auto ret = directories.insert(directory.string());
208 if (!ret.second)
209 {
Josh Lehan49cfba92019-10-08 16:50:42 -0700210 std::cerr << "Duplicate path " << directory.string() << "\n";
Cheng C Yang58b2b532019-05-31 00:19:45 +0800211 continue; // check if path has already been searched
Cheng C Yang209ec562019-03-12 16:37:44 +0800212 }
213
James Feistb6c0b912019-07-09 12:21:44 -0700214 fs::path device = directory / "device";
Cheng C Yang209ec562019-03-12 16:37:44 +0800215 std::string deviceName = fs::canonical(device).stem();
216 auto findHyphen = deviceName.find("-");
217 if (findHyphen == std::string::npos)
218 {
219 std::cerr << "found bad device" << deviceName << "\n";
220 continue;
221 }
222 std::string busStr = deviceName.substr(0, findHyphen);
223 std::string addrStr = deviceName.substr(findHyphen + 1);
224
225 size_t bus = 0;
226 size_t addr = 0;
227
228 try
229 {
230 bus = std::stoi(busStr);
231 addr = std::stoi(addrStr, 0, 16);
232 }
James Feistb6c0b912019-07-09 12:21:44 -0700233 catch (std::invalid_argument&)
Cheng C Yang209ec562019-03-12 16:37:44 +0800234 {
Josh Lehan49cfba92019-10-08 16:50:42 -0700235 std::cerr << "Error parsing bus " << busStr << " addr " << addrStr
236 << "\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800237 continue;
238 }
239
Cheng C Yang209ec562019-03-12 16:37:44 +0800240 const std::pair<std::string, boost::container::flat_map<
241 std::string, BasicVariantType>>*
242 baseConfig = nullptr;
243 const SensorData* sensorData = nullptr;
244 const std::string* interfacePath = nullptr;
245 const char* sensorType = nullptr;
246
247 for (const std::pair<sdbusplus::message::object_path, SensorData>&
248 sensor : sensorConfigs)
249 {
250 sensorData = &(sensor.second);
251 for (const char* type : sensorTypes)
252 {
253 auto sensorBase = sensorData->find(type);
254 if (sensorBase != sensorData->end())
255 {
256 baseConfig = &(*sensorBase);
257 sensorType = type;
258 break;
259 }
260 }
261 if (baseConfig == nullptr)
262 {
263 std::cerr << "error finding base configuration for "
264 << deviceName << "\n";
265 continue;
266 }
267
268 auto configBus = baseConfig->second.find("Bus");
269 auto configAddress = baseConfig->second.find("Address");
270
271 if (configBus == baseConfig->second.end() ||
272 configAddress == baseConfig->second.end())
273 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800274 std::cerr << "error finding necessary entry in configuration\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800275 continue;
276 }
277
Cheng C Yang58b2b532019-05-31 00:19:45 +0800278 const uint64_t* confBus;
279 const uint64_t* confAddr;
280 if (!(confBus = std::get_if<uint64_t>(&(configBus->second))) ||
281 !(confAddr = std::get_if<uint64_t>(&(configAddress->second))))
282 {
283 std::cerr
Josh Lehan49cfba92019-10-08 16:50:42 -0700284 << "Cannot get bus or address, invalid configuration\n";
Cheng C Yang58b2b532019-05-31 00:19:45 +0800285 continue;
286 }
287
288 if ((*confBus != bus) || (*confAddr != addr))
Cheng C Yang209ec562019-03-12 16:37:44 +0800289 {
Josh Lehan432d1ed2019-10-16 12:23:31 -0700290 std::cerr << "Configuration skipping " << *confBus << "-"
291 << *confAddr << " because not " << bus << "-" << addr
292 << "\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800293 continue;
294 }
295
296 interfacePath = &(sensor.first.str);
297 break;
298 }
299 if (interfacePath == nullptr)
300 {
Josh Lehan49cfba92019-10-08 16:50:42 -0700301 // To avoid this error message, add your export map entry,
302 // from Entity Manager, to sensorTypes at the top of this file.
Cheng C Yang209ec562019-03-12 16:37:44 +0800303 std::cerr << "failed to find match for " << deviceName << "\n";
304 continue;
305 }
306
Cheng C Yange50345b2019-04-02 17:26:15 +0800307 auto findPSUName = baseConfig->second.find("Name");
308 if (findPSUName == baseConfig->second.end())
Cheng C Yang209ec562019-03-12 16:37:44 +0800309 {
310 std::cerr << "could not determine configuration name for "
311 << deviceName << "\n";
312 continue;
313 }
314
Cheng C Yang58b2b532019-05-31 00:19:45 +0800315 if (!(psuName = std::get_if<std::string>(&(findPSUName->second))))
316 {
317 std::cerr << "Cannot find psu name, invalid configuration\n";
318 continue;
319 }
320 checkEvent(directory.string(), eventMatch, eventPathList);
321
Vijay Khemka996bad12019-05-28 15:15:16 -0700322 /* Check if there are more sensors in the same interface */
323 int i = 1;
324 std::vector<std::string> psuNames;
325 do
326 {
Josh Lehan49cfba92019-10-08 16:50:42 -0700327 // Individual string fields: Name, Name1, Name2, Name3, ...
Vijay Khemka996bad12019-05-28 15:15:16 -0700328 psuNames.push_back(std::get<std::string>(findPSUName->second));
329 findPSUName = baseConfig->second.find("Name" + std::to_string(i++));
330 } while (findPSUName != baseConfig->second.end());
331
Cheng C Yange50345b2019-04-02 17:26:15 +0800332 std::vector<fs::path> sensorPaths;
James Feistb6c0b912019-07-09 12:21:44 -0700333 if (!findFiles(directory, R"(\w\d+_input$)", sensorPaths, 0))
Cheng C Yang209ec562019-03-12 16:37:44 +0800334 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800335 std::cerr << "No PSU non-label sensor in PSU\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800336 continue;
337 }
338
Vijay Khemka996bad12019-05-28 15:15:16 -0700339 /* Find array of labels to be exposed if it is defined in config */
340 std::vector<std::string> findLabels;
341 auto findLabelObj = baseConfig->second.find("Labels");
342 if (findLabelObj != baseConfig->second.end())
343 {
344 findLabels =
345 std::get<std::vector<std::string>>(findLabelObj->second);
346 }
347
Jason Ling5747fab2019-10-02 16:46:23 -0700348 std::regex sensorNameRegEx("([A-Za-z]+)[0-9]*_");
349 std::smatch matches;
350
Cheng C Yange50345b2019-04-02 17:26:15 +0800351 for (const auto& sensorPath : sensorPaths)
Cheng C Yang209ec562019-03-12 16:37:44 +0800352 {
Cheng C Yang209ec562019-03-12 16:37:44 +0800353
Cheng C Yange50345b2019-04-02 17:26:15 +0800354 std::string labelHead;
355 std::string sensorPathStr = sensorPath.string();
356 std::string sensorNameStr = sensorPath.filename();
Jason Ling5747fab2019-10-02 16:46:23 -0700357 std::string sensorNameSubStr{""};
358 if (std::regex_search(sensorNameStr, matches, sensorNameRegEx))
359 {
360 sensorNameSubStr = matches[1];
361 }
362 else
363 {
364 std::cerr << "Couldn't extract the alpha prefix from "
365 << sensorNameStr;
366 continue;
367 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800368
Cheng C Yangecba9de2019-09-12 23:41:50 +0800369 auto labelPath =
370 boost::replace_all_copy(sensorPathStr, "input", "label");
371 std::ifstream labelFile(labelPath);
372 if (!labelFile.good())
Cheng C Yang209ec562019-03-12 16:37:44 +0800373 {
Josh Lehan432d1ed2019-10-16 12:23:31 -0700374 std::cerr << "Input file " << sensorPath
375 << " has no corresponding label file\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800376 labelHead = sensorNameStr.substr(0, sensorNameStr.find("_"));
Cheng C Yang209ec562019-03-12 16:37:44 +0800377 }
378 else
379 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800380 std::string label;
381 std::getline(labelFile, label);
382 labelFile.close();
Cheng C Yange50345b2019-04-02 17:26:15 +0800383 auto findSensor = sensors.find(label);
384 if (findSensor != sensors.end())
385 {
386 continue;
387 }
388
389 labelHead = label.substr(0, label.find(" "));
390 }
391
Cheng C Yang916360b2019-05-07 18:47:16 +0800392 checkPWMSensor(sensorPath, labelHead, *interfacePath, objectServer,
Vijay Khemka996bad12019-05-28 15:15:16 -0700393 psuNames[0]);
Cheng C Yang916360b2019-05-07 18:47:16 +0800394
Vijay Khemka996bad12019-05-28 15:15:16 -0700395 if (!findLabels.empty())
396 {
397 /* Check if this labelHead is enabled in config file */
398 if (std::find(findLabels.begin(), findLabels.end(),
399 labelHead) == findLabels.end())
400 {
Jason Ling5747fab2019-10-02 16:46:23 -0700401 std::cerr << "couldn't find " << labelHead
402 << " in the Labels list\n";
Vijay Khemka996bad12019-05-28 15:15:16 -0700403 continue;
404 }
405 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800406
Vijay Khemka996bad12019-05-28 15:15:16 -0700407 /* Find out sensor name index for this label */
Jason Ling5747fab2019-10-02 16:46:23 -0700408 std::regex rgx("[A-Za-z]+([0-9]+)");
409 int nameIndex{0};
410 if (std::regex_search(labelHead, matches, rgx))
Vijay Khemka996bad12019-05-28 15:15:16 -0700411 {
Jason Ling5747fab2019-10-02 16:46:23 -0700412 nameIndex = std::stoi(matches[1]);
Josh Lehan9fa25152019-10-16 16:52:38 -0700413
414 // Decrement to preserve alignment, because hwmon
415 // human-readable filenames and labels use 1-based numbering,
416 // but the "Name", "Name1", "Name2", etc. naming
417 // convention (the psuNames vector) uses 0-based numbering.
418 if (nameIndex > 0)
419 {
420 --nameIndex;
421 }
Vijay Khemka996bad12019-05-28 15:15:16 -0700422 }
423 else
James Feist17ab6e02019-06-25 12:28:13 -0700424 {
Vijay Khemka996bad12019-05-28 15:15:16 -0700425 nameIndex = 0;
James Feist17ab6e02019-06-25 12:28:13 -0700426 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800427
Jason Ling5747fab2019-10-02 16:46:23 -0700428 if (psuNames.size() <= nameIndex)
429 {
430 std::cerr << "Could not pair " << labelHead
431 << " with a Name field\n";
432 continue;
433 }
434
Cheng C Yange50345b2019-04-02 17:26:15 +0800435 auto findProperty = labelMatch.find(labelHead);
436 if (findProperty == labelMatch.end())
Cheng C Yang209ec562019-03-12 16:37:44 +0800437 {
Jason Ling5747fab2019-10-02 16:46:23 -0700438 std::cerr << "Could not find " << labelHead << "\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800439 continue;
440 }
441
Josh Lehan432d1ed2019-10-16 12:23:31 -0700442 if constexpr (DEBUG)
443 {
444 std::cerr << "Sensor label head " << labelHead
445 << " paired with " << psuNames[nameIndex] << "\n";
446 }
447
Cheng C Yang58b2b532019-05-31 00:19:45 +0800448 checkEventLimits(sensorPathStr, limitEventMatch, eventPathList);
449
Cheng C Yange50345b2019-04-02 17:26:15 +0800450 unsigned int factor =
451 std::pow(10, findProperty->second.sensorScaleFactor);
Vijay Khemka996bad12019-05-28 15:15:16 -0700452
Vijay Khemkadbdcfe02019-07-25 12:56:17 -0700453 /* Change first char of substring to uppercase */
454 char firstChar = sensorNameSubStr[0] - 0x20;
455 std::string strScaleFactor =
456 firstChar + sensorNameSubStr.substr(1) + "ScaleFactor";
457
458 auto findScaleFactor = baseConfig->second.find(strScaleFactor);
Vijay Khemka53ca4442019-07-23 11:03:55 -0700459 if (findScaleFactor != baseConfig->second.end())
460 {
461 factor =
462 std::visit(VariantToIntVisitor(), findScaleFactor->second);
463 }
464
Josh Lehan49cfba92019-10-08 16:50:42 -0700465 if constexpr (DEBUG)
466 {
467 std::cerr << "Sensor scaling factor " << factor << " string "
468 << strScaleFactor << "\n";
469 }
470
Vijay Khemka996bad12019-05-28 15:15:16 -0700471 std::vector<thresholds::Threshold> sensorThresholds;
472
James Feist17ab6e02019-06-25 12:28:13 -0700473 if (!parseThresholdsFromConfig(*sensorData, sensorThresholds))
Cheng C Yange50345b2019-04-02 17:26:15 +0800474 {
James Feist17ab6e02019-06-25 12:28:13 -0700475 std::cerr << "error populating thresholds for "
476 << sensorNameSubStr << "\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800477 }
478
479 auto findSensorType = sensorTable.find(sensorNameSubStr);
480 if (findSensorType == sensorTable.end())
481 {
Jason Ling5747fab2019-10-02 16:46:23 -0700482 std::cerr << sensorNameSubStr
483 << " is not a recognize sensor file\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800484 continue;
485 }
486
487 std::string sensorName =
Vijay Khemka996bad12019-05-28 15:15:16 -0700488 psuNames[nameIndex] + " " + findProperty->second.labelTypeName;
Cheng C Yange50345b2019-04-02 17:26:15 +0800489
Josh Lehan49cfba92019-10-08 16:50:42 -0700490 ++numCreated;
491 if constexpr (DEBUG)
492 {
493 std::cerr << "Created " << numCreated
494 << " sensors so far: " << sensorName << "\n";
495 }
496
Cheng C Yang58b2b532019-05-31 00:19:45 +0800497 sensors[sensorName] = std::make_unique<PSUSensor>(
Cheng C Yange50345b2019-04-02 17:26:15 +0800498 sensorPathStr, sensorType, objectServer, dbusConnection, io,
Cheng C Yang209ec562019-03-12 16:37:44 +0800499 sensorName, std::move(sensorThresholds), *interfacePath,
Cheng C Yange50345b2019-04-02 17:26:15 +0800500 findSensorType->second, factor, findProperty->second.maxReading,
501 findProperty->second.minReading);
Cheng C Yang209ec562019-03-12 16:37:44 +0800502 }
Cheng C Yang58b2b532019-05-31 00:19:45 +0800503
504 // OperationalStatus event
Cheng C Yang92498eb2019-09-26 21:59:25 +0800505 combineEvents[*psuName + "OperationalStatus"] = nullptr;
Cheng C Yang58b2b532019-05-31 00:19:45 +0800506 combineEvents[*psuName + "OperationalStatus"] =
507 std::make_unique<PSUCombineEvent>(
508 objectServer, io, *psuName, eventPathList, "OperationalStatus");
Cheng C Yang209ec562019-03-12 16:37:44 +0800509 }
Josh Lehan49cfba92019-10-08 16:50:42 -0700510
511 if constexpr (DEBUG)
512 {
513 std::cerr << "Created total of " << numCreated << " sensors\n";
514 }
Cheng C Yang209ec562019-03-12 16:37:44 +0800515 return;
516}
517
Cheng C Yang916360b2019-05-07 18:47:16 +0800518void propertyInitialize(void)
Cheng C Yang209ec562019-03-12 16:37:44 +0800519{
Cheng C Yange50345b2019-04-02 17:26:15 +0800520 sensorTable = {{"power", "power/"},
521 {"curr", "current/"},
522 {"temp", "temperature/"},
523 {"in", "voltage/"},
524 {"fan", "fan_tach/"}};
525
526 labelMatch = {{"pin", PSUProperty("Input Power", 3000, 0, 6)},
527 {"pout1", PSUProperty("Output Power", 3000, 0, 6)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700528 {"pout2", PSUProperty("Output Power", 3000, 0, 6)},
529 {"pout3", PSUProperty("Output Power", 3000, 0, 6)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700530 {"power1", PSUProperty("Output Power", 3000, 0, 6)},
Cheng C Yangbdbde962019-04-26 22:50:34 +0800531 {"vin", PSUProperty("Input Voltage", 300, 0, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700532 {"vout1", PSUProperty("Output Voltage", 255, 0, 3)},
533 {"vout2", PSUProperty("Output Voltage", 255, 0, 3)},
534 {"vout3", PSUProperty("Output Voltage", 255, 0, 3)},
Jason Ling5747fab2019-10-02 16:46:23 -0700535 {"vout4", PSUProperty("Output Voltage", 255, 0, 3)},
536 {"vout5", PSUProperty("Output Voltage", 255, 0, 3)},
537 {"vout6", PSUProperty("Output Voltage", 255, 0, 3)},
538 {"vout7", PSUProperty("Output Voltage", 255, 0, 3)},
539 {"vout8", PSUProperty("Output Voltage", 255, 0, 3)},
540 {"vout9", PSUProperty("Output Voltage", 255, 0, 3)},
541 {"vout10", PSUProperty("Output Voltage", 255, 0, 3)},
542 {"vout11", PSUProperty("Output Voltage", 255, 0, 3)},
543 {"vout12", PSUProperty("Output Voltage", 255, 0, 3)},
544 {"vout13", PSUProperty("Output Voltage", 255, 0, 3)},
545 {"vout14", PSUProperty("Output Voltage", 255, 0, 3)},
546 {"vout15", PSUProperty("Output Voltage", 255, 0, 3)},
547 {"vout16", PSUProperty("Output Voltage", 255, 0, 3)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700548 {"in1", PSUProperty("Output Voltage", 255, 0, 3)},
Cheng C Yange50345b2019-04-02 17:26:15 +0800549 {"iin", PSUProperty("Input Current", 20, 0, 3)},
550 {"iout1", PSUProperty("Output Current", 255, 0, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700551 {"iout2", PSUProperty("Output Current", 255, 0, 3)},
552 {"iout3", PSUProperty("Output Current", 255, 0, 3)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700553 {"curr1", PSUProperty("Output Current", 255, 0, 3)},
Cheng C Yange50345b2019-04-02 17:26:15 +0800554 {"temp1", PSUProperty("Temperature", 127, -128, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700555 {"temp2", PSUProperty("Temperature", 127, -128, 3)},
556 {"temp3", PSUProperty("Temperature", 127, -128, 3)},
Jason Ling5747fab2019-10-02 16:46:23 -0700557 {"temp4", PSUProperty("Temperature", 127, -128, 3)},
558 {"temp5", PSUProperty("Temperature", 127, -128, 3)},
Cheng C Yang8dbb3952019-05-23 00:03:12 +0800559 {"fan1", PSUProperty("Fan Speed 1", 30000, 0, 0)},
560 {"fan2", PSUProperty("Fan Speed 2", 30000, 0, 0)}};
Cheng C Yang916360b2019-05-07 18:47:16 +0800561
562 pwmTable = {{"fan1", "Fan_1"}, {"fan2", "Fan_2"}};
Cheng C Yang58b2b532019-05-31 00:19:45 +0800563
564 limitEventMatch = {{"PredictiveFailure", {"max_alarm", "min_alarm"}},
565 {"Failure", {"crit_alarm", "lcrit_alarm"}}};
566
567 eventMatch = {
568 {"PredictiveFailure", {"power1_alarm"}},
569 {"Failure", {"in2_alarm"}},
Cheng C Yang9c45e6b2019-08-13 07:21:32 +0800570 {"ACLost", {"in1_beep"}},
571 {"FanFault", {"fan1_alarm", "fan2_alarm", "fan1_fault", "fan2_fault"}},
572 {"ConfigureError", {"in1_fault"}}};
Cheng C Yang209ec562019-03-12 16:37:44 +0800573}
574
James Feistb6c0b912019-07-09 12:21:44 -0700575int main()
Cheng C Yang209ec562019-03-12 16:37:44 +0800576{
577 boost::asio::io_service io;
578 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
579
580 systemBus->request_name("xyz.openbmc_project.PSUSensor");
581 sdbusplus::asio::object_server objectServer(systemBus);
Cheng C Yang209ec562019-03-12 16:37:44 +0800582 std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
Cheng C Yang209ec562019-03-12 16:37:44 +0800583
Cheng C Yang916360b2019-05-07 18:47:16 +0800584 propertyInitialize();
Cheng C Yang209ec562019-03-12 16:37:44 +0800585
Cheng C Yang916360b2019-05-07 18:47:16 +0800586 io.post([&]() { createSensors(io, objectServer, systemBus); });
Cheng C Yang209ec562019-03-12 16:37:44 +0800587 boost::asio::deadline_timer filterTimer(io);
588 std::function<void(sdbusplus::message::message&)> eventHandler =
589 [&](sdbusplus::message::message& message) {
590 if (message.is_method_error())
591 {
592 std::cerr << "callback method error\n";
593 return;
594 }
595 filterTimer.expires_from_now(boost::posix_time::seconds(1));
596 filterTimer.async_wait([&](const boost::system::error_code& ec) {
597 if (ec == boost::asio::error::operation_aborted)
598 {
599 return;
600 }
601 else if (ec)
602 {
603 std::cerr << "timer error\n";
604 }
Cheng C Yang916360b2019-05-07 18:47:16 +0800605 createSensors(io, objectServer, systemBus);
Cheng C Yang209ec562019-03-12 16:37:44 +0800606 });
607 };
608
609 for (const char* type : sensorTypes)
610 {
611 auto match = std::make_unique<sdbusplus::bus::match::match>(
612 static_cast<sdbusplus::bus::bus&>(*systemBus),
613 "type='signal',member='PropertiesChanged',path_namespace='" +
614 std::string(inventoryPath) + "',arg0namespace='" + type + "'",
615 eventHandler);
616 matches.emplace_back(std::move(match));
617 }
618 io.run();
619}