1 #pragma once 2 #include <chrono> 3 #include <vector> 4 #include <algorithm> 5 #include <sdbusplus/bus.hpp> 6 #include <sdbusplus/server.hpp> 7 #include "fan.hpp" 8 #include "types.hpp" 9 #include "timer.hpp" 10 11 namespace phosphor 12 { 13 namespace fan 14 { 15 namespace control 16 { 17 18 /** 19 * The mode fan control will run in: 20 * - init - only do the initialization steps 21 * - control - run normal control algorithms 22 */ 23 enum class Mode 24 { 25 init, 26 control 27 }; 28 29 /** 30 * @class Represents a fan control zone, which is a group of fans 31 * that behave the same. 32 */ 33 class Zone 34 { 35 public: 36 37 Zone() = delete; 38 Zone(const Zone&) = delete; 39 Zone(Zone&&) = default; 40 Zone& operator=(const Zone&) = delete; 41 Zone& operator=(Zone&&) = delete; 42 ~Zone() = default; 43 44 /** 45 * Constructor 46 * Creates the appropriate fan objects based on 47 * the zone definition data passed in. 48 * 49 * @param[in] mode - mode of fan control 50 * @param[in] bus - the dbus object 51 * @param[in] events - sd_event pointer 52 * @param[in] def - the fan zone definition data 53 */ 54 Zone(Mode mode, 55 sdbusplus::bus::bus& bus, 56 phosphor::fan::event::EventPtr& events, 57 const ZoneDefinition& def); 58 59 /** 60 * Sets all fans in the zone to the speed 61 * passed in 62 * 63 * @param[in] speed - the fan speed 64 */ 65 void setSpeed(uint64_t speed); 66 67 /** 68 * Sets the zone to full speed 69 */ 70 inline void setFullSpeed() 71 { 72 if (_fullSpeed != 0) 73 { 74 setSpeed(_fullSpeed); 75 } 76 } 77 78 /** 79 * @brief Sets the automatic fan control allowed active state 80 * 81 * @param[in] group - A group that affects the active state 82 * @param[in] isActiveAllow - Active state according to group 83 */ 84 void setActiveAllow(const Group* group, bool isActiveAllow); 85 86 /** 87 * @brief Sets a given object's property value 88 * 89 * @param[in] object - Name of the object containing the property 90 * @param[in] interface - Interface name containing the property 91 * @param[in] property - Property name 92 * @param[in] value - Property value 93 */ 94 template <typename T> 95 void setPropertyValue(const char* object, 96 const char* interface, 97 const char* property, 98 T value) 99 { 100 _properties[object][interface][property] = value; 101 }; 102 103 /** 104 * @brief Get the value of an object's property 105 * 106 * @param[in] object - Name of the object containing the property 107 * @param[in] interface - Interface name containing the property 108 * @param[in] property - Property name 109 * 110 * @return - The property value 111 */ 112 template <typename T> 113 inline auto getPropertyValue(const std::string& object, 114 const std::string& interface, 115 const std::string& property) 116 { 117 return sdbusplus::message::variant_ns::get<T>( 118 _properties[object][interface][property]); 119 }; 120 121 /** 122 * @brief Get the default floor speed 123 * 124 * @return - The defined default floor speed 125 */ 126 inline auto getDefFloor() 127 { 128 return _defFloorSpeed; 129 }; 130 131 /** 132 * @brief Get the ceiling speed 133 * 134 * @return - The current ceiling speed 135 */ 136 inline auto& getCeiling() const 137 { 138 return _ceilingSpeed; 139 }; 140 141 /** 142 * @brief Set the ceiling speed to the given speed 143 * 144 * @param[in] speed - Speed to set the ceiling to 145 */ 146 inline void setCeiling(uint64_t speed) 147 { 148 _ceilingSpeed = speed; 149 }; 150 151 /** 152 * @brief Swaps the ceiling key value with what's given and 153 * returns the value that was swapped. 154 * 155 * @param[in] keyValue - New ceiling key value 156 * 157 * @return - Ceiling key value prior to swapping 158 */ 159 inline auto swapCeilingKeyValue(int64_t keyValue) 160 { 161 std::swap(_ceilingKeyValue, keyValue); 162 return keyValue; 163 }; 164 165 /** 166 * @brief Get the increase speed delta 167 * 168 * @return - The current increase speed delta 169 */ 170 inline auto& getIncSpeedDelta() const 171 { 172 return _incSpeedDelta; 173 }; 174 175 /** 176 * @brief Get the decrease speed delta 177 * 178 * @return - The current decrease speed delta 179 */ 180 inline auto& getDecSpeedDelta() const 181 { 182 return _decSpeedDelta; 183 }; 184 185 /** 186 * @brief Set the floor speed to the given speed and increase target 187 * speed to the floor when target is below floor. 188 * 189 * @param[in] speed - Speed to set the floor to 190 */ 191 void setFloor(uint64_t speed); 192 193 /** 194 * @brief Calculate the requested target speed from the given delta 195 * and increase the fan speeds, not going above the ceiling. 196 * 197 * @param[in] targetDelta - The delta to increase the target speed by 198 */ 199 void requestSpeedIncrease(uint64_t targetDelta); 200 201 /** 202 * @brief Calculate the requested target speed from the given delta 203 * and increase the fan speeds, not going above the ceiling. 204 * 205 * @param[in] targetDelta - The delta to increase the target speed by 206 */ 207 void requestSpeedDecrease(uint64_t targetDelta); 208 209 /** 210 * @brief Callback function for the increase timer that delays 211 * processing of requested speed increases while fans are increasing 212 */ 213 void incTimerExpired(); 214 215 /** 216 * @brief Callback function for the decrease timer that processes any 217 * requested speed decreases if allowed 218 */ 219 void decTimerExpired(); 220 221 private: 222 223 /** 224 * The dbus object 225 */ 226 sdbusplus::bus::bus& _bus; 227 228 /** 229 * Full speed for the zone 230 */ 231 const uint64_t _fullSpeed; 232 233 /** 234 * The zone number 235 */ 236 const size_t _zoneNum; 237 238 /** 239 * The default floor speed for the zone 240 */ 241 const uint64_t _defFloorSpeed; 242 243 /** 244 * The default ceiling speed for the zone 245 */ 246 const uint64_t _defCeilingSpeed; 247 248 /** 249 * The floor speed to not go below 250 */ 251 uint64_t _floorSpeed = _defFloorSpeed; 252 253 /** 254 * The ceiling speed to not go above 255 */ 256 uint64_t _ceilingSpeed = _defCeilingSpeed; 257 258 /** 259 * The previous sensor value for calculating the ceiling 260 */ 261 int64_t _ceilingKeyValue = 0; 262 263 /** 264 * Automatic fan control active state 265 */ 266 bool _isActive = true; 267 268 /** 269 * Target speed for this zone 270 */ 271 uint64_t _targetSpeed = _fullSpeed; 272 273 /** 274 * Speed increase delta 275 */ 276 uint64_t _incSpeedDelta = 0; 277 278 /** 279 * Speed decrease delta 280 */ 281 uint64_t _decSpeedDelta = 0; 282 283 /** 284 * Speed increase delay in seconds 285 */ 286 std::chrono::seconds _incDelay; 287 288 /** 289 * Speed decrease interval in seconds 290 */ 291 std::chrono::seconds _decInterval; 292 293 /** 294 * The increase timer object 295 */ 296 phosphor::fan::util::Timer _incTimer; 297 298 /** 299 * The decrease timer object 300 */ 301 phosphor::fan::util::Timer _decTimer; 302 303 /** 304 * The vector of fans in this zone 305 */ 306 std::vector<std::unique_ptr<Fan>> _fans; 307 308 /** 309 * @brief Map of object property values 310 */ 311 std::map<std::string, 312 std::map<std::string, 313 std::map<std::string, 314 PropertyVariantType>>> _properties; 315 316 /** 317 * @brief Map of active fan control allowed by groups 318 */ 319 std::map<const Group*, bool> _active; 320 321 /** 322 * @brief List of signal event arguments 323 */ 324 std::vector<std::unique_ptr<EventData>> _signalEvents; 325 326 /** 327 * @brief list of Dbus matches for callbacks 328 */ 329 std::vector<sdbusplus::server::match::match> _matches; 330 331 /** 332 * @brief Initialize all the set speed event properties and actions 333 * 334 * @param[in] def - zone definition containing set speed events 335 */ 336 void initEvents(const ZoneDefinition& def); 337 338 /** 339 * @brief Refresh the given property's cached value 340 * 341 * @param[in] bus - the bus to use 342 * @param[in] path - the dbus path name 343 * @param[in] iface - the dbus interface name 344 * @param[in] prop - the property name 345 */ 346 void refreshProperty(sdbusplus::bus::bus& bus, 347 const std::string& path, 348 const std::string& iface, 349 const std::string& prop); 350 351 /** 352 * @brief Get a property value from the path/interface given 353 * 354 * @param[in] bus - the bus to use 355 * @param[in] path - the dbus path name 356 * @param[in] iface - the dbus interface name 357 * @param[in] prop - the property name 358 * @param[out] value - the value of the property 359 */ 360 static void getProperty(sdbusplus::bus::bus& bus, 361 const std::string& path, 362 const std::string& iface, 363 const std::string& prop, 364 PropertyVariantType& value); 365 366 /** 367 * @brief Dbus signal change callback handler 368 * 369 * @param[in] msg - Expanded sdbusplus message data 370 * @param[in] eventData - The single event's data 371 */ 372 void handleEvent(sdbusplus::message::message& msg, 373 const EventData* eventData); 374 }; 375 376 } 377 } 378 } 379