blob: b366c443e534f4af239f1e63a9661b63c5303623 [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
Matt Spinlerabf8da32017-04-27 14:08:45 -0500127 private:
128
129 /**
130 * @brief Returns the target speed of the sensor
131 *
132 * If the sensor itself doesn't have a target, it finds
133 * the target speed from another sensor.
134 *
135 * @param[in] sensor - the sensor to get the target speed for
136 */
137 uint64_t getTargetSpeed(const TachSensor& sensor);
138
139 /**
140 * @brief Returns true if the sensor input is not within
141 * some deviation of the target.
142 *
143 * @param[in] sensor - the sensor to check
144 */
145 bool outOfRange(const TachSensor& sensor);
146
147 /**
148 * @brief Returns true if too many sensors are nonfunctional
149 * as defined by _numSensorFailsForNonFunc
150 */
151 bool tooManySensorsNonfunctional();
152
Matt Spinlerb1e18512017-04-27 14:42:33 -0500153 /**
154 * @brief Updates the Functional property in the inventory
155 * for the fan based on the value passed in.
156 *
157 * @param[in] functional - If the Functional property should
158 * be set to true or false.
159 */
160 void updateInventory(bool functional);
161
162 /**
163 * @brief Returns the object map to use when updating the inventory
164 *
165 * @param[in] functional - If the Functional property should
166 * be set to true or false.
167 */
168 ObjectMap getObjectMap(bool functional);
Matt Spinlerabf8da32017-04-27 14:08:45 -0500169
170 /**
171 * @brief the dbus object
172 */
173 sdbusplus::bus::bus& _bus;
174
175 /**
176 * @brief The inventory name of the fan
177 */
178 const std::string _name;
179
180 /**
181 * @brief The percentage that the input speed must be below
182 * the target speed to be considered an error.
183 * Between 0 and 100.
184 */
185 const size_t _deviation;
186
187 /**
188 * The number of sensors that must be nonfunctional at the
189 * same time in order for the fan to be set to nonfunctional
190 * in the inventory.
191 */
192 const size_t _numSensorFailsForNonFunc;
193
194 /**
195 * @brief The current functional state of the fan
196 */
197 bool _functional = true;
198
199 /**
200 * The sensor objects for the fan
201 */
202 std::vector<std::unique_ptr<TachSensor>> _sensors;
Matt Spinlerc39e8592017-09-28 13:13:08 -0500203
204 /**
205 * The tach trust manager object
206 */
207 std::unique_ptr<trust::Manager>& _trustManager;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500208};
209
210}
211}
212}