xref: /openbmc/phosphor-fan-presence/monitor/fan.hpp (revision 177fe986c14f5feecb97ef1aec435d2780b6e473)
1abf8da36SMatt Spinler #pragma once
2abf8da36SMatt Spinler 
3abf8da36SMatt Spinler #include "tach_sensor.hpp"
4c39e859bSMatt Spinler #include "trust_manager.hpp"
5abf8da36SMatt Spinler #include "types.hpp"
6abf8da36SMatt Spinler 
7*177fe986SMatthew Barth #include <sdbusplus/bus.hpp>
8*177fe986SMatthew Barth #include <sdeventplus/event.hpp>
9*177fe986SMatthew Barth 
10*177fe986SMatthew Barth #include <tuple>
11*177fe986SMatthew Barth #include <vector>
12*177fe986SMatthew Barth 
13abf8da36SMatt Spinler namespace phosphor
14abf8da36SMatt Spinler {
15abf8da36SMatt Spinler namespace fan
16abf8da36SMatt Spinler {
17abf8da36SMatt Spinler namespace monitor
18abf8da36SMatt Spinler {
19abf8da36SMatt Spinler 
20edaeb31cSBrad Bishop /**
21edaeb31cSBrad Bishop  * @class InvalidSensorError
22edaeb31cSBrad Bishop  *
23edaeb31cSBrad Bishop  * An exception type for sensors that don't exist or
24edaeb31cSBrad Bishop  * are otherwise inaccessible.
25edaeb31cSBrad Bishop  */
26*177fe986SMatthew Barth class InvalidSensorError : public std::exception
27*177fe986SMatthew Barth {};
28abf8da36SMatt Spinler 
29abf8da36SMatt Spinler /**
30abf8da36SMatt Spinler  * @class Fan
31abf8da36SMatt Spinler  *
32abf8da36SMatt Spinler  * Represents a fan, which can contain 1 or more sensors which
33abf8da36SMatt Spinler  * loosely correspond to rotors.  See below.
34abf8da36SMatt Spinler  *
35abf8da36SMatt Spinler  * There is a sensor when hwmon exposes one, which means there is a
36abf8da36SMatt Spinler  * speed value to be read.  Sometimes there is a sensor per rotor,
37abf8da36SMatt Spinler  * and other times multiple rotors just use 1 sensor total where
38abf8da36SMatt Spinler  * the sensor reports the slowest speed of all of the rotors.
39abf8da36SMatt Spinler  *
40abf8da36SMatt Spinler  * A rotor's speed is set by writing the Target value of a sensor.
41abf8da36SMatt Spinler  * Sometimes each sensor in a fan supports having a Target, and other
42abf8da36SMatt Spinler  * times not all of them do.  A TachSensor object knows if it supports
43abf8da36SMatt Spinler  * the Target property.
44abf8da36SMatt Spinler  *
45abf8da36SMatt Spinler  * The strategy for monitoring fan speeds is as follows:
46abf8da36SMatt Spinler  *
47abf8da36SMatt Spinler  * Every time a Target (new speed written) or Input (actual speed read)
48abf8da36SMatt Spinler  * sensor changes, check if the input value is within some range of the target
49abf8da36SMatt Spinler  * value.  If it isn't, start a timer at the end of which the sensor will be
50abf8da36SMatt Spinler  * set to not functional.  If enough sensors in the fan are now nonfunctional,
51abf8da36SMatt Spinler  * set the whole fan to nonfunctional in the inventory.
52abf8da36SMatt Spinler  *
53abf8da36SMatt Spinler  * When sensor inputs come back within a specified range of the target,
54abf8da36SMatt Spinler  * stop its timer if running, make the sensor functional again if it wasn't,
55abf8da36SMatt Spinler  * and if enough sensors in the fan are now functional set the whole fan
56abf8da36SMatt Spinler  * back to functional in the inventory.
57abf8da36SMatt Spinler  */
58abf8da36SMatt Spinler class Fan
59abf8da36SMatt Spinler {
60b1e18514SMatt Spinler     using Property = std::string;
61c21d0b36SPatrick Williams     using Value = std::variant<bool>;
62b1e18514SMatt Spinler     using PropertyMap = std::map<Property, Value>;
63b1e18514SMatt Spinler 
64b1e18514SMatt Spinler     using Interface = std::string;
65b1e18514SMatt Spinler     using InterfaceMap = std::map<Interface, PropertyMap>;
66b1e18514SMatt Spinler 
67b1e18514SMatt Spinler     using Object = sdbusplus::message::object_path;
68b1e18514SMatt Spinler     using ObjectMap = std::map<Object, InterfaceMap>;
69abf8da36SMatt Spinler 
70abf8da36SMatt Spinler   public:
71abf8da36SMatt Spinler     Fan() = delete;
72abf8da36SMatt Spinler     Fan(const Fan&) = delete;
73abf8da36SMatt Spinler     Fan(Fan&&) = default;
74abf8da36SMatt Spinler     Fan& operator=(const Fan&) = delete;
75abf8da36SMatt Spinler     Fan& operator=(Fan&&) = default;
76abf8da36SMatt Spinler     ~Fan() = default;
77abf8da36SMatt Spinler 
78abf8da36SMatt Spinler     /**
79abf8da36SMatt Spinler      * @brief Constructor
80abf8da36SMatt Spinler      *
816ad28430SMatthew Barth      * @param mode - mode of fan monitor
82abf8da36SMatt Spinler      * @param bus - the dbus object
831cfc2f11SWilliam A. Kennington III      * @param event - event loop reference
84c39e859bSMatt Spinler      * @param trust - the tach trust manager
85abf8da36SMatt Spinler      * @param def - the fan definition structure
86abf8da36SMatt Spinler      */
87*177fe986SMatthew Barth     Fan(Mode mode, sdbusplus::bus::bus& bus, const sdeventplus::Event& event,
88*177fe986SMatthew Barth         std::unique_ptr<trust::Manager>& trust, const FanDefinition& def);
89abf8da36SMatt Spinler 
90ebaae611SMatt Spinler     /**
91ebaae611SMatt Spinler      * @brief Callback function for when an input sensor changes
92ebaae611SMatt Spinler      *
93ebaae611SMatt Spinler      * Starts a timer, where if it expires then the sensor
94a9406a77SMatt Spinler      * was out of range for too long and can be considered not functional.
95ebaae611SMatt Spinler      */
96ebaae611SMatt Spinler     void tachChanged(TachSensor& sensor);
97ebaae611SMatt Spinler 
98ebaae611SMatt Spinler     /**
99ebaae611SMatt Spinler      * @brief Calls tachChanged(sensor) on each sensor
100ebaae611SMatt Spinler      */
101ebaae611SMatt Spinler     void tachChanged();
102abf8da36SMatt Spinler 
103a9406a77SMatt Spinler     /**
104a9406a77SMatt Spinler      * @brief The callback function for the timer
105a9406a77SMatt Spinler      *
106a9406a77SMatt Spinler      * Sets the sensor to not functional.
107a9406a77SMatt Spinler      * If enough sensors are now not functional,
108a9406a77SMatt Spinler      * updates the functional status of the whole
109a9406a77SMatt Spinler      * fan in the inventory.
110a9406a77SMatt Spinler      *
111a9406a77SMatt Spinler      * @param[in] sensor - the sensor whose timer expired
112a9406a77SMatt Spinler      */
113a9406a77SMatt Spinler     void timerExpired(TachSensor& sensor);
114a9406a77SMatt Spinler 
1154d982856SMatthew Barth     /**
1164d982856SMatthew Barth      * @brief Get the name of the fan
1174d982856SMatthew Barth      *
1184d982856SMatthew Barth      * @return - The fan name
1194d982856SMatthew Barth      */
1204d982856SMatthew Barth     inline const std::string& getName() const
1214d982856SMatthew Barth     {
1224d982856SMatthew Barth         return _name;
1234d982856SMatthew Barth     }
1244d982856SMatthew Barth 
125f552ea5cSMatthew Barth     /**
126f552ea5cSMatthew Barth      * @brief Finds the target speed of this fan
127f552ea5cSMatthew Barth      *
128f552ea5cSMatthew Barth      * Finds the target speed from the list of sensors that make up this
129f552ea5cSMatthew Barth      * fan. At least one sensor should contain a target speed value.
130f552ea5cSMatthew Barth      *
131f552ea5cSMatthew Barth      * @return - The target speed found from the list of sensors on the fan
132f552ea5cSMatthew Barth      */
133f552ea5cSMatthew Barth     uint64_t findTargetSpeed();
134f552ea5cSMatthew Barth 
135abf8da36SMatt Spinler   private:
136abf8da36SMatt Spinler     /**
137abf8da36SMatt Spinler      * @brief Returns true if the sensor input is not within
138abf8da36SMatt Spinler      * some deviation of the target.
139abf8da36SMatt Spinler      *
140abf8da36SMatt Spinler      * @param[in] sensor - the sensor to check
141abf8da36SMatt Spinler      */
142abf8da36SMatt Spinler     bool outOfRange(const TachSensor& sensor);
143abf8da36SMatt Spinler 
144abf8da36SMatt Spinler     /**
145abf8da36SMatt Spinler      * @brief Returns true if too many sensors are nonfunctional
146abf8da36SMatt Spinler      *        as defined by _numSensorFailsForNonFunc
147abf8da36SMatt Spinler      */
148abf8da36SMatt Spinler     bool tooManySensorsNonfunctional();
149abf8da36SMatt Spinler 
150b1e18514SMatt Spinler     /**
151b1e18514SMatt Spinler      * @brief Updates the Functional property in the inventory
152b1e18514SMatt Spinler      *        for the fan based on the value passed in.
153b1e18514SMatt Spinler      *
154b1e18514SMatt Spinler      * @param[in] functional - If the Functional property should
155b1e18514SMatt Spinler      *                         be set to true or false.
156b1e18514SMatt Spinler      */
157b1e18514SMatt Spinler     void updateInventory(bool functional);
158b1e18514SMatt Spinler 
159b1e18514SMatt Spinler     /**
160abf8da36SMatt Spinler      * @brief the dbus object
161abf8da36SMatt Spinler      */
162abf8da36SMatt Spinler     sdbusplus::bus::bus& _bus;
163abf8da36SMatt Spinler 
164abf8da36SMatt Spinler     /**
165abf8da36SMatt Spinler      * @brief The inventory name of the fan
166abf8da36SMatt Spinler      */
167abf8da36SMatt Spinler     const std::string _name;
168abf8da36SMatt Spinler 
169abf8da36SMatt Spinler     /**
170abf8da36SMatt Spinler      * @brief The percentage that the input speed must be below
171abf8da36SMatt Spinler      *        the target speed to be considered an error.
172abf8da36SMatt Spinler      *        Between 0 and 100.
173abf8da36SMatt Spinler      */
174abf8da36SMatt Spinler     const size_t _deviation;
175abf8da36SMatt Spinler 
176abf8da36SMatt Spinler     /**
177abf8da36SMatt Spinler      * The number of sensors that must be nonfunctional at the
178abf8da36SMatt Spinler      * same time in order for the fan to be set to nonfunctional
179abf8da36SMatt Spinler      * in the inventory.
180abf8da36SMatt Spinler      */
181abf8da36SMatt Spinler     const size_t _numSensorFailsForNonFunc;
182abf8da36SMatt Spinler 
183abf8da36SMatt Spinler     /**
184abf8da36SMatt Spinler      * @brief The current functional state of the fan
185abf8da36SMatt Spinler      */
186abf8da36SMatt Spinler     bool _functional = true;
187abf8da36SMatt Spinler 
188abf8da36SMatt Spinler     /**
189abf8da36SMatt Spinler      * The sensor objects for the fan
190abf8da36SMatt Spinler      */
19132affb98SMatthew Barth     std::vector<std::shared_ptr<TachSensor>> _sensors;
192c39e859bSMatt Spinler 
193c39e859bSMatt Spinler     /**
194c39e859bSMatt Spinler      * The tach trust manager object
195c39e859bSMatt Spinler      */
196c39e859bSMatt Spinler     std::unique_ptr<trust::Manager>& _trustManager;
197abf8da36SMatt Spinler };
198abf8da36SMatt Spinler 
199*177fe986SMatthew Barth } // namespace monitor
200*177fe986SMatthew Barth } // namespace fan
201*177fe986SMatthew Barth } // namespace phosphor
202