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