blob: bd8179f9e6060e012557b395b8b9e09353a9cd01 [file] [log] [blame]
Matt Spinlerabf8da32017-04-27 14:08:45 -05001#pragma once
2
3#include <sdbusplus/bus.hpp>
4#include <tuple>
5#include <vector>
Matt Spinlere824f982017-05-11 10:07:55 -05006#include "event.hpp"
Matt Spinlerabf8da32017-04-27 14:08:45 -05007#include "tach_sensor.hpp"
Matt Spinlerc39e8592017-09-28 13:13:08 -05008#include "trust_manager.hpp"
Matt Spinlerabf8da32017-04-27 14:08:45 -05009#include "types.hpp"
10
11namespace phosphor
12{
13namespace fan
14{
15namespace monitor
16{
17
Brad Bishopedaeb312017-07-30 19:38:20 -040018/**
Matthew Barth6ad28432017-08-22 11:18:19 -050019 * The mode fan monitor will run in:
20 * - init - only do the initialization steps
21 * - monitor - run normal monitoring algorithm
22 */
23enum class Mode
24{
25 init,
26 monitor
27};
28
29/**
Brad Bishopedaeb312017-07-30 19:38:20 -040030 * @class InvalidSensorError
31 *
32 * An exception type for sensors that don't exist or
33 * are otherwise inaccessible.
34 */
35class InvalidSensorError : public std::exception {};
Matt Spinlerabf8da32017-04-27 14:08:45 -050036
37/**
38 * @class Fan
39 *
40 * Represents a fan, which can contain 1 or more sensors which
41 * loosely correspond to rotors. See below.
42 *
43 * There is a sensor when hwmon exposes one, which means there is a
44 * speed value to be read. Sometimes there is a sensor per rotor,
45 * and other times multiple rotors just use 1 sensor total where
46 * the sensor reports the slowest speed of all of the rotors.
47 *
48 * A rotor's speed is set by writing the Target value of a sensor.
49 * Sometimes each sensor in a fan supports having a Target, and other
50 * times not all of them do. A TachSensor object knows if it supports
51 * the Target property.
52 *
53 * The strategy for monitoring fan speeds is as follows:
54 *
55 * Every time a Target (new speed written) or Input (actual speed read)
56 * sensor changes, check if the input value is within some range of the target
57 * value. If it isn't, start a timer at the end of which the sensor will be
58 * set to not functional. If enough sensors in the fan are now nonfunctional,
59 * set the whole fan to nonfunctional in the inventory.
60 *
61 * When sensor inputs come back within a specified range of the target,
62 * stop its timer if running, make the sensor functional again if it wasn't,
63 * and if enough sensors in the fan are now functional set the whole fan
64 * back to functional in the inventory.
65 */
66class Fan
67{
Matt Spinlerb1e18512017-04-27 14:42:33 -050068 using Property = std::string;
69 using Value = sdbusplus::message::variant<bool>;
70 using PropertyMap = std::map<Property, Value>;
71
72 using Interface = std::string;
73 using InterfaceMap = std::map<Interface, PropertyMap>;
74
75 using Object = sdbusplus::message::object_path;
76 using ObjectMap = std::map<Object, InterfaceMap>;
Matt Spinlerabf8da32017-04-27 14:08:45 -050077
78 public:
79
80 Fan() = delete;
81 Fan(const Fan&) = delete;
82 Fan(Fan&&) = default;
83 Fan& operator=(const Fan&) = delete;
84 Fan& operator=(Fan&&) = default;
85 ~Fan() = default;
86
87 /**
88 * @brief Constructor
89 *
Matthew Barth6ad28432017-08-22 11:18:19 -050090 * @param mode - mode of fan monitor
Matt Spinlerabf8da32017-04-27 14:08:45 -050091 * @param bus - the dbus object
92 * @param events - pointer to sd_event object
Matt Spinlerc39e8592017-09-28 13:13:08 -050093 * @param trust - the tach trust manager
Matt Spinlerabf8da32017-04-27 14:08:45 -050094 * @param def - the fan definition structure
95 */
Matthew Barth6ad28432017-08-22 11:18:19 -050096 Fan(Mode mode,
97 sdbusplus::bus::bus& bus,
Matt Spinlere824f982017-05-11 10:07:55 -050098 phosphor::fan::event::EventPtr& events,
Matt Spinlerc39e8592017-09-28 13:13:08 -050099 std::unique_ptr<trust::Manager>& trust,
Matt Spinlerabf8da32017-04-27 14:08:45 -0500100 const FanDefinition& def);
101
Matt Spinlerebaae612017-04-27 14:21:48 -0500102 /**
103 * @brief Callback function for when an input sensor changes
104 *
105 * Starts a timer, where if it expires then the sensor
Matt Spinlera9406a72017-04-27 14:29:24 -0500106 * was out of range for too long and can be considered not functional.
Matt Spinlerebaae612017-04-27 14:21:48 -0500107 */
108 void tachChanged(TachSensor& sensor);
109
110 /**
111 * @brief Calls tachChanged(sensor) on each sensor
112 */
113 void tachChanged();
Matt Spinlerabf8da32017-04-27 14:08:45 -0500114
Matt Spinlera9406a72017-04-27 14:29:24 -0500115 /**
116 * @brief The callback function for the timer
117 *
118 * Sets the sensor to not functional.
119 * If enough sensors are now not functional,
120 * updates the functional status of the whole
121 * fan in the inventory.
122 *
123 * @param[in] sensor - the sensor whose timer expired
124 */
125 void timerExpired(TachSensor& sensor);
126
Matthew Barth4d982852017-11-17 09:37:13 -0600127 /**
128 * @brief Get the name of the fan
129 *
130 * @return - The fan name
131 */
132 inline const std::string& getName() const
133 {
134 return _name;
135 }
136
Matthew Barthf552ea52018-01-15 16:22:04 -0600137 /**
138 * @brief Finds the target speed of this fan
139 *
140 * Finds the target speed from the list of sensors that make up this
141 * fan. At least one sensor should contain a target speed value.
142 *
143 * @return - The target speed found from the list of sensors on the fan
144 */
145 uint64_t findTargetSpeed();
146
Matt Spinlerabf8da32017-04-27 14:08:45 -0500147 private:
148
149 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500150 * @brief Returns true if the sensor input is not within
151 * some deviation of the target.
152 *
153 * @param[in] sensor - the sensor to check
154 */
155 bool outOfRange(const TachSensor& sensor);
156
157 /**
158 * @brief Returns true if too many sensors are nonfunctional
159 * as defined by _numSensorFailsForNonFunc
160 */
161 bool tooManySensorsNonfunctional();
162
Matt Spinlerb1e18512017-04-27 14:42:33 -0500163 /**
164 * @brief Updates the Functional property in the inventory
165 * for the fan based on the value passed in.
166 *
167 * @param[in] functional - If the Functional property should
168 * be set to true or false.
169 */
170 void updateInventory(bool functional);
171
172 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500173 * @brief the dbus object
174 */
175 sdbusplus::bus::bus& _bus;
176
177 /**
178 * @brief The inventory name of the fan
179 */
180 const std::string _name;
181
182 /**
183 * @brief The percentage that the input speed must be below
184 * the target speed to be considered an error.
185 * Between 0 and 100.
186 */
187 const size_t _deviation;
188
189 /**
190 * The number of sensors that must be nonfunctional at the
191 * same time in order for the fan to be set to nonfunctional
192 * in the inventory.
193 */
194 const size_t _numSensorFailsForNonFunc;
195
196 /**
197 * @brief The current functional state of the fan
198 */
199 bool _functional = true;
200
201 /**
202 * The sensor objects for the fan
203 */
204 std::vector<std::unique_ptr<TachSensor>> _sensors;
Matt Spinlerc39e8592017-09-28 13:13:08 -0500205
206 /**
207 * The tach trust manager object
208 */
209 std::unique_ptr<trust::Manager>& _trustManager;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500210};
211
212}
213}
214}