blob: 9880b086e55b63fae6be7a2e8472c1ab51891c0f [file] [log] [blame]
Brandon Wymana0f33ce2019-10-17 18:32:29 -05001#include "psu_manager.hpp"
2
3#include "utility.hpp"
4
Brandon Wymanaed1f752019-11-25 18:10:52 -06005using namespace phosphor::logging;
6
Brandon Wymana0f33ce2019-10-17 18:32:29 -05007namespace phosphor
8{
9namespace power
10{
11namespace manager
12{
13
Brandon Wymanaed1f752019-11-25 18:10:52 -060014PSUManager::PSUManager(sdbusplus::bus::bus& bus, const sdeventplus::Event& e,
15 const std::string& configfile) :
16 bus(bus)
17{
18 // Parse out the JSON properties
19 sys_properties properties;
20 getJSONProperties(configfile, bus, properties, psus);
21
22 using namespace sdeventplus;
23 auto interval = std::chrono::milliseconds(properties.pollInterval);
24 timer = std::make_unique<utility::Timer<ClockId::Monotonic>>(
25 e, std::bind(&PSUManager::analyze, this), interval);
26
27 minPSUs = {properties.minPowerSupplies};
28 maxPSUs = {properties.maxPowerSupplies};
29
30 // Subscribe to power state changes
31 powerService = util::getService(POWER_OBJ_PATH, POWER_IFACE, bus);
32 powerOnMatch = std::make_unique<sdbusplus::bus::match_t>(
33 bus,
34 sdbusplus::bus::match::rules::propertiesChanged(POWER_OBJ_PATH,
35 POWER_IFACE),
36 [this](auto& msg) { this->powerStateChanged(msg); });
37
38 initialize();
39}
40
41void PSUManager::getJSONProperties(
42 const std::string& path, sdbusplus::bus::bus& bus, sys_properties& p,
43 std::vector<std::unique_ptr<PowerSupply>>& psus)
44{
45 nlohmann::json configFileJSON = util::loadJSONFromFile(path.c_str());
46
47 if (configFileJSON == nullptr)
48 {
49 throw std::runtime_error("Failed to load JSON configuration file");
50 }
51
52 if (!configFileJSON.contains("SystemProperties"))
53 {
54 throw std::runtime_error("Missing required SystemProperties");
55 }
56
57 if (!configFileJSON.contains("PowerSupplies"))
58 {
59 throw std::runtime_error("Missing required PowerSupplies");
60 }
61
62 auto sysProps = configFileJSON["SystemProperties"];
63
64 if (!sysProps.contains("pollInterval"))
65 {
66 throw std::runtime_error("Missing required pollInterval property");
67 }
68
69 p.pollInterval = sysProps["pollInterval"];
70
71 if (sysProps.contains("MinPowerSupplies"))
72 {
73 p.minPowerSupplies = sysProps["MinPowerSupplies"];
74 }
75 else
76 {
77 p.minPowerSupplies = 0;
78 }
79
80 if (sysProps.contains("MaxPowerSupplies"))
81 {
82 p.maxPowerSupplies = sysProps["MaxPowerSupplies"];
83 }
84 else
85 {
86 p.maxPowerSupplies = 0;
87 }
88
89 for (auto psuJSON : configFileJSON["PowerSupplies"])
90 {
Brandon Wymanc63941c2020-01-27 16:49:33 -060091 if (psuJSON.contains("Inventory") && psuJSON.contains("Bus") &&
92 psuJSON.contains("Address"))
Brandon Wymanaed1f752019-11-25 18:10:52 -060093 {
94 std::string invpath = psuJSON["Inventory"];
Brandon Wymanc63941c2020-01-27 16:49:33 -060095 std::uint8_t i2cbus = psuJSON["Bus"];
96 std::string i2caddr = psuJSON["Address"];
97 auto psu =
98 std::make_unique<PowerSupply>(bus, invpath, i2cbus, i2caddr);
Brandon Wymanaed1f752019-11-25 18:10:52 -060099 psus.emplace_back(std::move(psu));
100 }
Brandon Wymanc63941c2020-01-27 16:49:33 -0600101 else
102 {
103 log<level::ERR>("Insufficient PowerSupply properties");
104 }
Brandon Wymanaed1f752019-11-25 18:10:52 -0600105 }
106
107 if (psus.empty())
108 {
109 throw std::runtime_error("No power supplies to monitor");
110 }
111}
112
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500113void PSUManager::powerStateChanged(sdbusplus::message::message& msg)
114{
115 int32_t state = 0;
116 std::string msgSensor;
117 std::map<std::string, sdbusplus::message::variant<int32_t>> msgData;
118 msg.read(msgSensor, msgData);
119
120 // Check if it was the Present property that changed.
121 auto valPropMap = msgData.find("state");
122 if (valPropMap != msgData.end())
123 {
124 state = std::get<int32_t>(valPropMap->second);
125
126 // Power is on when state=1. Clear faults.
127 if (state)
128 {
129 powerOn = true;
130 clearFaults();
131 }
132 else
133 {
134 powerOn = false;
135 }
136 }
137}
138
139} // namespace manager
140} // namespace power
141} // namespace phosphor