1abf8da36SMatt Spinler #pragma once 2abf8da36SMatt Spinler 3abf8da36SMatt Spinler #include <sdbusplus/bus.hpp> 4abf8da36SMatt Spinler #include <tuple> 5abf8da36SMatt Spinler #include <vector> 6abf8da36SMatt Spinler #include "tach_sensor.hpp" 7abf8da36SMatt Spinler #include "types.hpp" 8abf8da36SMatt Spinler 9abf8da36SMatt Spinler namespace phosphor 10abf8da36SMatt Spinler { 11abf8da36SMatt Spinler namespace fan 12abf8da36SMatt Spinler { 13abf8da36SMatt Spinler namespace monitor 14abf8da36SMatt Spinler { 15abf8da36SMatt Spinler 16abf8da36SMatt Spinler 17abf8da36SMatt Spinler /** 18abf8da36SMatt Spinler * @class Fan 19abf8da36SMatt Spinler * 20abf8da36SMatt Spinler * Represents a fan, which can contain 1 or more sensors which 21abf8da36SMatt Spinler * loosely correspond to rotors. See below. 22abf8da36SMatt Spinler * 23abf8da36SMatt Spinler * There is a sensor when hwmon exposes one, which means there is a 24abf8da36SMatt Spinler * speed value to be read. Sometimes there is a sensor per rotor, 25abf8da36SMatt Spinler * and other times multiple rotors just use 1 sensor total where 26abf8da36SMatt Spinler * the sensor reports the slowest speed of all of the rotors. 27abf8da36SMatt Spinler * 28abf8da36SMatt Spinler * A rotor's speed is set by writing the Target value of a sensor. 29abf8da36SMatt Spinler * Sometimes each sensor in a fan supports having a Target, and other 30abf8da36SMatt Spinler * times not all of them do. A TachSensor object knows if it supports 31abf8da36SMatt Spinler * the Target property. 32abf8da36SMatt Spinler * 33abf8da36SMatt Spinler * The strategy for monitoring fan speeds is as follows: 34abf8da36SMatt Spinler * 35abf8da36SMatt Spinler * Every time a Target (new speed written) or Input (actual speed read) 36abf8da36SMatt Spinler * sensor changes, check if the input value is within some range of the target 37abf8da36SMatt Spinler * value. If it isn't, start a timer at the end of which the sensor will be 38abf8da36SMatt Spinler * set to not functional. If enough sensors in the fan are now nonfunctional, 39abf8da36SMatt Spinler * set the whole fan to nonfunctional in the inventory. 40abf8da36SMatt Spinler * 41abf8da36SMatt Spinler * When sensor inputs come back within a specified range of the target, 42abf8da36SMatt Spinler * stop its timer if running, make the sensor functional again if it wasn't, 43abf8da36SMatt Spinler * and if enough sensors in the fan are now functional set the whole fan 44abf8da36SMatt Spinler * back to functional in the inventory. 45abf8da36SMatt Spinler */ 46abf8da36SMatt Spinler class Fan 47abf8da36SMatt Spinler { 48abf8da36SMatt Spinler 49abf8da36SMatt Spinler public: 50abf8da36SMatt Spinler 51abf8da36SMatt Spinler Fan() = delete; 52abf8da36SMatt Spinler Fan(const Fan&) = delete; 53abf8da36SMatt Spinler Fan(Fan&&) = default; 54abf8da36SMatt Spinler Fan& operator=(const Fan&) = delete; 55abf8da36SMatt Spinler Fan& operator=(Fan&&) = default; 56abf8da36SMatt Spinler ~Fan() = default; 57abf8da36SMatt Spinler 58abf8da36SMatt Spinler /** 59abf8da36SMatt Spinler * @brief Constructor 60abf8da36SMatt Spinler * 61abf8da36SMatt Spinler * @param bus - the dbus object 62abf8da36SMatt Spinler * @param events - pointer to sd_event object 63abf8da36SMatt Spinler * @param def - the fan definition structure 64abf8da36SMatt Spinler */ 65abf8da36SMatt Spinler Fan(sdbusplus::bus::bus& bus, 66abf8da36SMatt Spinler std::shared_ptr<sd_event>& events, 67abf8da36SMatt Spinler const FanDefinition& def); 68abf8da36SMatt Spinler 69ebaae611SMatt Spinler /** 70ebaae611SMatt Spinler * @brief Callback function for when an input sensor changes 71ebaae611SMatt Spinler * 72ebaae611SMatt Spinler * Starts a timer, where if it expires then the sensor 73*a9406a77SMatt Spinler * was out of range for too long and can be considered not functional. 74ebaae611SMatt Spinler */ 75ebaae611SMatt Spinler void tachChanged(TachSensor& sensor); 76ebaae611SMatt Spinler 77ebaae611SMatt Spinler /** 78ebaae611SMatt Spinler * @brief Calls tachChanged(sensor) on each sensor 79ebaae611SMatt Spinler */ 80ebaae611SMatt Spinler void tachChanged(); 81abf8da36SMatt Spinler 82*a9406a77SMatt Spinler /** 83*a9406a77SMatt Spinler * @brief The callback function for the timer 84*a9406a77SMatt Spinler * 85*a9406a77SMatt Spinler * Sets the sensor to not functional. 86*a9406a77SMatt Spinler * If enough sensors are now not functional, 87*a9406a77SMatt Spinler * updates the functional status of the whole 88*a9406a77SMatt Spinler * fan in the inventory. 89*a9406a77SMatt Spinler * 90*a9406a77SMatt Spinler * @param[in] sensor - the sensor whose timer expired 91*a9406a77SMatt Spinler */ 92*a9406a77SMatt Spinler void timerExpired(TachSensor& sensor); 93*a9406a77SMatt Spinler 94abf8da36SMatt Spinler private: 95abf8da36SMatt Spinler 96abf8da36SMatt Spinler /** 97abf8da36SMatt Spinler * @brief Returns the target speed of the sensor 98abf8da36SMatt Spinler * 99abf8da36SMatt Spinler * If the sensor itself doesn't have a target, it finds 100abf8da36SMatt Spinler * the target speed from another sensor. 101abf8da36SMatt Spinler * 102abf8da36SMatt Spinler * @param[in] sensor - the sensor to get the target speed for 103abf8da36SMatt Spinler */ 104abf8da36SMatt Spinler uint64_t getTargetSpeed(const TachSensor& sensor); 105abf8da36SMatt Spinler 106abf8da36SMatt Spinler /** 107abf8da36SMatt Spinler * @brief Returns true if the sensor input is not within 108abf8da36SMatt Spinler * some deviation of the target. 109abf8da36SMatt Spinler * 110abf8da36SMatt Spinler * @param[in] sensor - the sensor to check 111abf8da36SMatt Spinler */ 112abf8da36SMatt Spinler bool outOfRange(const TachSensor& sensor); 113abf8da36SMatt Spinler 114abf8da36SMatt Spinler /** 115abf8da36SMatt Spinler * @brief Returns true if too many sensors are nonfunctional 116abf8da36SMatt Spinler * as defined by _numSensorFailsForNonFunc 117abf8da36SMatt Spinler */ 118abf8da36SMatt Spinler bool tooManySensorsNonfunctional(); 119abf8da36SMatt Spinler 120abf8da36SMatt Spinler 121abf8da36SMatt Spinler /** 122abf8da36SMatt Spinler * @brief the dbus object 123abf8da36SMatt Spinler */ 124abf8da36SMatt Spinler sdbusplus::bus::bus& _bus; 125abf8da36SMatt Spinler 126abf8da36SMatt Spinler /** 127abf8da36SMatt Spinler * @brief The inventory name of the fan 128abf8da36SMatt Spinler */ 129abf8da36SMatt Spinler const std::string _name; 130abf8da36SMatt Spinler 131abf8da36SMatt Spinler /** 132abf8da36SMatt Spinler * @brief The percentage that the input speed must be below 133abf8da36SMatt Spinler * the target speed to be considered an error. 134abf8da36SMatt Spinler * Between 0 and 100. 135abf8da36SMatt Spinler */ 136abf8da36SMatt Spinler const size_t _deviation; 137abf8da36SMatt Spinler 138abf8da36SMatt Spinler /** 139abf8da36SMatt Spinler * The number of sensors that must be nonfunctional at the 140abf8da36SMatt Spinler * same time in order for the fan to be set to nonfunctional 141abf8da36SMatt Spinler * in the inventory. 142abf8da36SMatt Spinler */ 143abf8da36SMatt Spinler const size_t _numSensorFailsForNonFunc; 144abf8da36SMatt Spinler 145abf8da36SMatt Spinler /** 146abf8da36SMatt Spinler * @brief The current functional state of the fan 147abf8da36SMatt Spinler */ 148abf8da36SMatt Spinler bool _functional = true; 149abf8da36SMatt Spinler 150abf8da36SMatt Spinler /** 151abf8da36SMatt Spinler * The sensor objects for the fan 152abf8da36SMatt Spinler */ 153abf8da36SMatt Spinler std::vector<std::unique_ptr<TachSensor>> _sensors; 154abf8da36SMatt Spinler }; 155abf8da36SMatt Spinler 156abf8da36SMatt Spinler } 157abf8da36SMatt Spinler } 158abf8da36SMatt Spinler } 159