blob: 663e27e730ad10b400300c2a08fc999120be945b [file] [log] [blame]
Matt Spinlerabf8da32017-04-27 14:08:45 -05001#pragma once
2
3#include <sdbusplus/bus.hpp>
William A. Kennington III1cfc2f12018-10-19 17:29:46 -07004#include <sdeventplus/event.hpp>
Matt Spinlerabf8da32017-04-27 14:08:45 -05005#include <tuple>
6#include <vector>
7#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/**
19 * @class InvalidSensorError
20 *
21 * An exception type for sensors that don't exist or
22 * are otherwise inaccessible.
23 */
24class InvalidSensorError : public std::exception {};
Matt Spinlerabf8da32017-04-27 14:08:45 -050025
26/**
27 * @class Fan
28 *
29 * Represents a fan, which can contain 1 or more sensors which
30 * loosely correspond to rotors. See below.
31 *
32 * There is a sensor when hwmon exposes one, which means there is a
33 * speed value to be read. Sometimes there is a sensor per rotor,
34 * and other times multiple rotors just use 1 sensor total where
35 * the sensor reports the slowest speed of all of the rotors.
36 *
37 * A rotor's speed is set by writing the Target value of a sensor.
38 * Sometimes each sensor in a fan supports having a Target, and other
39 * times not all of them do. A TachSensor object knows if it supports
40 * the Target property.
41 *
42 * The strategy for monitoring fan speeds is as follows:
43 *
44 * Every time a Target (new speed written) or Input (actual speed read)
45 * sensor changes, check if the input value is within some range of the target
46 * value. If it isn't, start a timer at the end of which the sensor will be
47 * set to not functional. If enough sensors in the fan are now nonfunctional,
48 * set the whole fan to nonfunctional in the inventory.
49 *
50 * When sensor inputs come back within a specified range of the target,
51 * stop its timer if running, make the sensor functional again if it wasn't,
52 * and if enough sensors in the fan are now functional set the whole fan
53 * back to functional in the inventory.
54 */
55class Fan
56{
Matt Spinlerb1e18512017-04-27 14:42:33 -050057 using Property = std::string;
58 using Value = sdbusplus::message::variant<bool>;
59 using PropertyMap = std::map<Property, Value>;
60
61 using Interface = std::string;
62 using InterfaceMap = std::map<Interface, PropertyMap>;
63
64 using Object = sdbusplus::message::object_path;
65 using ObjectMap = std::map<Object, InterfaceMap>;
Matt Spinlerabf8da32017-04-27 14:08:45 -050066
67 public:
68
69 Fan() = delete;
70 Fan(const Fan&) = delete;
71 Fan(Fan&&) = default;
72 Fan& operator=(const Fan&) = delete;
73 Fan& operator=(Fan&&) = default;
74 ~Fan() = default;
75
76 /**
77 * @brief Constructor
78 *
Matthew Barth6ad28432017-08-22 11:18:19 -050079 * @param mode - mode of fan monitor
Matt Spinlerabf8da32017-04-27 14:08:45 -050080 * @param bus - the dbus object
William A. Kennington III1cfc2f12018-10-19 17:29:46 -070081 * @param event - event loop reference
Matt Spinlerc39e8592017-09-28 13:13:08 -050082 * @param trust - the tach trust manager
Matt Spinlerabf8da32017-04-27 14:08:45 -050083 * @param def - the fan definition structure
84 */
Matthew Barth6ad28432017-08-22 11:18:19 -050085 Fan(Mode mode,
86 sdbusplus::bus::bus& bus,
William A. Kennington III1cfc2f12018-10-19 17:29:46 -070087 const sdeventplus::Event& event,
Matt Spinlerc39e8592017-09-28 13:13:08 -050088 std::unique_ptr<trust::Manager>& trust,
Matt Spinlerabf8da32017-04-27 14:08:45 -050089 const FanDefinition& def);
90
Matt Spinlerebaae612017-04-27 14:21:48 -050091 /**
92 * @brief Callback function for when an input sensor changes
93 *
94 * Starts a timer, where if it expires then the sensor
Matt Spinlera9406a72017-04-27 14:29:24 -050095 * was out of range for too long and can be considered not functional.
Matt Spinlerebaae612017-04-27 14:21:48 -050096 */
97 void tachChanged(TachSensor& sensor);
98
99 /**
100 * @brief Calls tachChanged(sensor) on each sensor
101 */
102 void tachChanged();
Matt Spinlerabf8da32017-04-27 14:08:45 -0500103
Matt Spinlera9406a72017-04-27 14:29:24 -0500104 /**
105 * @brief The callback function for the timer
106 *
107 * Sets the sensor to not functional.
108 * If enough sensors are now not functional,
109 * updates the functional status of the whole
110 * fan in the inventory.
111 *
112 * @param[in] sensor - the sensor whose timer expired
113 */
114 void timerExpired(TachSensor& sensor);
115
Matthew Barth4d982852017-11-17 09:37:13 -0600116 /**
117 * @brief Get the name of the fan
118 *
119 * @return - The fan name
120 */
121 inline const std::string& getName() const
122 {
123 return _name;
124 }
125
Matthew Barthf552ea52018-01-15 16:22:04 -0600126 /**
127 * @brief Finds the target speed of this fan
128 *
129 * Finds the target speed from the list of sensors that make up this
130 * fan. At least one sensor should contain a target speed value.
131 *
132 * @return - The target speed found from the list of sensors on the fan
133 */
134 uint64_t findTargetSpeed();
135
Matt Spinlerabf8da32017-04-27 14:08:45 -0500136 private:
137
138 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500139 * @brief Returns true if the sensor input is not within
140 * some deviation of the target.
141 *
142 * @param[in] sensor - the sensor to check
143 */
144 bool outOfRange(const TachSensor& sensor);
145
146 /**
147 * @brief Returns true if too many sensors are nonfunctional
148 * as defined by _numSensorFailsForNonFunc
149 */
150 bool tooManySensorsNonfunctional();
151
Matt Spinlerb1e18512017-04-27 14:42:33 -0500152 /**
153 * @brief Updates the Functional property in the inventory
154 * for the fan based on the value passed in.
155 *
156 * @param[in] functional - If the Functional property should
157 * be set to true or false.
158 */
159 void updateInventory(bool functional);
160
161 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500162 * @brief the dbus object
163 */
164 sdbusplus::bus::bus& _bus;
165
166 /**
167 * @brief The inventory name of the fan
168 */
169 const std::string _name;
170
171 /**
172 * @brief The percentage that the input speed must be below
173 * the target speed to be considered an error.
174 * Between 0 and 100.
175 */
176 const size_t _deviation;
177
178 /**
179 * The number of sensors that must be nonfunctional at the
180 * same time in order for the fan to be set to nonfunctional
181 * in the inventory.
182 */
183 const size_t _numSensorFailsForNonFunc;
184
185 /**
186 * @brief The current functional state of the fan
187 */
188 bool _functional = true;
189
190 /**
191 * The sensor objects for the fan
192 */
Matthew Barth32affb92018-02-16 16:11:13 -0600193 std::vector<std::shared_ptr<TachSensor>> _sensors;
Matt Spinlerc39e8592017-09-28 13:13:08 -0500194
195 /**
196 * The tach trust manager object
197 */
198 std::unique_ptr<trust::Manager>& _trustManager;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500199};
200
201}
202}
203}