blob: 105270539a4090fc07e95fdad4cba5e4d9f6c083 [file] [log] [blame]
Brandon Wyman2bac8602019-09-12 18:12:21 -05001#pragma once
2
Brandon Wymana0f33ce2019-10-17 18:32:29 -05003#include "power_supply.hpp"
4#include "types.hpp"
5#include "utility.hpp"
6
7#include <phosphor-logging/log.hpp>
Brandon Wyman2bac8602019-09-12 18:12:21 -05008#include <sdbusplus/bus/match.hpp>
9#include <sdeventplus/event.hpp>
10#include <sdeventplus/utility/timer.hpp>
11
Brandon Wymana0f33ce2019-10-17 18:32:29 -050012using namespace phosphor::power::psu;
13using namespace phosphor::logging;
14
Brandon Wyman2bac8602019-09-12 18:12:21 -050015namespace phosphor
16{
17namespace power
18{
19namespace manager
20{
21
22/**
23 * @class PSUManager
24 *
25 * This class will create an object used to manage and monitor a list of power
26 * supply devices.
27 */
28class PSUManager
29{
30 public:
31 PSUManager() = delete;
32 ~PSUManager() = default;
33 PSUManager(const PSUManager&) = delete;
34 PSUManager& operator=(const PSUManager&) = delete;
35 PSUManager(PSUManager&&) = delete;
36 PSUManager& operator=(PSUManager&&) = delete;
37
38 /**
39 * Constructor
40 *
41 * @param[in] bus - D-Bus bus object
42 * @param[in] e - event object
43 * @param[in] i - polling interval in milliseconds
44 */
45 PSUManager(sdbusplus::bus::bus& bus, const sdeventplus::Event& e,
46 std::chrono::milliseconds i) :
47 bus(bus),
48 timer(e, std::bind(&PSUManager::analyze, this), i)
49 {
Brandon Wymana0f33ce2019-10-17 18:32:29 -050050 // Subscribe to power state changes
51 powerService = util::getService(POWER_OBJ_PATH, POWER_IFACE, bus);
52 powerOnMatch = std::make_unique<sdbusplus::bus::match_t>(
53 bus,
54 sdbusplus::bus::match::rules::propertiesChanged(POWER_OBJ_PATH,
55 POWER_IFACE),
56 [this](auto& msg) { this->powerStateChanged(msg); });
57
58 initialize();
Brandon Wyman2bac8602019-09-12 18:12:21 -050059 }
60
61 /**
62 * Initializes the manager.
63 *
64 * Get current BMC state, ...
65 */
66 void initialize()
67 {
Brandon Wymana0f33ce2019-10-17 18:32:29 -050068 // When state = 1, system is powered on
69 int32_t state = 0;
70
71 try
72 {
73 // Use getProperty utility function to get power state.
74 util::getProperty<int32_t>(POWER_IFACE, "state", POWER_OBJ_PATH,
75 powerService, bus, state);
76
77 if (state)
78 {
79 powerOn = true;
80 }
81 else
82 {
83 powerOn = false;
84 }
85 }
86 catch (std::exception& e)
87 {
88 log<level::INFO>("Failed to get power state. Assuming it is off.");
89 powerOn = false;
90 }
91
92 clearFaults();
93 updateInventory();
Brandon Wyman2bac8602019-09-12 18:12:21 -050094 }
95
96 /**
97 * Starts the timer to start monitoring the list of devices.
98 */
99 int run()
100 {
101 return timer.get_event().loop();
102 }
103
104 /**
105 * This function will be called in various situations in order to clear
106 * any fault status bits that may have been set, in order to start over
107 * with a clean state. Presence changes and power state changes will want
108 * to clear any faults logged.
109 */
110 void clearFaults()
111 {
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500112 for (auto& psu : psus)
113 {
114 psu.clearFaults();
115 }
Brandon Wyman2bac8602019-09-12 18:12:21 -0500116 }
117
118 private:
119 /**
120 * The D-Bus object
121 */
122 sdbusplus::bus::bus& bus;
123
124 /**
125 * The timer that runs to periodically check the power supplies.
126 */
127 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
128
129 /**
130 * Analyze the status of each of the power supplies.
131 */
132 void analyze()
133 {
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500134 for (auto& psu : psus)
135 {
136 psu.analyze();
137 }
Brandon Wyman2bac8602019-09-12 18:12:21 -0500138 }
139
140 /** @brief True if the power is on. */
141 bool powerOn = false;
142
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500143 /** @brief Used as part of subscribing to power on state changes*/
144 std::string powerService;
145
Brandon Wyman2bac8602019-09-12 18:12:21 -0500146 /** @brief Used to subscribe to D-Bus power on state changes */
147 std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch;
148
149 /**
Brandon Wyman2bac8602019-09-12 18:12:21 -0500150 * @brief Callback for power state property changes
151 *
152 * Process changes to the powered on state property for the system.
153 *
154 * @param[in] msg - Data associated with the power state signal
155 */
156 void powerStateChanged(sdbusplus::message::message& msg);
157
158 /**
159 * @brief Adds properties to the inventory.
160 *
161 * Reads the values from the devices and writes them to the associated
162 * power supply D-Bus inventory objects.
163 *
164 * This needs to be done on startup, and each time the presence state
165 * changes.
166 */
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500167 void updateInventory()
168 {
169 for (auto& psu : psus)
170 {
171 psu.updateInventory();
172 }
173 }
174
175 /**
176 * @brief The vector for power supplies.
177 */
178 std::vector<PowerSupply> psus;
Brandon Wyman2bac8602019-09-12 18:12:21 -0500179};
180
181} // namespace manager
182} // namespace power
183} // namespace phosphor