1 #pragma once 2 3 #include "types.hpp" 4 5 #include <algorithm> 6 #include <vector> 7 8 namespace phosphor::fan::monitor 9 { 10 11 /** 12 * @class PowerOffCause 13 * 14 * This abstract class provides a satisfied() pure virtual method 15 * that is called to know if the system should be powered off due 16 * to fan health. Each type of class that is derived from this 17 * one provides different behavior, for example one may count 18 * missing fans, and another may count nonfunctional fans. 19 */ 20 class PowerOffCause 21 { 22 public: 23 PowerOffCause() = delete; 24 virtual ~PowerOffCause() = default; 25 PowerOffCause(const PowerOffCause&) = delete; 26 PowerOffCause& operator=(const PowerOffCause&) = delete; 27 PowerOffCause(PowerOffCause&&) = delete; 28 PowerOffCause& operator=(PowerOffCause&&) = delete; 29 30 /** 31 * @brief Constructor 32 * 33 * @param[in] count - The number of items that is compared 34 * against in the derived class. 35 * @param[in] name - The name of the cause. Used for tracing. 36 */ 37 PowerOffCause(size_t count, const std::string& name) : 38 _count(count), _name(std::to_string(count) + " " + name) 39 {} 40 41 /** 42 * @brief Pure virtual that says if the system should be powered 43 * off based on the fan health. 44 * 45 * @param[in] fanHealth - The FanHealth map 46 * 47 * @return bool - If system should be powered off 48 */ 49 virtual bool satisfied(const FanHealth& fanHealth) = 0; 50 51 /** 52 * @brief Returns the name of the cause. 53 * 54 * For example: "3 Missing Fans" 55 * 56 * @return std::string - The name 57 */ 58 const std::string& name() const 59 { 60 return _name; 61 } 62 63 protected: 64 /** 65 * @brief The number of fan health items that the derived 66 * class uses to compare to the fan health status. 67 * For example, a 3 for 3 missing fans. 68 */ 69 const size_t _count; 70 71 /** 72 * @brief The cause name 73 */ 74 const std::string _name; 75 }; 76 77 /** 78 * @class MissingFanFRUCause 79 * 80 * This class provides a satisfied() method that checks for 81 * missing fans in the fan health map. 82 * 83 */ 84 class MissingFanFRUCause : public PowerOffCause 85 { 86 public: 87 MissingFanFRUCause() = delete; 88 ~MissingFanFRUCause() = default; 89 MissingFanFRUCause(const MissingFanFRUCause&) = delete; 90 MissingFanFRUCause& operator=(const MissingFanFRUCause&) = delete; 91 MissingFanFRUCause(MissingFanFRUCause&&) = delete; 92 MissingFanFRUCause& operator=(MissingFanFRUCause&&) = delete; 93 94 /** 95 * @brief Constructor 96 * 97 * @param[in] count - The minimum number of fans that must be 98 * missing to need a power off. 99 */ 100 explicit MissingFanFRUCause(size_t count) : 101 PowerOffCause(count, "Missing Fan FRUs") 102 {} 103 104 /** 105 * @brief Returns true if 'count' or more fans are missing 106 * to require a power off. 107 * 108 * @param[in] fanHealth - The FanHealth map 109 */ 110 bool satisfied(const FanHealth& fanHealth) override 111 { 112 size_t count = std::count_if(fanHealth.begin(), fanHealth.end(), 113 [](const auto& fan) { 114 return !std::get<presentHealthPos>(fan.second); 115 }); 116 117 return count >= _count; 118 } 119 }; 120 121 /** 122 * @class NonfuncFanRotorCause 123 * 124 * This class provides a satisfied() method that checks for 125 * nonfunctional fan rotors in the fan health map. 126 */ 127 class NonfuncFanRotorCause : public PowerOffCause 128 { 129 public: 130 NonfuncFanRotorCause() = delete; 131 ~NonfuncFanRotorCause() = default; 132 NonfuncFanRotorCause(const NonfuncFanRotorCause&) = delete; 133 NonfuncFanRotorCause& operator=(const NonfuncFanRotorCause&) = delete; 134 NonfuncFanRotorCause(NonfuncFanRotorCause&&) = delete; 135 NonfuncFanRotorCause& operator=(NonfuncFanRotorCause&&) = delete; 136 137 /** 138 * @brief Constructor 139 * 140 * @param[in] count - The minimum number of rotors that must be 141 * nonfunctional to need a power off. 142 */ 143 explicit NonfuncFanRotorCause(size_t count) : 144 PowerOffCause(count, "Nonfunctional Fan Rotors") 145 {} 146 147 /** 148 * @brief Returns true if 'count' or more rotors are nonfunctional 149 * to require a power off. 150 * 151 * @param[in] fanHealth - The FanHealth map 152 */ 153 bool satisfied(const FanHealth& fanHealth) override 154 { 155 size_t count = std::accumulate(fanHealth.begin(), fanHealth.end(), 0, 156 [](int sum, const auto& fan) { 157 const auto& tachs = std::get<sensorFuncHealthPos>(fan.second); 158 auto nonFuncTachs = std::count_if(tachs.begin(), tachs.end(), 159 [](bool tach) { return !tach; }); 160 return sum + nonFuncTachs; 161 }); 162 163 return count >= _count; 164 } 165 }; 166 167 /** 168 * @class FanFRUsWithNonfuncRotorsCause 169 * 170 * This class provides a satisfied() method that checks for 171 * fans with nonfunctional fan rotors in the fan health map. 172 */ 173 class FanFRUsWithNonfuncRotorsCause : public PowerOffCause 174 { 175 public: 176 FanFRUsWithNonfuncRotorsCause() = delete; 177 ~FanFRUsWithNonfuncRotorsCause() = default; 178 FanFRUsWithNonfuncRotorsCause(const FanFRUsWithNonfuncRotorsCause&) = 179 delete; 180 FanFRUsWithNonfuncRotorsCause& 181 operator=(const FanFRUsWithNonfuncRotorsCause&) = delete; 182 FanFRUsWithNonfuncRotorsCause(FanFRUsWithNonfuncRotorsCause&&) = delete; 183 FanFRUsWithNonfuncRotorsCause& 184 operator=(FanFRUsWithNonfuncRotorsCause&&) = delete; 185 186 /** 187 * @brief Constructor 188 * 189 * @param[in] count - The minimum number of fan FRUs with 190 * nonfunctional rotors to need a power off. 191 */ 192 explicit FanFRUsWithNonfuncRotorsCause(size_t count) : 193 PowerOffCause(count, "Fans with Nonfunctional Rotors") 194 {} 195 196 /** 197 * @brief Returns true if 'count' or more fan FRUs have 198 * nonfunctional rotors. 199 * 200 * @param[in] fanHealth - The FanHealth map 201 */ 202 bool satisfied(const FanHealth& fanHealth) override 203 { 204 size_t count = std::count_if(fanHealth.begin(), fanHealth.end(), 205 [](const auto& fan) { 206 const auto& tachs = std::get<sensorFuncHealthPos>(fan.second); 207 208 return std::any_of(tachs.begin(), tachs.end(), 209 [](bool func) { return !func; }); 210 }); 211 212 return count >= _count; 213 } 214 }; 215 216 } // namespace phosphor::fan::monitor 217