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 struct sys_properties
13 {
14     int pollInterval;
15     int minPowerSupplies;
16     int maxPowerSupplies;
17 };
18 
19 using namespace phosphor::power::psu;
20 using namespace phosphor::logging;
21 
22 namespace phosphor
23 {
24 namespace power
25 {
26 namespace manager
27 {
28 
29 /**
30  * @class PSUManager
31  *
32  * This class will create an object used to manage and monitor a list of power
33  * supply devices.
34  */
35 class PSUManager
36 {
37   public:
38     PSUManager() = delete;
39     ~PSUManager() = default;
40     PSUManager(const PSUManager&) = delete;
41     PSUManager& operator=(const PSUManager&) = delete;
42     PSUManager(PSUManager&&) = delete;
43     PSUManager& operator=(PSUManager&&) = delete;
44 
45     /**
46      * Constructor
47      *
48      * @param[in] bus - D-Bus bus object
49      * @param[in] e - event object
50      * @param[in] configfile - string path to the configuration file
51      */
52     PSUManager(sdbusplus::bus::bus& bus, const sdeventplus::Event& e,
53                const std::string& configfile);
54 
55     void getJSONProperties(const std::string& path, sdbusplus::bus::bus& bus,
56                            sys_properties& p,
57                            std::vector<std::unique_ptr<PowerSupply>>& psus);
58 
59     /**
60      * Initializes the manager.
61      *
62      * Get current BMC state, ...
63      */
64     void initialize()
65     {
66         // When state = 1, system is powered on
67         int32_t state = 0;
68 
69         try
70         {
71             // Use getProperty utility function to get power state.
72             util::getProperty<int32_t>(POWER_IFACE, "state", POWER_OBJ_PATH,
73                                        powerService, bus, state);
74 
75             if (state)
76             {
77                 powerOn = true;
78             }
79             else
80             {
81                 powerOn = false;
82             }
83         }
84         catch (std::exception& e)
85         {
86             log<level::INFO>("Failed to get power state. Assuming it is off.");
87             powerOn = false;
88         }
89 
90         clearFaults();
91         updateInventory();
92     }
93 
94     /**
95      * Starts the timer to start monitoring the list of devices.
96      */
97     int run()
98     {
99         return timer->get_event().loop();
100     }
101 
102     /**
103      * This function will be called in various situations in order to clear
104      * any fault status bits that may have been set, in order to start over
105      * with a clean state. Presence changes and power state changes will want
106      * to clear any faults logged.
107      */
108     void clearFaults()
109     {
110         for (auto& psu : psus)
111         {
112             psu->clearFaults();
113         }
114     }
115 
116   private:
117     /**
118      * The D-Bus object
119      */
120     sdbusplus::bus::bus& bus;
121 
122     /**
123      * The timer that runs to periodically check the power supplies.
124      */
125     std::unique_ptr<
126         sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
127         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 Minimum number of power supplies to operate.
177      */
178     int minPSUs = 1;
179 
180     /**
181      * @brief Maximum number of power supplies possible.
182      */
183     int maxPSUs = 1;
184 
185     /**
186      * @brief The vector for power supplies.
187      */
188     std::vector<std::unique_ptr<PowerSupply>> psus;
189 };
190 
191 } // namespace manager
192 } // namespace power
193 } // namespace phosphor
194