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