blob: 5136ceea974495ca5a5878cb63db7bf6a786144b [file] [log] [blame]
Matt Spinlerabf8da32017-04-27 14:08:45 -05001#pragma once
2
Matt Spinlerabf8da32017-04-27 14:08:45 -05003#include "tach_sensor.hpp"
Matt Spinlerc39e8592017-09-28 13:13:08 -05004#include "trust_manager.hpp"
Matt Spinlerabf8da32017-04-27 14:08:45 -05005#include "types.hpp"
6
Matthew Barth177fe982020-05-26 11:05:19 -05007#include <sdbusplus/bus.hpp>
8#include <sdeventplus/event.hpp>
9
10#include <tuple>
11#include <vector>
12
Matt Spinlerabf8da32017-04-27 14:08:45 -050013namespace phosphor
14{
15namespace fan
16{
17namespace monitor
18{
19
Brad Bishopedaeb312017-07-30 19:38:20 -040020/**
21 * @class InvalidSensorError
22 *
23 * An exception type for sensors that don't exist or
24 * are otherwise inaccessible.
25 */
Matthew Barth177fe982020-05-26 11:05:19 -050026class InvalidSensorError : public std::exception
27{};
Matt Spinlerabf8da32017-04-27 14:08:45 -050028
29/**
30 * @class Fan
31 *
32 * Represents a fan, which can contain 1 or more sensors which
33 * loosely correspond to rotors. See below.
34 *
35 * There is a sensor when hwmon exposes one, which means there is a
36 * speed value to be read. Sometimes there is a sensor per rotor,
37 * and other times multiple rotors just use 1 sensor total where
38 * the sensor reports the slowest speed of all of the rotors.
39 *
40 * A rotor's speed is set by writing the Target value of a sensor.
41 * Sometimes each sensor in a fan supports having a Target, and other
42 * times not all of them do. A TachSensor object knows if it supports
43 * the Target property.
44 *
45 * The strategy for monitoring fan speeds is as follows:
46 *
47 * Every time a Target (new speed written) or Input (actual speed read)
48 * sensor changes, check if the input value is within some range of the target
49 * value. If it isn't, start a timer at the end of which the sensor will be
50 * set to not functional. If enough sensors in the fan are now nonfunctional,
51 * set the whole fan to nonfunctional in the inventory.
52 *
53 * When sensor inputs come back within a specified range of the target,
54 * stop its timer if running, make the sensor functional again if it wasn't,
55 * and if enough sensors in the fan are now functional set the whole fan
56 * back to functional in the inventory.
57 */
58class Fan
59{
Matt Spinlerb1e18512017-04-27 14:42:33 -050060 using Property = std::string;
Patrick Williamsc21d0b32020-05-13 17:55:14 -050061 using Value = std::variant<bool>;
Matt Spinlerb1e18512017-04-27 14:42:33 -050062 using PropertyMap = std::map<Property, Value>;
63
64 using Interface = std::string;
65 using InterfaceMap = std::map<Interface, PropertyMap>;
66
67 using Object = sdbusplus::message::object_path;
68 using ObjectMap = std::map<Object, InterfaceMap>;
Matt Spinlerabf8da32017-04-27 14:08:45 -050069
Matthew Barth177fe982020-05-26 11:05:19 -050070 public:
71 Fan() = delete;
72 Fan(const Fan&) = delete;
73 Fan(Fan&&) = default;
74 Fan& operator=(const Fan&) = delete;
75 Fan& operator=(Fan&&) = default;
76 ~Fan() = default;
Matt Spinlerabf8da32017-04-27 14:08:45 -050077
Matthew Barth177fe982020-05-26 11:05:19 -050078 /**
79 * @brief Constructor
80 *
81 * @param mode - mode of fan monitor
82 * @param bus - the dbus object
83 * @param event - event loop reference
84 * @param trust - the tach trust manager
85 * @param def - the fan definition structure
86 */
87 Fan(Mode mode, sdbusplus::bus::bus& bus, const sdeventplus::Event& event,
88 std::unique_ptr<trust::Manager>& trust, const FanDefinition& def);
Matt Spinlerabf8da32017-04-27 14:08:45 -050089
Matthew Barth177fe982020-05-26 11:05:19 -050090 /**
91 * @brief Callback function for when an input sensor changes
92 *
93 * Starts a timer, where if it expires then the sensor
94 * was out of range for too long and can be considered not functional.
95 */
96 void tachChanged(TachSensor& sensor);
Matt Spinlerabf8da32017-04-27 14:08:45 -050097
Matthew Barth177fe982020-05-26 11:05:19 -050098 /**
99 * @brief Calls tachChanged(sensor) on each sensor
100 */
101 void tachChanged();
Matt Spinlerebaae612017-04-27 14:21:48 -0500102
Matthew Barth177fe982020-05-26 11:05:19 -0500103 /**
104 * @brief The callback function for the timer
105 *
106 * Sets the sensor to not functional.
107 * If enough sensors are now not functional,
108 * updates the functional status of the whole
109 * fan in the inventory.
110 *
111 * @param[in] sensor - the sensor whose timer expired
112 */
113 void timerExpired(TachSensor& sensor);
Matt Spinlerabf8da32017-04-27 14:08:45 -0500114
Matthew Barth177fe982020-05-26 11:05:19 -0500115 /**
116 * @brief Get the name of the fan
117 *
118 * @return - The fan name
119 */
120 inline const std::string& getName() const
121 {
122 return _name;
123 }
Matt Spinlera9406a72017-04-27 14:29:24 -0500124
Matthew Barth177fe982020-05-26 11:05:19 -0500125 /**
126 * @brief Finds the target speed of this fan
127 *
128 * Finds the target speed from the list of sensors that make up this
129 * fan. At least one sensor should contain a target speed value.
130 *
131 * @return - The target speed found from the list of sensors on the fan
132 */
133 uint64_t findTargetSpeed();
Matthew Barth4d982852017-11-17 09:37:13 -0600134
Matthew Barth177fe982020-05-26 11:05:19 -0500135 private:
136 /**
137 * @brief Returns true if the sensor input is not within
138 * some deviation of the target.
139 *
140 * @param[in] sensor - the sensor to check
141 */
142 bool outOfRange(const TachSensor& sensor);
Matthew Barthf552ea52018-01-15 16:22:04 -0600143
Matthew Barth177fe982020-05-26 11:05:19 -0500144 /**
145 * @brief Returns true if too many sensors are nonfunctional
146 * as defined by _numSensorFailsForNonFunc
147 */
148 bool tooManySensorsNonfunctional();
Matt Spinlerabf8da32017-04-27 14:08:45 -0500149
Matthew Barth177fe982020-05-26 11:05:19 -0500150 /**
151 * @brief Updates the Functional property in the inventory
152 * for the fan based on the value passed in.
153 *
154 * @param[in] functional - If the Functional property should
155 * be set to true or false.
156 */
157 void updateInventory(bool functional);
Matt Spinlerabf8da32017-04-27 14:08:45 -0500158
Matthew Barth177fe982020-05-26 11:05:19 -0500159 /**
160 * @brief the dbus object
161 */
162 sdbusplus::bus::bus& _bus;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500163
Matthew Barth177fe982020-05-26 11:05:19 -0500164 /**
165 * @brief The inventory name of the fan
166 */
167 const std::string _name;
Matt Spinlerb1e18512017-04-27 14:42:33 -0500168
Matthew Barth177fe982020-05-26 11:05:19 -0500169 /**
170 * @brief The percentage that the input speed must be below
171 * the target speed to be considered an error.
172 * Between 0 and 100.
173 */
174 const size_t _deviation;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500175
Matthew Barth177fe982020-05-26 11:05:19 -0500176 /**
177 * The number of sensors that must be nonfunctional at the
178 * same time in order for the fan to be set to nonfunctional
179 * in the inventory.
180 */
181 const size_t _numSensorFailsForNonFunc;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500182
Matthew Barth177fe982020-05-26 11:05:19 -0500183 /**
184 * @brief The current functional state of the fan
185 */
186 bool _functional = true;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500187
Matthew Barth177fe982020-05-26 11:05:19 -0500188 /**
189 * The sensor objects for the fan
190 */
191 std::vector<std::shared_ptr<TachSensor>> _sensors;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500192
Matthew Barth177fe982020-05-26 11:05:19 -0500193 /**
194 * The tach trust manager object
195 */
196 std::unique_ptr<trust::Manager>& _trustManager;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500197};
198
Matthew Barth177fe982020-05-26 11:05:19 -0500199} // namespace monitor
200} // namespace fan
201} // namespace phosphor