blob: 41fc21c7d8d765db29fc5e9392397a6a491c21de [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 Lehan0830c7b2019-10-08 16:35:09 -070030static constexpr std::array<const char*, 3> sensorTypes = {
Jason Ling5747fab2019-10-02 16:46:23 -070031 "xyz.openbmc_project.Configuration.pmbus",
Josh Lehan0830c7b2019-10-08 16:35:09 -070032 "xyz.openbmc_project.Configuration.MAX34451",
33 "xyz.openbmc_project.Configuration.ISL68137"};
Cheng C Yang209ec562019-03-12 16:37:44 +080034
Josh Lehan0830c7b2019-10-08 16:35:09 -070035static std::vector<std::string> pmbusNames = {"pmbus", "pxe1610", "ina219",
36 "ina230", "max34451", "isl68137"};
37
Cheng C Yang209ec562019-03-12 16:37:44 +080038namespace fs = std::filesystem;
39
Cheng C Yang916360b2019-05-07 18:47:16 +080040static boost::container::flat_map<std::string, std::unique_ptr<PSUSensor>>
41 sensors;
Cheng C Yang58b2b532019-05-31 00:19:45 +080042static boost::container::flat_map<std::string, std::unique_ptr<PSUCombineEvent>>
43 combineEvents;
Cheng C Yang916360b2019-05-07 18:47:16 +080044static boost::container::flat_map<std::string, std::unique_ptr<PwmSensor>>
45 pwmSensors;
46static boost::container::flat_map<std::string, std::string> sensorTable;
47static boost::container::flat_map<std::string, PSUProperty> labelMatch;
48static boost::container::flat_map<std::string, std::string> pwmTable;
Cheng C Yang58b2b532019-05-31 00:19:45 +080049static boost::container::flat_map<std::string, std::vector<std::string>>
50 eventMatch;
51static boost::container::flat_map<std::string, std::vector<std::string>>
52 limitEventMatch;
53
54// Function CheckEvent will check each attribute from eventMatch table in the
55// sysfs. If the attributes exists in sysfs, then store the complete path
56// of the attribute into eventPathList.
57void checkEvent(
58 const std::string& directory,
59 const boost::container::flat_map<std::string, std::vector<std::string>>&
60 eventMatch,
61 boost::container::flat_map<std::string, std::vector<std::string>>&
62 eventPathList)
63{
64 for (const auto& match : eventMatch)
65 {
66 const std::vector<std::string>& eventAttrs = match.second;
67 const std::string& eventName = match.first;
68 for (const auto& eventAttr : eventAttrs)
69 {
70 auto eventPath = directory + "/" + eventAttr;
71
72 std::ifstream eventFile(eventPath);
73 if (!eventFile.good())
74 {
75 continue;
76 }
77
78 eventPathList[eventName].push_back(eventPath);
79 }
80 }
81}
82
83// Function checkEventLimits will check all the psu related xxx_input attributes
84// in sysfs to see if xxx_crit_alarm xxx_lcrit_alarm xxx_max_alarm
85// xxx_min_alarm exist, then store the existing paths of the alarm attributes
86// to eventPathList.
87void checkEventLimits(
88 const std::string& sensorPathStr,
89 const boost::container::flat_map<std::string, std::vector<std::string>>&
90 limitEventMatch,
91 boost::container::flat_map<std::string, std::vector<std::string>>&
92 eventPathList)
93{
94 for (const auto& limitMatch : limitEventMatch)
95 {
96 const std::vector<std::string>& limitEventAttrs = limitMatch.second;
97 const std::string& eventName = limitMatch.first;
98 for (const auto& limitEventAttr : limitEventAttrs)
99 {
100 auto limitEventPath =
101 boost::replace_all_copy(sensorPathStr, "input", limitEventAttr);
102 std::ifstream eventFile(limitEventPath);
103 if (!eventFile.good())
104 {
105 continue;
106 }
107 eventPathList[eventName].push_back(limitEventPath);
108 }
109 }
110}
Cheng C Yang916360b2019-05-07 18:47:16 +0800111
112static void checkPWMSensor(const fs::path& sensorPath, std::string& labelHead,
113 const std::string& interfacePath,
114 sdbusplus::asio::object_server& objectServer,
115 std::string psuName)
116{
117 for (const auto& pwmName : pwmTable)
118 {
119 if (pwmName.first != labelHead)
120 {
121 continue;
122 }
123
124 const std::string& sensorPathStr = sensorPath.string();
125 const std::string& pwmPathStr =
126 boost::replace_all_copy(sensorPathStr, "input", "target");
127 std::ifstream pwmFile(pwmPathStr);
128 if (!pwmFile.good())
129 {
130 continue;
131 }
132
133 auto findPWMSensor = pwmSensors.find(psuName + labelHead);
134 if (findPWMSensor != pwmSensors.end())
135 {
136 continue;
137 }
138
139 pwmSensors[psuName + labelHead] = std::make_unique<PwmSensor>(
140 "Pwm_" + psuName + "_" + pwmName.second, pwmPathStr, objectServer,
Cheng C Yang15266a92019-06-12 08:42:52 +0800141 interfacePath + "_" + pwmName.second);
Cheng C Yang916360b2019-05-07 18:47:16 +0800142 }
143}
144
145void createSensors(boost::asio::io_service& io,
146 sdbusplus::asio::object_server& objectServer,
147 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
Cheng C Yang209ec562019-03-12 16:37:44 +0800148{
149
150 ManagedObjectType sensorConfigs;
151 bool useCache = false;
152
Cheng C Yang58b2b532019-05-31 00:19:45 +0800153 // TODO may need only modify the ones that need to be changed.
154 sensors.clear();
Cheng C Yang92498eb2019-09-26 21:59:25 +0800155 combineEvents.clear();
Cheng C Yang209ec562019-03-12 16:37:44 +0800156 for (const char* type : sensorTypes)
157 {
158 if (!getSensorConfiguration(type, dbusConnection, sensorConfigs,
159 useCache))
160 {
161 std::cerr << "error get sensor config from entity manager\n";
162 return;
163 }
164 useCache = true;
165 }
166
167 std::vector<fs::path> pmbusPaths;
168 if (!findFiles(fs::path("/sys/class/hwmon"), "name", pmbusPaths))
169 {
170 std::cerr << "No PSU sensors in system\n";
171 return;
172 }
173
174 boost::container::flat_set<std::string> directories;
175 for (const auto& pmbusPath : pmbusPaths)
176 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800177 boost::container::flat_map<std::string, std::vector<std::string>>
178 eventPathList;
179
180 std::ifstream nameFile(pmbusPath);
181 if (!nameFile.good())
182 {
183 std::cerr << "Failure reading " << pmbusPath << "\n";
184 continue;
185 }
186
187 std::string pmbusName;
188 std::getline(nameFile, pmbusName);
189 nameFile.close();
Vijay Khemka996bad12019-05-28 15:15:16 -0700190
191 if (std::find(pmbusNames.begin(), pmbusNames.end(), pmbusName) ==
192 pmbusNames.end())
Cheng C Yang58b2b532019-05-31 00:19:45 +0800193 {
194 continue;
195 }
196
197 const std::string* psuName;
Cheng C Yang209ec562019-03-12 16:37:44 +0800198 auto directory = pmbusPath.parent_path();
199
200 auto ret = directories.insert(directory.string());
201 if (!ret.second)
202 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800203 continue; // check if path has already been searched
Cheng C Yang209ec562019-03-12 16:37:44 +0800204 }
205
James Feistb6c0b912019-07-09 12:21:44 -0700206 fs::path device = directory / "device";
Cheng C Yang209ec562019-03-12 16:37:44 +0800207 std::string deviceName = fs::canonical(device).stem();
208 auto findHyphen = deviceName.find("-");
209 if (findHyphen == std::string::npos)
210 {
211 std::cerr << "found bad device" << deviceName << "\n";
212 continue;
213 }
214 std::string busStr = deviceName.substr(0, findHyphen);
215 std::string addrStr = deviceName.substr(findHyphen + 1);
216
217 size_t bus = 0;
218 size_t addr = 0;
219
220 try
221 {
222 bus = std::stoi(busStr);
223 addr = std::stoi(addrStr, 0, 16);
224 }
James Feistb6c0b912019-07-09 12:21:44 -0700225 catch (std::invalid_argument&)
Cheng C Yang209ec562019-03-12 16:37:44 +0800226 {
227 continue;
228 }
229
Cheng C Yang209ec562019-03-12 16:37:44 +0800230 const std::pair<std::string, boost::container::flat_map<
231 std::string, BasicVariantType>>*
232 baseConfig = nullptr;
233 const SensorData* sensorData = nullptr;
234 const std::string* interfacePath = nullptr;
235 const char* sensorType = nullptr;
236
237 for (const std::pair<sdbusplus::message::object_path, SensorData>&
238 sensor : sensorConfigs)
239 {
240 sensorData = &(sensor.second);
241 for (const char* type : sensorTypes)
242 {
243 auto sensorBase = sensorData->find(type);
244 if (sensorBase != sensorData->end())
245 {
246 baseConfig = &(*sensorBase);
247 sensorType = type;
248 break;
249 }
250 }
251 if (baseConfig == nullptr)
252 {
253 std::cerr << "error finding base configuration for "
254 << deviceName << "\n";
255 continue;
256 }
257
258 auto configBus = baseConfig->second.find("Bus");
259 auto configAddress = baseConfig->second.find("Address");
260
261 if (configBus == baseConfig->second.end() ||
262 configAddress == baseConfig->second.end())
263 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800264 std::cerr << "error finding necessary entry in configuration\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800265 continue;
266 }
267
Cheng C Yang58b2b532019-05-31 00:19:45 +0800268 const uint64_t* confBus;
269 const uint64_t* confAddr;
270 if (!(confBus = std::get_if<uint64_t>(&(configBus->second))) ||
271 !(confAddr = std::get_if<uint64_t>(&(configAddress->second))))
272 {
273 std::cerr
274 << "Canot get bus or address, invalid configuration\n";
275 continue;
276 }
277
278 if ((*confBus != bus) || (*confAddr != addr))
Cheng C Yang209ec562019-03-12 16:37:44 +0800279 {
280 continue;
281 }
282
283 interfacePath = &(sensor.first.str);
284 break;
285 }
286 if (interfacePath == nullptr)
287 {
288 std::cerr << "failed to find match for " << deviceName << "\n";
289 continue;
290 }
291
Cheng C Yange50345b2019-04-02 17:26:15 +0800292 auto findPSUName = baseConfig->second.find("Name");
293 if (findPSUName == baseConfig->second.end())
Cheng C Yang209ec562019-03-12 16:37:44 +0800294 {
295 std::cerr << "could not determine configuration name for "
296 << deviceName << "\n";
297 continue;
298 }
299
Cheng C Yang58b2b532019-05-31 00:19:45 +0800300 if (!(psuName = std::get_if<std::string>(&(findPSUName->second))))
301 {
302 std::cerr << "Cannot find psu name, invalid configuration\n";
303 continue;
304 }
305 checkEvent(directory.string(), eventMatch, eventPathList);
306
Vijay Khemka996bad12019-05-28 15:15:16 -0700307 /* Check if there are more sensors in the same interface */
308 int i = 1;
309 std::vector<std::string> psuNames;
310 do
311 {
312 psuNames.push_back(std::get<std::string>(findPSUName->second));
313 findPSUName = baseConfig->second.find("Name" + std::to_string(i++));
314 } while (findPSUName != baseConfig->second.end());
315
Cheng C Yange50345b2019-04-02 17:26:15 +0800316 std::vector<fs::path> sensorPaths;
James Feistb6c0b912019-07-09 12:21:44 -0700317 if (!findFiles(directory, R"(\w\d+_input$)", sensorPaths, 0))
Cheng C Yang209ec562019-03-12 16:37:44 +0800318 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800319 std::cerr << "No PSU non-label sensor in PSU\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800320 continue;
321 }
322
Vijay Khemka996bad12019-05-28 15:15:16 -0700323 /* Find array of labels to be exposed if it is defined in config */
324 std::vector<std::string> findLabels;
325 auto findLabelObj = baseConfig->second.find("Labels");
326 if (findLabelObj != baseConfig->second.end())
327 {
328 findLabels =
329 std::get<std::vector<std::string>>(findLabelObj->second);
330 }
331
Jason Ling5747fab2019-10-02 16:46:23 -0700332 std::regex sensorNameRegEx("([A-Za-z]+)[0-9]*_");
333 std::smatch matches;
334
Cheng C Yange50345b2019-04-02 17:26:15 +0800335 for (const auto& sensorPath : sensorPaths)
Cheng C Yang209ec562019-03-12 16:37:44 +0800336 {
Cheng C Yang209ec562019-03-12 16:37:44 +0800337
Cheng C Yange50345b2019-04-02 17:26:15 +0800338 std::string labelHead;
339 std::string sensorPathStr = sensorPath.string();
340 std::string sensorNameStr = sensorPath.filename();
Jason Ling5747fab2019-10-02 16:46:23 -0700341 std::string sensorNameSubStr{""};
342 if (std::regex_search(sensorNameStr, matches, sensorNameRegEx))
343 {
344 sensorNameSubStr = matches[1];
345 }
346 else
347 {
348 std::cerr << "Couldn't extract the alpha prefix from "
349 << sensorNameStr;
350 continue;
351 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800352
Cheng C Yangecba9de2019-09-12 23:41:50 +0800353 auto labelPath =
354 boost::replace_all_copy(sensorPathStr, "input", "label");
355 std::ifstream labelFile(labelPath);
356 if (!labelFile.good())
Cheng C Yang209ec562019-03-12 16:37:44 +0800357 {
Cheng C Yangecba9de2019-09-12 23:41:50 +0800358 std::cerr << "Failure reading " << sensorPath << "\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800359 labelHead = sensorNameStr.substr(0, sensorNameStr.find("_"));
Cheng C Yang209ec562019-03-12 16:37:44 +0800360 }
361 else
362 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800363 std::string label;
364 std::getline(labelFile, label);
365 labelFile.close();
Cheng C Yange50345b2019-04-02 17:26:15 +0800366 auto findSensor = sensors.find(label);
367 if (findSensor != sensors.end())
368 {
369 continue;
370 }
371
372 labelHead = label.substr(0, label.find(" "));
373 }
374
Cheng C Yang916360b2019-05-07 18:47:16 +0800375 checkPWMSensor(sensorPath, labelHead, *interfacePath, objectServer,
Vijay Khemka996bad12019-05-28 15:15:16 -0700376 psuNames[0]);
Cheng C Yang916360b2019-05-07 18:47:16 +0800377
Vijay Khemka996bad12019-05-28 15:15:16 -0700378 if (!findLabels.empty())
379 {
380 /* Check if this labelHead is enabled in config file */
381 if (std::find(findLabels.begin(), findLabels.end(),
382 labelHead) == findLabels.end())
383 {
Jason Ling5747fab2019-10-02 16:46:23 -0700384 std::cerr << "couldn't find " << labelHead
385 << " in the Labels list\n";
Vijay Khemka996bad12019-05-28 15:15:16 -0700386 continue;
387 }
388 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800389
Vijay Khemka996bad12019-05-28 15:15:16 -0700390 /* Find out sensor name index for this label */
Jason Ling5747fab2019-10-02 16:46:23 -0700391 std::regex rgx("[A-Za-z]+([0-9]+)");
392 int nameIndex{0};
393 if (std::regex_search(labelHead, matches, rgx))
Vijay Khemka996bad12019-05-28 15:15:16 -0700394 {
Jason Ling5747fab2019-10-02 16:46:23 -0700395 nameIndex = std::stoi(matches[1]);
Vijay Khemka996bad12019-05-28 15:15:16 -0700396 }
397 else
James Feist17ab6e02019-06-25 12:28:13 -0700398 {
Vijay Khemka996bad12019-05-28 15:15:16 -0700399 nameIndex = 0;
James Feist17ab6e02019-06-25 12:28:13 -0700400 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800401
Jason Ling5747fab2019-10-02 16:46:23 -0700402 if (psuNames.size() <= nameIndex)
403 {
404 std::cerr << "Could not pair " << labelHead
405 << " with a Name field\n";
406 continue;
407 }
408
Cheng C Yange50345b2019-04-02 17:26:15 +0800409 auto findProperty = labelMatch.find(labelHead);
410 if (findProperty == labelMatch.end())
Cheng C Yang209ec562019-03-12 16:37:44 +0800411 {
Jason Ling5747fab2019-10-02 16:46:23 -0700412 std::cerr << "Could not find " << labelHead << "\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800413 continue;
414 }
415
Cheng C Yang58b2b532019-05-31 00:19:45 +0800416 checkEventLimits(sensorPathStr, limitEventMatch, eventPathList);
417
Cheng C Yange50345b2019-04-02 17:26:15 +0800418 unsigned int factor =
419 std::pow(10, findProperty->second.sensorScaleFactor);
Vijay Khemka996bad12019-05-28 15:15:16 -0700420
Vijay Khemkadbdcfe02019-07-25 12:56:17 -0700421 /* Change first char of substring to uppercase */
422 char firstChar = sensorNameSubStr[0] - 0x20;
423 std::string strScaleFactor =
424 firstChar + sensorNameSubStr.substr(1) + "ScaleFactor";
425
426 auto findScaleFactor = baseConfig->second.find(strScaleFactor);
Vijay Khemka53ca4442019-07-23 11:03:55 -0700427 if (findScaleFactor != baseConfig->second.end())
428 {
429 factor =
430 std::visit(VariantToIntVisitor(), findScaleFactor->second);
431 }
432
Vijay Khemka996bad12019-05-28 15:15:16 -0700433 std::vector<thresholds::Threshold> sensorThresholds;
434
James Feist17ab6e02019-06-25 12:28:13 -0700435 if (!parseThresholdsFromConfig(*sensorData, sensorThresholds))
Cheng C Yange50345b2019-04-02 17:26:15 +0800436 {
James Feist17ab6e02019-06-25 12:28:13 -0700437 std::cerr << "error populating thresholds for "
438 << sensorNameSubStr << "\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800439 }
440
441 auto findSensorType = sensorTable.find(sensorNameSubStr);
442 if (findSensorType == sensorTable.end())
443 {
Jason Ling5747fab2019-10-02 16:46:23 -0700444 std::cerr << sensorNameSubStr
445 << " is not a recognize sensor file\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800446 continue;
447 }
448
449 std::string sensorName =
Vijay Khemka996bad12019-05-28 15:15:16 -0700450 psuNames[nameIndex] + " " + findProperty->second.labelTypeName;
Cheng C Yange50345b2019-04-02 17:26:15 +0800451
Cheng C Yang58b2b532019-05-31 00:19:45 +0800452 sensors[sensorName] = std::make_unique<PSUSensor>(
Cheng C Yange50345b2019-04-02 17:26:15 +0800453 sensorPathStr, sensorType, objectServer, dbusConnection, io,
Cheng C Yang209ec562019-03-12 16:37:44 +0800454 sensorName, std::move(sensorThresholds), *interfacePath,
Cheng C Yange50345b2019-04-02 17:26:15 +0800455 findSensorType->second, factor, findProperty->second.maxReading,
456 findProperty->second.minReading);
Cheng C Yang209ec562019-03-12 16:37:44 +0800457 }
Cheng C Yang58b2b532019-05-31 00:19:45 +0800458
459 // OperationalStatus event
Cheng C Yang92498eb2019-09-26 21:59:25 +0800460 combineEvents[*psuName + "OperationalStatus"] = nullptr;
Cheng C Yang58b2b532019-05-31 00:19:45 +0800461 combineEvents[*psuName + "OperationalStatus"] =
462 std::make_unique<PSUCombineEvent>(
463 objectServer, io, *psuName, eventPathList, "OperationalStatus");
Cheng C Yang209ec562019-03-12 16:37:44 +0800464 }
465 return;
466}
467
Cheng C Yang916360b2019-05-07 18:47:16 +0800468void propertyInitialize(void)
Cheng C Yang209ec562019-03-12 16:37:44 +0800469{
Cheng C Yange50345b2019-04-02 17:26:15 +0800470 sensorTable = {{"power", "power/"},
471 {"curr", "current/"},
472 {"temp", "temperature/"},
473 {"in", "voltage/"},
474 {"fan", "fan_tach/"}};
475
476 labelMatch = {{"pin", PSUProperty("Input Power", 3000, 0, 6)},
477 {"pout1", PSUProperty("Output Power", 3000, 0, 6)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700478 {"pout2", PSUProperty("Output Power", 3000, 0, 6)},
479 {"pout3", PSUProperty("Output Power", 3000, 0, 6)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700480 {"power1", PSUProperty("Output Power", 3000, 0, 6)},
Cheng C Yangbdbde962019-04-26 22:50:34 +0800481 {"vin", PSUProperty("Input Voltage", 300, 0, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700482 {"vout1", PSUProperty("Output Voltage", 255, 0, 3)},
483 {"vout2", PSUProperty("Output Voltage", 255, 0, 3)},
484 {"vout3", PSUProperty("Output Voltage", 255, 0, 3)},
Jason Ling5747fab2019-10-02 16:46:23 -0700485 {"vout4", PSUProperty("Output Voltage", 255, 0, 3)},
486 {"vout5", PSUProperty("Output Voltage", 255, 0, 3)},
487 {"vout6", PSUProperty("Output Voltage", 255, 0, 3)},
488 {"vout7", PSUProperty("Output Voltage", 255, 0, 3)},
489 {"vout8", PSUProperty("Output Voltage", 255, 0, 3)},
490 {"vout9", PSUProperty("Output Voltage", 255, 0, 3)},
491 {"vout10", PSUProperty("Output Voltage", 255, 0, 3)},
492 {"vout11", PSUProperty("Output Voltage", 255, 0, 3)},
493 {"vout12", PSUProperty("Output Voltage", 255, 0, 3)},
494 {"vout13", PSUProperty("Output Voltage", 255, 0, 3)},
495 {"vout14", PSUProperty("Output Voltage", 255, 0, 3)},
496 {"vout15", PSUProperty("Output Voltage", 255, 0, 3)},
497 {"vout16", PSUProperty("Output Voltage", 255, 0, 3)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700498 {"in1", PSUProperty("Output Voltage", 255, 0, 3)},
Cheng C Yange50345b2019-04-02 17:26:15 +0800499 {"iin", PSUProperty("Input Current", 20, 0, 3)},
500 {"iout1", PSUProperty("Output Current", 255, 0, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700501 {"iout2", PSUProperty("Output Current", 255, 0, 3)},
502 {"iout3", PSUProperty("Output Current", 255, 0, 3)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700503 {"curr1", PSUProperty("Output Current", 255, 0, 3)},
Cheng C Yange50345b2019-04-02 17:26:15 +0800504 {"temp1", PSUProperty("Temperature", 127, -128, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700505 {"temp2", PSUProperty("Temperature", 127, -128, 3)},
506 {"temp3", PSUProperty("Temperature", 127, -128, 3)},
Jason Ling5747fab2019-10-02 16:46:23 -0700507 {"temp4", PSUProperty("Temperature", 127, -128, 3)},
508 {"temp5", PSUProperty("Temperature", 127, -128, 3)},
Cheng C Yang8dbb3952019-05-23 00:03:12 +0800509 {"fan1", PSUProperty("Fan Speed 1", 30000, 0, 0)},
510 {"fan2", PSUProperty("Fan Speed 2", 30000, 0, 0)}};
Cheng C Yang916360b2019-05-07 18:47:16 +0800511
512 pwmTable = {{"fan1", "Fan_1"}, {"fan2", "Fan_2"}};
Cheng C Yang58b2b532019-05-31 00:19:45 +0800513
514 limitEventMatch = {{"PredictiveFailure", {"max_alarm", "min_alarm"}},
515 {"Failure", {"crit_alarm", "lcrit_alarm"}}};
516
517 eventMatch = {
518 {"PredictiveFailure", {"power1_alarm"}},
519 {"Failure", {"in2_alarm"}},
Cheng C Yang9c45e6b2019-08-13 07:21:32 +0800520 {"ACLost", {"in1_beep"}},
521 {"FanFault", {"fan1_alarm", "fan2_alarm", "fan1_fault", "fan2_fault"}},
522 {"ConfigureError", {"in1_fault"}}};
Cheng C Yang209ec562019-03-12 16:37:44 +0800523}
524
James Feistb6c0b912019-07-09 12:21:44 -0700525int main()
Cheng C Yang209ec562019-03-12 16:37:44 +0800526{
527 boost::asio::io_service io;
528 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
529
530 systemBus->request_name("xyz.openbmc_project.PSUSensor");
531 sdbusplus::asio::object_server objectServer(systemBus);
Cheng C Yang209ec562019-03-12 16:37:44 +0800532 std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
Cheng C Yang209ec562019-03-12 16:37:44 +0800533
Cheng C Yang916360b2019-05-07 18:47:16 +0800534 propertyInitialize();
Cheng C Yang209ec562019-03-12 16:37:44 +0800535
Cheng C Yang916360b2019-05-07 18:47:16 +0800536 io.post([&]() { createSensors(io, objectServer, systemBus); });
Cheng C Yang209ec562019-03-12 16:37:44 +0800537 boost::asio::deadline_timer filterTimer(io);
538 std::function<void(sdbusplus::message::message&)> eventHandler =
539 [&](sdbusplus::message::message& message) {
540 if (message.is_method_error())
541 {
542 std::cerr << "callback method error\n";
543 return;
544 }
545 filterTimer.expires_from_now(boost::posix_time::seconds(1));
546 filterTimer.async_wait([&](const boost::system::error_code& ec) {
547 if (ec == boost::asio::error::operation_aborted)
548 {
549 return;
550 }
551 else if (ec)
552 {
553 std::cerr << "timer error\n";
554 }
Cheng C Yang916360b2019-05-07 18:47:16 +0800555 createSensors(io, objectServer, systemBus);
Cheng C Yang209ec562019-03-12 16:37:44 +0800556 });
557 };
558
559 for (const char* type : sensorTypes)
560 {
561 auto match = std::make_unique<sdbusplus::bus::match::match>(
562 static_cast<sdbusplus::bus::bus&>(*systemBus),
563 "type='signal',member='PropertiesChanged',path_namespace='" +
564 std::string(inventoryPath) + "',arg0namespace='" + type + "'",
565 eventHandler);
566 matches.emplace_back(std::move(match));
567 }
568 io.run();
569}