xref: /openbmc/phosphor-power/phosphor-power-supply/psu_manager.hpp (revision 5b27a95bec8bdcd84728fbf3415e1760aa95ebe5)
1 #pragma once
2 
3 #include "power_supply.hpp"
4 #include "types.hpp"
5 #include "utility.hpp"
6 
7 #include <phosphor-logging/log.hpp>
8 #include <sdbusplus/bus/match.hpp>
9 #include <sdeventplus/event.hpp>
10 #include <sdeventplus/utility/timer.hpp>
11 
12 using namespace phosphor::power::psu;
13 using namespace phosphor::logging;
14 
15 namespace phosphor
16 {
17 namespace power
18 {
19 namespace 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  */
28 class 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     {
50         // 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();
59     }
60 
61     /**
62      * Initializes the manager.
63      *
64      * Get current BMC state, ...
65      */
66     void initialize()
67     {
68         // 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();
94     }
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     {
112         for (auto& psu : psus)
113         {
114             psu.clearFaults();
115         }
116     }
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     {
134         for (auto& psu : psus)
135         {
136             psu.analyze();
137         }
138     }
139 
140     /** @brief True if the power is on. */
141     bool powerOn = false;
142 
143     /** @brief Used as part of subscribing to power on state changes*/
144     std::string powerService;
145 
146     /** @brief Used to subscribe to D-Bus power on state changes */
147     std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch;
148 
149     /**
150      * @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      */
167     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;
179 };
180 
181 } // namespace manager
182 } // namespace power
183 } // namespace phosphor
184