blob: ed8caf8d3509cd796b4508c6d2a50afdecdd875b [file] [log] [blame]
Matt Spinlerabf8da32017-04-27 14:08:45 -05001#pragma once
2
3#include <chrono>
4#include <sdbusplus/bus.hpp>
5#include <sdbusplus/server.hpp>
Matt Spinlere824f982017-05-11 10:07:55 -05006#include "event.hpp"
Matt Spinlera9406a72017-04-27 14:29:24 -05007#include "timer.hpp"
Matt Spinlerabf8da32017-04-27 14:08:45 -05008
9namespace phosphor
10{
11namespace fan
12{
13namespace monitor
14{
15
16class Fan;
17
Matt Spinler78689dd2017-09-28 10:12:07 -050018constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/";
Matt Spinlerabf8da32017-04-27 14:08:45 -050019
20/**
Matthew Barth0a9fe162018-01-26 12:53:15 -060021 * The mode fan monitor will run in:
22 * - init - only do the initialization steps
23 * - monitor - run normal monitoring algorithm
24 */
25enum class Mode
26{
27 init,
28 monitor
29};
30
31/**
Matt Spinlerabf8da32017-04-27 14:08:45 -050032 * @class TachSensor
33 *
34 * This class represents the sensor that reads a tach value.
35 * It may also support a Target, which is the property used to
36 * set a speed. Since it doesn't necessarily have a Target, it
37 * won't for sure know if it is running too slow, so it leaves
38 * that determination to other code.
39 *
40 * This class has a parent Fan object that knows about all
41 * sensors for that fan.
42 */
43class TachSensor
44{
45 public:
46
47 TachSensor() = delete;
48 TachSensor(const TachSensor&) = delete;
Brad Bishopfa0766e2017-07-30 15:42:10 -040049 // TachSensor is not moveable since the this pointer is used as systemd
50 // callback context.
51 TachSensor(TachSensor&&) = delete;
Matt Spinlerabf8da32017-04-27 14:08:45 -050052 TachSensor& operator=(const TachSensor&) = delete;
Brad Bishopfa0766e2017-07-30 15:42:10 -040053 TachSensor& operator=(TachSensor&&) = delete;
Matt Spinlerabf8da32017-04-27 14:08:45 -050054 ~TachSensor() = default;
55
56 /**
57 * @brief Constructor
58 *
Matthew Barth0a9fe162018-01-26 12:53:15 -060059 * @param[in] mode - mode of fan monitor
Matt Spinlerabf8da32017-04-27 14:08:45 -050060 * @param[in] bus - the dbus object
61 * @param[in] fan - the parent fan object
62 * @param[in] id - the id of the sensor
63 * @param[in] hasTarget - if the sensor supports
64 * setting the speed
Matthew Barth9396bcc2018-02-19 14:13:20 -060065 * @param[in] funcDelay - Delay to mark functional
Lei YU80f271b2018-01-31 15:24:46 +080066 * @param[in] interface - the interface of the target
Lei YU8e5d1972018-01-26 17:14:00 +080067 * @param[in] factor - the factor of the sensor target
68 * @param[in] offset - the offset of the sensor target
Matt Spinlerabf8da32017-04-27 14:08:45 -050069 * @param[in] timeout - Normal timeout value to use
Matt Spinlera9406a72017-04-27 14:29:24 -050070 * @param[in] events - sd_event pointer
Matt Spinlerabf8da32017-04-27 14:08:45 -050071 */
Matthew Barth0a9fe162018-01-26 12:53:15 -060072 TachSensor(Mode mode,
73 sdbusplus::bus::bus& bus,
Matt Spinlerabf8da32017-04-27 14:08:45 -050074 Fan& fan,
75 const std::string& id,
76 bool hasTarget,
Matthew Barth9396bcc2018-02-19 14:13:20 -060077 size_t funcDelay,
Lei YU80f271b2018-01-31 15:24:46 +080078 const std::string& interface,
Lei YU8e5d1972018-01-26 17:14:00 +080079 size_t factor,
80 size_t offset,
Matt Spinlera9406a72017-04-27 14:29:24 -050081 size_t timeout,
Matt Spinlere824f982017-05-11 10:07:55 -050082 phosphor::fan::event::EventPtr& events);
Matt Spinlerabf8da32017-04-27 14:08:45 -050083
84 /**
85 * @brief Returns the target speed value
86 */
Matthew Barthf552ea52018-01-15 16:22:04 -060087 uint64_t getTarget() const;
Matt Spinlerabf8da32017-04-27 14:08:45 -050088
89 /**
90 * @brief Returns the input speed value
91 */
92 inline int64_t getInput() const
93 {
94 return _tachInput;
95 }
96
97 /**
98 * @brief Returns true if sensor has a target
99 */
100 inline bool hasTarget() const
101 {
102 return _hasTarget;
103 }
104
105 /**
Lei YU80f271b2018-01-31 15:24:46 +0800106 * @brief Returns the interface of the sensor target
107 */
108 inline std::string getInterface() const
109 {
110 return _interface;
111 }
112
113 /**
Lei YU8e5d1972018-01-26 17:14:00 +0800114 * @brief Returns the factor of the sensor target
115 */
116 inline size_t getFactor() const
117 {
118 return _factor;
119 }
120
121 /**
122 * @brief Returns the offset of the sensor target
123 */
124 inline size_t getOffset() const
125 {
126 return _offset;
127 }
128
129 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500130 * Returns true if the hardware behind this
131 * sensor is considered working OK/functional.
132 */
133 inline bool functional() const
134 {
135 return _functional;
136 }
137
138 /**
Matthew Barthd199dcd2017-11-20 10:36:41 -0600139 * Set the functional status and update inventory to match
Matt Spinlerabf8da32017-04-27 14:08:45 -0500140 */
Matthew Barthd199dcd2017-11-20 10:36:41 -0600141 void setFunctional(bool functional);
Matt Spinlerabf8da32017-04-27 14:08:45 -0500142
Matt Spinlera9406a72017-04-27 14:29:24 -0500143 /**
Matt Spinler6fa181c2017-09-27 16:24:45 -0500144 * @brief Says if the timer is running or not
145 *
146 * @return bool - if timer is currently running
Matt Spinlera9406a72017-04-27 14:29:24 -0500147 */
Matt Spinler6fa181c2017-09-27 16:24:45 -0500148 inline bool timerRunning()
Matt Spinlera9406a72017-04-27 14:29:24 -0500149 {
Matt Spinler6fa181c2017-09-27 16:24:45 -0500150 return _timer.running();
151 }
152
153 /**
154 * @brief Starts the timer for the amount of time
155 * specified in the constructor
156 */
157 inline void startTimer()
158 {
159 _timer.start(
160 getTimeout(),
161 phosphor::fan::util::Timer::TimerType::oneshot);
162 }
163
164 /**
165 * @brief Stops the timer
166 */
167 inline void stopTimer()
168 {
169 _timer.stop();
Matt Spinlera9406a72017-04-27 14:29:24 -0500170 }
171
172 /**
173 * @brief Returns the timeout value to use for the sensor
174 */
175 std::chrono::microseconds getTimeout();
176
Matt Spinlerce75b512017-07-26 15:10:48 -0500177 /**
178 * Returns the sensor name
179 */
180 inline const std::string& name() const
181 {
182 return _name;
183 };
184
Matt Spinlerabf8da32017-04-27 14:08:45 -0500185 private:
186
187 /**
Matt Spinlerebaae612017-04-27 14:21:48 -0500188 * @brief Returns the match string to use for matching
189 * on a properties changed signal.
190 */
191 std::string getMatchString(const std::string& interface);
192
193 /**
Matt Spinlerebaae612017-04-27 14:21:48 -0500194 * @brief Reads the Target property and stores in _tachTarget.
195 * Also calls Fan::tachChanged().
196 *
197 * @param[in] msg - the dbus message
Matt Spinlerebaae612017-04-27 14:21:48 -0500198 */
Brad Bishop771659f2017-07-30 19:52:21 -0400199 void handleTargetChange(sdbusplus::message::message& msg);
Matt Spinlerebaae612017-04-27 14:21:48 -0500200
201 /**
202 * @brief Reads the Value property and stores in _tachInput.
203 * Also calls Fan::tachChanged().
204 *
205 * @param[in] msg - the dbus message
Matt Spinlerebaae612017-04-27 14:21:48 -0500206 */
Brad Bishop771659f2017-07-30 19:52:21 -0400207 void handleTachChange(sdbusplus::message::message& msg);
Matt Spinlerebaae612017-04-27 14:21:48 -0500208
Matthew Barth4d982852017-11-17 09:37:13 -0600209 /**
210 * @brief Updates the Functional property in the inventory
211 * for this tach sensor based on the value passed in.
212 *
213 * @param[in] functional - If the Functional property should
214 * be set to true or false.
215 */
216 void updateInventory(bool functional);
Matt Spinlerebaae612017-04-27 14:21:48 -0500217
218 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500219 * @brief the dbus object
220 */
221 sdbusplus::bus::bus& _bus;
222
223 /**
224 * @brief Reference to the parent Fan object
225 */
226 Fan& _fan;
227
228 /**
229 * @brief The name of the sensor, including the full path
230 *
231 * For example /xyz/openbmc_project/sensors/fan_tach/fan0
232 */
233 const std::string _name;
234
235 /**
Matthew Barth4d982852017-11-17 09:37:13 -0600236 * @brief The inventory name of the sensor, including the full path
237 */
238 const std::string _invName;
239
240 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500241 * @brief If functional (not too slow). The parent
242 * fan object sets this.
243 */
Matthew Barthd199dcd2017-11-20 10:36:41 -0600244 bool _functional;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500245
246 /**
247 * @brief If the sensor has a Target property (can set speed)
248 */
249 const bool _hasTarget;
250
251 /**
Matthew Barth9396bcc2018-02-19 14:13:20 -0600252 * @brief Amount of time to delay updating to functional
253 */
254 const size_t _funcDelay;
255
256 /**
Lei YU80f271b2018-01-31 15:24:46 +0800257 * @brief The interface that the target implements
258 */
259 const std::string _interface;
260
261 /**
Lei YU8e5d1972018-01-26 17:14:00 +0800262 * @brief The factor of target to get fan rpm
263 */
264 const size_t _factor;
265
266 /**
267 * @brief The offset of target to get fan rpm
268 */
269 const size_t _offset;
270
271 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500272 * @brief The input speed, from the Value dbus property
273 */
274 int64_t _tachInput = 0;
275
276 /**
277 * @brief The current target speed, from the Target dbus property
278 * (if applicable)
279 */
280 uint64_t _tachTarget = 0;
281
282 /**
283 * @brief The timeout value to use
284 */
285 const size_t _timeout;
Matt Spinlerebaae612017-04-27 14:21:48 -0500286
287 /**
Matt Spinlera9406a72017-04-27 14:29:24 -0500288 * The timer object
289 */
290 phosphor::fan::util::Timer _timer;
291
292 /**
Matt Spinlerebaae612017-04-27 14:21:48 -0500293 * @brief The match object for the Value properties changed signal
294 */
295 std::unique_ptr<sdbusplus::server::match::match> tachSignal;
296
297 /**
298 * @brief The match object for the Target properties changed signal
299 */
300 std::unique_ptr<sdbusplus::server::match::match> targetSignal;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500301};
302
303}
304}
305}