blob: e364a246d9b1421352651fbd359957bda272a623 [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*/
Cheng C Yang58b2b532019-05-31 00:19:45 +080016#include <PSUEvent.hpp>
Cheng C Yang209ec562019-03-12 16:37:44 +080017#include <PSUSensor.hpp>
18#include <Utils.hpp>
19#include <boost/algorithm/string/predicate.hpp>
20#include <boost/algorithm/string/replace.hpp>
21#include <boost/container/flat_set.hpp>
James Feist24f02f22019-04-15 11:05:39 -070022#include <filesystem>
Cheng C Yang209ec562019-03-12 16:37:44 +080023#include <fstream>
Cheng C Yang58b2b532019-05-31 00:19:45 +080024#include <iostream>
Cheng C Yang209ec562019-03-12 16:37:44 +080025#include <regex>
26#include <sdbusplus/asio/connection.hpp>
27#include <sdbusplus/asio/object_server.hpp>
28
Jason Ling5747fab2019-10-02 16:46:23 -070029static constexpr std::array<const char*, 2> sensorTypes = {
30 "xyz.openbmc_project.Configuration.pmbus",
31 "xyz.openbmc_project.Configuration.MAX34451"};
Cheng C Yang209ec562019-03-12 16:37:44 +080032
Vijay Khemkaa0b731d2019-07-24 15:58:48 -070033static std::vector<std::string> pmbusNames = {"pmbus", "pxe1610", "ina219",
Jason Ling5747fab2019-10-02 16:46:23 -070034 "ina230", "max34451"};
Cheng C Yang209ec562019-03-12 16:37:44 +080035namespace fs = std::filesystem;
36
Cheng C Yang916360b2019-05-07 18:47:16 +080037static boost::container::flat_map<std::string, std::unique_ptr<PSUSensor>>
38 sensors;
Cheng C Yang58b2b532019-05-31 00:19:45 +080039static boost::container::flat_map<std::string, std::unique_ptr<PSUCombineEvent>>
40 combineEvents;
Cheng C Yang916360b2019-05-07 18:47:16 +080041static boost::container::flat_map<std::string, std::unique_ptr<PwmSensor>>
42 pwmSensors;
43static boost::container::flat_map<std::string, std::string> sensorTable;
44static boost::container::flat_map<std::string, PSUProperty> labelMatch;
45static boost::container::flat_map<std::string, std::string> pwmTable;
Cheng C Yang58b2b532019-05-31 00:19:45 +080046static boost::container::flat_map<std::string, std::vector<std::string>>
47 eventMatch;
48static boost::container::flat_map<std::string, std::vector<std::string>>
49 limitEventMatch;
50
51// Function CheckEvent will check each attribute from eventMatch table in the
52// sysfs. If the attributes exists in sysfs, then store the complete path
53// of the attribute into eventPathList.
54void checkEvent(
55 const std::string& directory,
56 const boost::container::flat_map<std::string, std::vector<std::string>>&
57 eventMatch,
58 boost::container::flat_map<std::string, std::vector<std::string>>&
59 eventPathList)
60{
61 for (const auto& match : eventMatch)
62 {
63 const std::vector<std::string>& eventAttrs = match.second;
64 const std::string& eventName = match.first;
65 for (const auto& eventAttr : eventAttrs)
66 {
67 auto eventPath = directory + "/" + eventAttr;
68
69 std::ifstream eventFile(eventPath);
70 if (!eventFile.good())
71 {
72 continue;
73 }
74
75 eventPathList[eventName].push_back(eventPath);
76 }
77 }
78}
79
80// Function checkEventLimits will check all the psu related xxx_input attributes
81// in sysfs to see if xxx_crit_alarm xxx_lcrit_alarm xxx_max_alarm
82// xxx_min_alarm exist, then store the existing paths of the alarm attributes
83// to eventPathList.
84void checkEventLimits(
85 const std::string& sensorPathStr,
86 const boost::container::flat_map<std::string, std::vector<std::string>>&
87 limitEventMatch,
88 boost::container::flat_map<std::string, std::vector<std::string>>&
89 eventPathList)
90{
91 for (const auto& limitMatch : limitEventMatch)
92 {
93 const std::vector<std::string>& limitEventAttrs = limitMatch.second;
94 const std::string& eventName = limitMatch.first;
95 for (const auto& limitEventAttr : limitEventAttrs)
96 {
97 auto limitEventPath =
98 boost::replace_all_copy(sensorPathStr, "input", limitEventAttr);
99 std::ifstream eventFile(limitEventPath);
100 if (!eventFile.good())
101 {
102 continue;
103 }
104 eventPathList[eventName].push_back(limitEventPath);
105 }
106 }
107}
Cheng C Yang916360b2019-05-07 18:47:16 +0800108
109static void checkPWMSensor(const fs::path& sensorPath, std::string& labelHead,
110 const std::string& interfacePath,
111 sdbusplus::asio::object_server& objectServer,
112 std::string psuName)
113{
114 for (const auto& pwmName : pwmTable)
115 {
116 if (pwmName.first != labelHead)
117 {
118 continue;
119 }
120
121 const std::string& sensorPathStr = sensorPath.string();
122 const std::string& pwmPathStr =
123 boost::replace_all_copy(sensorPathStr, "input", "target");
124 std::ifstream pwmFile(pwmPathStr);
125 if (!pwmFile.good())
126 {
127 continue;
128 }
129
130 auto findPWMSensor = pwmSensors.find(psuName + labelHead);
131 if (findPWMSensor != pwmSensors.end())
132 {
133 continue;
134 }
135
136 pwmSensors[psuName + labelHead] = std::make_unique<PwmSensor>(
137 "Pwm_" + psuName + "_" + pwmName.second, pwmPathStr, objectServer,
Cheng C Yang15266a92019-06-12 08:42:52 +0800138 interfacePath + "_" + pwmName.second);
Cheng C Yang916360b2019-05-07 18:47:16 +0800139 }
140}
141
142void createSensors(boost::asio::io_service& io,
143 sdbusplus::asio::object_server& objectServer,
144 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
Cheng C Yang209ec562019-03-12 16:37:44 +0800145{
146
147 ManagedObjectType sensorConfigs;
148 bool useCache = false;
149
Cheng C Yang58b2b532019-05-31 00:19:45 +0800150 // TODO may need only modify the ones that need to be changed.
151 sensors.clear();
Cheng C Yang92498eb2019-09-26 21:59:25 +0800152 combineEvents.clear();
Cheng C Yang209ec562019-03-12 16:37:44 +0800153 for (const char* type : sensorTypes)
154 {
155 if (!getSensorConfiguration(type, dbusConnection, sensorConfigs,
156 useCache))
157 {
158 std::cerr << "error get sensor config from entity manager\n";
159 return;
160 }
161 useCache = true;
162 }
163
164 std::vector<fs::path> pmbusPaths;
165 if (!findFiles(fs::path("/sys/class/hwmon"), "name", pmbusPaths))
166 {
167 std::cerr << "No PSU sensors in system\n";
168 return;
169 }
170
171 boost::container::flat_set<std::string> directories;
172 for (const auto& pmbusPath : pmbusPaths)
173 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800174 boost::container::flat_map<std::string, std::vector<std::string>>
175 eventPathList;
176
177 std::ifstream nameFile(pmbusPath);
178 if (!nameFile.good())
179 {
180 std::cerr << "Failure reading " << pmbusPath << "\n";
181 continue;
182 }
183
184 std::string pmbusName;
185 std::getline(nameFile, pmbusName);
186 nameFile.close();
Vijay Khemka996bad12019-05-28 15:15:16 -0700187
188 if (std::find(pmbusNames.begin(), pmbusNames.end(), pmbusName) ==
189 pmbusNames.end())
Cheng C Yang58b2b532019-05-31 00:19:45 +0800190 {
191 continue;
192 }
193
194 const std::string* psuName;
Cheng C Yang209ec562019-03-12 16:37:44 +0800195 auto directory = pmbusPath.parent_path();
196
197 auto ret = directories.insert(directory.string());
198 if (!ret.second)
199 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800200 continue; // check if path has already been searched
Cheng C Yang209ec562019-03-12 16:37:44 +0800201 }
202
James Feistb6c0b912019-07-09 12:21:44 -0700203 fs::path device = directory / "device";
Cheng C Yang209ec562019-03-12 16:37:44 +0800204 std::string deviceName = fs::canonical(device).stem();
205 auto findHyphen = deviceName.find("-");
206 if (findHyphen == std::string::npos)
207 {
208 std::cerr << "found bad device" << deviceName << "\n";
209 continue;
210 }
211 std::string busStr = deviceName.substr(0, findHyphen);
212 std::string addrStr = deviceName.substr(findHyphen + 1);
213
214 size_t bus = 0;
215 size_t addr = 0;
216
217 try
218 {
219 bus = std::stoi(busStr);
220 addr = std::stoi(addrStr, 0, 16);
221 }
James Feistb6c0b912019-07-09 12:21:44 -0700222 catch (std::invalid_argument&)
Cheng C Yang209ec562019-03-12 16:37:44 +0800223 {
224 continue;
225 }
226
Cheng C Yang209ec562019-03-12 16:37:44 +0800227 const std::pair<std::string, boost::container::flat_map<
228 std::string, BasicVariantType>>*
229 baseConfig = nullptr;
230 const SensorData* sensorData = nullptr;
231 const std::string* interfacePath = nullptr;
232 const char* sensorType = nullptr;
233
234 for (const std::pair<sdbusplus::message::object_path, SensorData>&
235 sensor : sensorConfigs)
236 {
237 sensorData = &(sensor.second);
238 for (const char* type : sensorTypes)
239 {
240 auto sensorBase = sensorData->find(type);
241 if (sensorBase != sensorData->end())
242 {
243 baseConfig = &(*sensorBase);
244 sensorType = type;
245 break;
246 }
247 }
248 if (baseConfig == nullptr)
249 {
250 std::cerr << "error finding base configuration for "
251 << deviceName << "\n";
252 continue;
253 }
254
255 auto configBus = baseConfig->second.find("Bus");
256 auto configAddress = baseConfig->second.find("Address");
257
258 if (configBus == baseConfig->second.end() ||
259 configAddress == baseConfig->second.end())
260 {
Cheng C Yang58b2b532019-05-31 00:19:45 +0800261 std::cerr << "error finding necessary entry in configuration\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800262 continue;
263 }
264
Cheng C Yang58b2b532019-05-31 00:19:45 +0800265 const uint64_t* confBus;
266 const uint64_t* confAddr;
267 if (!(confBus = std::get_if<uint64_t>(&(configBus->second))) ||
268 !(confAddr = std::get_if<uint64_t>(&(configAddress->second))))
269 {
270 std::cerr
271 << "Canot get bus or address, invalid configuration\n";
272 continue;
273 }
274
275 if ((*confBus != bus) || (*confAddr != addr))
Cheng C Yang209ec562019-03-12 16:37:44 +0800276 {
277 continue;
278 }
279
280 interfacePath = &(sensor.first.str);
281 break;
282 }
283 if (interfacePath == nullptr)
284 {
285 std::cerr << "failed to find match for " << deviceName << "\n";
286 continue;
287 }
288
Cheng C Yange50345b2019-04-02 17:26:15 +0800289 auto findPSUName = baseConfig->second.find("Name");
290 if (findPSUName == baseConfig->second.end())
Cheng C Yang209ec562019-03-12 16:37:44 +0800291 {
292 std::cerr << "could not determine configuration name for "
293 << deviceName << "\n";
294 continue;
295 }
296
Cheng C Yang58b2b532019-05-31 00:19:45 +0800297 if (!(psuName = std::get_if<std::string>(&(findPSUName->second))))
298 {
299 std::cerr << "Cannot find psu name, invalid configuration\n";
300 continue;
301 }
302 checkEvent(directory.string(), eventMatch, eventPathList);
303
Vijay Khemka996bad12019-05-28 15:15:16 -0700304 /* Check if there are more sensors in the same interface */
305 int i = 1;
306 std::vector<std::string> psuNames;
307 do
308 {
309 psuNames.push_back(std::get<std::string>(findPSUName->second));
310 findPSUName = baseConfig->second.find("Name" + std::to_string(i++));
311 } while (findPSUName != baseConfig->second.end());
312
Cheng C Yange50345b2019-04-02 17:26:15 +0800313 std::vector<fs::path> sensorPaths;
James Feistb6c0b912019-07-09 12:21:44 -0700314 if (!findFiles(directory, R"(\w\d+_input$)", sensorPaths, 0))
Cheng C Yang209ec562019-03-12 16:37:44 +0800315 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800316 std::cerr << "No PSU non-label sensor in PSU\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800317 continue;
318 }
319
Vijay Khemka996bad12019-05-28 15:15:16 -0700320 /* Find array of labels to be exposed if it is defined in config */
321 std::vector<std::string> findLabels;
322 auto findLabelObj = baseConfig->second.find("Labels");
323 if (findLabelObj != baseConfig->second.end())
324 {
325 findLabels =
326 std::get<std::vector<std::string>>(findLabelObj->second);
327 }
328
Jason Ling5747fab2019-10-02 16:46:23 -0700329 std::regex sensorNameRegEx("([A-Za-z]+)[0-9]*_");
330 std::smatch matches;
331
Cheng C Yange50345b2019-04-02 17:26:15 +0800332 for (const auto& sensorPath : sensorPaths)
Cheng C Yang209ec562019-03-12 16:37:44 +0800333 {
Cheng C Yang209ec562019-03-12 16:37:44 +0800334
Cheng C Yange50345b2019-04-02 17:26:15 +0800335 std::string labelHead;
336 std::string sensorPathStr = sensorPath.string();
337 std::string sensorNameStr = sensorPath.filename();
Jason Ling5747fab2019-10-02 16:46:23 -0700338 std::string sensorNameSubStr{""};
339 if (std::regex_search(sensorNameStr, matches, sensorNameRegEx))
340 {
341 sensorNameSubStr = matches[1];
342 }
343 else
344 {
345 std::cerr << "Couldn't extract the alpha prefix from "
346 << sensorNameStr;
347 continue;
348 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800349
Cheng C Yangecba9de2019-09-12 23:41:50 +0800350 auto labelPath =
351 boost::replace_all_copy(sensorPathStr, "input", "label");
352 std::ifstream labelFile(labelPath);
353 if (!labelFile.good())
Cheng C Yang209ec562019-03-12 16:37:44 +0800354 {
Cheng C Yangecba9de2019-09-12 23:41:50 +0800355 std::cerr << "Failure reading " << sensorPath << "\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800356 labelHead = sensorNameStr.substr(0, sensorNameStr.find("_"));
Cheng C Yang209ec562019-03-12 16:37:44 +0800357 }
358 else
359 {
Cheng C Yange50345b2019-04-02 17:26:15 +0800360 std::string label;
361 std::getline(labelFile, label);
362 labelFile.close();
Cheng C Yange50345b2019-04-02 17:26:15 +0800363 auto findSensor = sensors.find(label);
364 if (findSensor != sensors.end())
365 {
366 continue;
367 }
368
369 labelHead = label.substr(0, label.find(" "));
370 }
371
Cheng C Yang916360b2019-05-07 18:47:16 +0800372 checkPWMSensor(sensorPath, labelHead, *interfacePath, objectServer,
Vijay Khemka996bad12019-05-28 15:15:16 -0700373 psuNames[0]);
Cheng C Yang916360b2019-05-07 18:47:16 +0800374
Vijay Khemka996bad12019-05-28 15:15:16 -0700375 if (!findLabels.empty())
376 {
377 /* Check if this labelHead is enabled in config file */
378 if (std::find(findLabels.begin(), findLabels.end(),
379 labelHead) == findLabels.end())
380 {
Jason Ling5747fab2019-10-02 16:46:23 -0700381 std::cerr << "couldn't find " << labelHead
382 << " in the Labels list\n";
Vijay Khemka996bad12019-05-28 15:15:16 -0700383 continue;
384 }
385 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800386
Vijay Khemka996bad12019-05-28 15:15:16 -0700387 /* Find out sensor name index for this label */
Jason Ling5747fab2019-10-02 16:46:23 -0700388 std::regex rgx("[A-Za-z]+([0-9]+)");
389 int nameIndex{0};
390 if (std::regex_search(labelHead, matches, rgx))
Vijay Khemka996bad12019-05-28 15:15:16 -0700391 {
Jason Ling5747fab2019-10-02 16:46:23 -0700392 nameIndex = std::stoi(matches[1]);
Vijay Khemka996bad12019-05-28 15:15:16 -0700393 }
394 else
James Feist17ab6e02019-06-25 12:28:13 -0700395 {
Vijay Khemka996bad12019-05-28 15:15:16 -0700396 nameIndex = 0;
James Feist17ab6e02019-06-25 12:28:13 -0700397 }
Cheng C Yange50345b2019-04-02 17:26:15 +0800398
Jason Ling5747fab2019-10-02 16:46:23 -0700399 if (psuNames.size() <= nameIndex)
400 {
401 std::cerr << "Could not pair " << labelHead
402 << " with a Name field\n";
403 continue;
404 }
405
Cheng C Yange50345b2019-04-02 17:26:15 +0800406 auto findProperty = labelMatch.find(labelHead);
407 if (findProperty == labelMatch.end())
Cheng C Yang209ec562019-03-12 16:37:44 +0800408 {
Jason Ling5747fab2019-10-02 16:46:23 -0700409 std::cerr << "Could not find " << labelHead << "\n";
Cheng C Yang209ec562019-03-12 16:37:44 +0800410 continue;
411 }
412
Cheng C Yang58b2b532019-05-31 00:19:45 +0800413 checkEventLimits(sensorPathStr, limitEventMatch, eventPathList);
414
Cheng C Yange50345b2019-04-02 17:26:15 +0800415 unsigned int factor =
416 std::pow(10, findProperty->second.sensorScaleFactor);
Vijay Khemka996bad12019-05-28 15:15:16 -0700417
Vijay Khemkadbdcfe02019-07-25 12:56:17 -0700418 /* Change first char of substring to uppercase */
419 char firstChar = sensorNameSubStr[0] - 0x20;
420 std::string strScaleFactor =
421 firstChar + sensorNameSubStr.substr(1) + "ScaleFactor";
422
423 auto findScaleFactor = baseConfig->second.find(strScaleFactor);
Vijay Khemka53ca4442019-07-23 11:03:55 -0700424 if (findScaleFactor != baseConfig->second.end())
425 {
426 factor =
427 std::visit(VariantToIntVisitor(), findScaleFactor->second);
428 }
429
Vijay Khemka996bad12019-05-28 15:15:16 -0700430 std::vector<thresholds::Threshold> sensorThresholds;
431
James Feist17ab6e02019-06-25 12:28:13 -0700432 if (!parseThresholdsFromConfig(*sensorData, sensorThresholds))
Cheng C Yange50345b2019-04-02 17:26:15 +0800433 {
James Feist17ab6e02019-06-25 12:28:13 -0700434 std::cerr << "error populating thresholds for "
435 << sensorNameSubStr << "\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800436 }
437
438 auto findSensorType = sensorTable.find(sensorNameSubStr);
439 if (findSensorType == sensorTable.end())
440 {
Jason Ling5747fab2019-10-02 16:46:23 -0700441 std::cerr << sensorNameSubStr
442 << " is not a recognize sensor file\n";
Cheng C Yange50345b2019-04-02 17:26:15 +0800443 continue;
444 }
445
446 std::string sensorName =
Vijay Khemka996bad12019-05-28 15:15:16 -0700447 psuNames[nameIndex] + " " + findProperty->second.labelTypeName;
Cheng C Yange50345b2019-04-02 17:26:15 +0800448
Cheng C Yang58b2b532019-05-31 00:19:45 +0800449 sensors[sensorName] = std::make_unique<PSUSensor>(
Cheng C Yange50345b2019-04-02 17:26:15 +0800450 sensorPathStr, sensorType, objectServer, dbusConnection, io,
Cheng C Yang209ec562019-03-12 16:37:44 +0800451 sensorName, std::move(sensorThresholds), *interfacePath,
Cheng C Yange50345b2019-04-02 17:26:15 +0800452 findSensorType->second, factor, findProperty->second.maxReading,
453 findProperty->second.minReading);
Cheng C Yang209ec562019-03-12 16:37:44 +0800454 }
Cheng C Yang58b2b532019-05-31 00:19:45 +0800455
456 // OperationalStatus event
Cheng C Yang92498eb2019-09-26 21:59:25 +0800457 combineEvents[*psuName + "OperationalStatus"] = nullptr;
Cheng C Yang58b2b532019-05-31 00:19:45 +0800458 combineEvents[*psuName + "OperationalStatus"] =
459 std::make_unique<PSUCombineEvent>(
460 objectServer, io, *psuName, eventPathList, "OperationalStatus");
Cheng C Yang209ec562019-03-12 16:37:44 +0800461 }
462 return;
463}
464
Cheng C Yang916360b2019-05-07 18:47:16 +0800465void propertyInitialize(void)
Cheng C Yang209ec562019-03-12 16:37:44 +0800466{
Cheng C Yange50345b2019-04-02 17:26:15 +0800467 sensorTable = {{"power", "power/"},
468 {"curr", "current/"},
469 {"temp", "temperature/"},
470 {"in", "voltage/"},
471 {"fan", "fan_tach/"}};
472
473 labelMatch = {{"pin", PSUProperty("Input Power", 3000, 0, 6)},
474 {"pout1", PSUProperty("Output Power", 3000, 0, 6)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700475 {"pout2", PSUProperty("Output Power", 3000, 0, 6)},
476 {"pout3", PSUProperty("Output Power", 3000, 0, 6)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700477 {"power1", PSUProperty("Output Power", 3000, 0, 6)},
Cheng C Yangbdbde962019-04-26 22:50:34 +0800478 {"vin", PSUProperty("Input Voltage", 300, 0, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700479 {"vout1", PSUProperty("Output Voltage", 255, 0, 3)},
480 {"vout2", PSUProperty("Output Voltage", 255, 0, 3)},
481 {"vout3", PSUProperty("Output Voltage", 255, 0, 3)},
Jason Ling5747fab2019-10-02 16:46:23 -0700482 {"vout4", PSUProperty("Output Voltage", 255, 0, 3)},
483 {"vout5", PSUProperty("Output Voltage", 255, 0, 3)},
484 {"vout6", PSUProperty("Output Voltage", 255, 0, 3)},
485 {"vout7", PSUProperty("Output Voltage", 255, 0, 3)},
486 {"vout8", PSUProperty("Output Voltage", 255, 0, 3)},
487 {"vout9", PSUProperty("Output Voltage", 255, 0, 3)},
488 {"vout10", PSUProperty("Output Voltage", 255, 0, 3)},
489 {"vout11", PSUProperty("Output Voltage", 255, 0, 3)},
490 {"vout12", PSUProperty("Output Voltage", 255, 0, 3)},
491 {"vout13", PSUProperty("Output Voltage", 255, 0, 3)},
492 {"vout14", PSUProperty("Output Voltage", 255, 0, 3)},
493 {"vout15", PSUProperty("Output Voltage", 255, 0, 3)},
494 {"vout16", PSUProperty("Output Voltage", 255, 0, 3)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700495 {"in1", PSUProperty("Output Voltage", 255, 0, 3)},
Cheng C Yange50345b2019-04-02 17:26:15 +0800496 {"iin", PSUProperty("Input Current", 20, 0, 3)},
497 {"iout1", PSUProperty("Output Current", 255, 0, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700498 {"iout2", PSUProperty("Output Current", 255, 0, 3)},
499 {"iout3", PSUProperty("Output Current", 255, 0, 3)},
Vijay Khemkabe664412019-06-28 12:10:04 -0700500 {"curr1", PSUProperty("Output Current", 255, 0, 3)},
Cheng C Yange50345b2019-04-02 17:26:15 +0800501 {"temp1", PSUProperty("Temperature", 127, -128, 3)},
Vijay Khemka996bad12019-05-28 15:15:16 -0700502 {"temp2", PSUProperty("Temperature", 127, -128, 3)},
503 {"temp3", PSUProperty("Temperature", 127, -128, 3)},
Jason Ling5747fab2019-10-02 16:46:23 -0700504 {"temp4", PSUProperty("Temperature", 127, -128, 3)},
505 {"temp5", PSUProperty("Temperature", 127, -128, 3)},
Cheng C Yang8dbb3952019-05-23 00:03:12 +0800506 {"fan1", PSUProperty("Fan Speed 1", 30000, 0, 0)},
507 {"fan2", PSUProperty("Fan Speed 2", 30000, 0, 0)}};
Cheng C Yang916360b2019-05-07 18:47:16 +0800508
509 pwmTable = {{"fan1", "Fan_1"}, {"fan2", "Fan_2"}};
Cheng C Yang58b2b532019-05-31 00:19:45 +0800510
511 limitEventMatch = {{"PredictiveFailure", {"max_alarm", "min_alarm"}},
512 {"Failure", {"crit_alarm", "lcrit_alarm"}}};
513
514 eventMatch = {
515 {"PredictiveFailure", {"power1_alarm"}},
516 {"Failure", {"in2_alarm"}},
Cheng C Yang9c45e6b2019-08-13 07:21:32 +0800517 {"ACLost", {"in1_beep"}},
518 {"FanFault", {"fan1_alarm", "fan2_alarm", "fan1_fault", "fan2_fault"}},
519 {"ConfigureError", {"in1_fault"}}};
Cheng C Yang209ec562019-03-12 16:37:44 +0800520}
521
James Feistb6c0b912019-07-09 12:21:44 -0700522int main()
Cheng C Yang209ec562019-03-12 16:37:44 +0800523{
524 boost::asio::io_service io;
525 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
526
527 systemBus->request_name("xyz.openbmc_project.PSUSensor");
528 sdbusplus::asio::object_server objectServer(systemBus);
Cheng C Yang209ec562019-03-12 16:37:44 +0800529 std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
Cheng C Yang209ec562019-03-12 16:37:44 +0800530
Cheng C Yang916360b2019-05-07 18:47:16 +0800531 propertyInitialize();
Cheng C Yang209ec562019-03-12 16:37:44 +0800532
Cheng C Yang916360b2019-05-07 18:47:16 +0800533 io.post([&]() { createSensors(io, objectServer, systemBus); });
Cheng C Yang209ec562019-03-12 16:37:44 +0800534 boost::asio::deadline_timer filterTimer(io);
535 std::function<void(sdbusplus::message::message&)> eventHandler =
536 [&](sdbusplus::message::message& message) {
537 if (message.is_method_error())
538 {
539 std::cerr << "callback method error\n";
540 return;
541 }
542 filterTimer.expires_from_now(boost::posix_time::seconds(1));
543 filterTimer.async_wait([&](const boost::system::error_code& ec) {
544 if (ec == boost::asio::error::operation_aborted)
545 {
546 return;
547 }
548 else if (ec)
549 {
550 std::cerr << "timer error\n";
551 }
Cheng C Yang916360b2019-05-07 18:47:16 +0800552 createSensors(io, objectServer, systemBus);
Cheng C Yang209ec562019-03-12 16:37:44 +0800553 });
554 };
555
556 for (const char* type : sensorTypes)
557 {
558 auto match = std::make_unique<sdbusplus::bus::match::match>(
559 static_cast<sdbusplus::bus::bus&>(*systemBus),
560 "type='signal',member='PropertiesChanged',path_namespace='" +
561 std::string(inventoryPath) + "',arg0namespace='" + type + "'",
562 eventHandler);
563 matches.emplace_back(std::move(match));
564 }
565 io.run();
566}