xref: /openbmc/phosphor-fan-presence/monitor/fan.hpp (revision a9406a774a35c02fabc94ab842788dd9891f59e8)
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