blob: 2cd0f4aba0bb5ae1a07bfbd9b73944a423b14602 [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
Lei YU80f271b2018-01-31 15:24:46 +080065 * @param[in] interface - the interface of the target
Lei YU8e5d1972018-01-26 17:14:00 +080066 * @param[in] factor - the factor of the sensor target
67 * @param[in] offset - the offset of the sensor target
Matt Spinlerabf8da32017-04-27 14:08:45 -050068 * @param[in] timeout - Normal timeout value to use
Matt Spinlera9406a72017-04-27 14:29:24 -050069 * @param[in] events - sd_event pointer
Matt Spinlerabf8da32017-04-27 14:08:45 -050070 */
Matthew Barth0a9fe162018-01-26 12:53:15 -060071 TachSensor(Mode mode,
72 sdbusplus::bus::bus& bus,
Matt Spinlerabf8da32017-04-27 14:08:45 -050073 Fan& fan,
74 const std::string& id,
75 bool hasTarget,
Lei YU80f271b2018-01-31 15:24:46 +080076 const std::string& interface,
Lei YU8e5d1972018-01-26 17:14:00 +080077 size_t factor,
78 size_t offset,
Matt Spinlera9406a72017-04-27 14:29:24 -050079 size_t timeout,
Matt Spinlere824f982017-05-11 10:07:55 -050080 phosphor::fan::event::EventPtr& events);
Matt Spinlerabf8da32017-04-27 14:08:45 -050081
82 /**
83 * @brief Returns the target speed value
84 */
Matthew Barthf552ea52018-01-15 16:22:04 -060085 uint64_t getTarget() const;
Matt Spinlerabf8da32017-04-27 14:08:45 -050086
87 /**
88 * @brief Returns the input speed value
89 */
90 inline int64_t getInput() const
91 {
92 return _tachInput;
93 }
94
95 /**
96 * @brief Returns true if sensor has a target
97 */
98 inline bool hasTarget() const
99 {
100 return _hasTarget;
101 }
102
103 /**
Lei YU80f271b2018-01-31 15:24:46 +0800104 * @brief Returns the interface of the sensor target
105 */
106 inline std::string getInterface() const
107 {
108 return _interface;
109 }
110
111 /**
Lei YU8e5d1972018-01-26 17:14:00 +0800112 * @brief Returns the factor of the sensor target
113 */
114 inline size_t getFactor() const
115 {
116 return _factor;
117 }
118
119 /**
120 * @brief Returns the offset of the sensor target
121 */
122 inline size_t getOffset() const
123 {
124 return _offset;
125 }
126
127 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500128 * Returns true if the hardware behind this
129 * sensor is considered working OK/functional.
130 */
131 inline bool functional() const
132 {
133 return _functional;
134 }
135
136 /**
Matthew Barthd199dcd2017-11-20 10:36:41 -0600137 * Set the functional status and update inventory to match
Matt Spinlerabf8da32017-04-27 14:08:45 -0500138 */
Matthew Barthd199dcd2017-11-20 10:36:41 -0600139 void setFunctional(bool functional);
Matt Spinlerabf8da32017-04-27 14:08:45 -0500140
Matt Spinlera9406a72017-04-27 14:29:24 -0500141 /**
Matt Spinler6fa181c2017-09-27 16:24:45 -0500142 * @brief Says if the timer is running or not
143 *
144 * @return bool - if timer is currently running
Matt Spinlera9406a72017-04-27 14:29:24 -0500145 */
Matt Spinler6fa181c2017-09-27 16:24:45 -0500146 inline bool timerRunning()
Matt Spinlera9406a72017-04-27 14:29:24 -0500147 {
Matt Spinler6fa181c2017-09-27 16:24:45 -0500148 return _timer.running();
149 }
150
151 /**
152 * @brief Starts the timer for the amount of time
153 * specified in the constructor
154 */
155 inline void startTimer()
156 {
157 _timer.start(
158 getTimeout(),
159 phosphor::fan::util::Timer::TimerType::oneshot);
160 }
161
162 /**
163 * @brief Stops the timer
164 */
165 inline void stopTimer()
166 {
167 _timer.stop();
Matt Spinlera9406a72017-04-27 14:29:24 -0500168 }
169
170 /**
171 * @brief Returns the timeout value to use for the sensor
172 */
173 std::chrono::microseconds getTimeout();
174
Matt Spinlerce75b512017-07-26 15:10:48 -0500175 /**
176 * Returns the sensor name
177 */
178 inline const std::string& name() const
179 {
180 return _name;
181 };
182
Matt Spinlerabf8da32017-04-27 14:08:45 -0500183 private:
184
185 /**
Matt Spinlerebaae612017-04-27 14:21:48 -0500186 * @brief Returns the match string to use for matching
187 * on a properties changed signal.
188 */
189 std::string getMatchString(const std::string& interface);
190
191 /**
Matt Spinlerebaae612017-04-27 14:21:48 -0500192 * @brief Reads the Target property and stores in _tachTarget.
193 * Also calls Fan::tachChanged().
194 *
195 * @param[in] msg - the dbus message
Matt Spinlerebaae612017-04-27 14:21:48 -0500196 */
Brad Bishop771659f2017-07-30 19:52:21 -0400197 void handleTargetChange(sdbusplus::message::message& msg);
Matt Spinlerebaae612017-04-27 14:21:48 -0500198
199 /**
200 * @brief Reads the Value property and stores in _tachInput.
201 * Also calls Fan::tachChanged().
202 *
203 * @param[in] msg - the dbus message
Matt Spinlerebaae612017-04-27 14:21:48 -0500204 */
Brad Bishop771659f2017-07-30 19:52:21 -0400205 void handleTachChange(sdbusplus::message::message& msg);
Matt Spinlerebaae612017-04-27 14:21:48 -0500206
Matthew Barth4d982852017-11-17 09:37:13 -0600207 /**
208 * @brief Updates the Functional property in the inventory
209 * for this tach sensor based on the value passed in.
210 *
211 * @param[in] functional - If the Functional property should
212 * be set to true or false.
213 */
214 void updateInventory(bool functional);
Matt Spinlerebaae612017-04-27 14:21:48 -0500215
216 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500217 * @brief the dbus object
218 */
219 sdbusplus::bus::bus& _bus;
220
221 /**
222 * @brief Reference to the parent Fan object
223 */
224 Fan& _fan;
225
226 /**
227 * @brief The name of the sensor, including the full path
228 *
229 * For example /xyz/openbmc_project/sensors/fan_tach/fan0
230 */
231 const std::string _name;
232
233 /**
Matthew Barth4d982852017-11-17 09:37:13 -0600234 * @brief The inventory name of the sensor, including the full path
235 */
236 const std::string _invName;
237
238 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500239 * @brief If functional (not too slow). The parent
240 * fan object sets this.
241 */
Matthew Barthd199dcd2017-11-20 10:36:41 -0600242 bool _functional;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500243
244 /**
245 * @brief If the sensor has a Target property (can set speed)
246 */
247 const bool _hasTarget;
248
249 /**
Lei YU80f271b2018-01-31 15:24:46 +0800250 * @brief The interface that the target implements
251 */
252 const std::string _interface;
253
254 /**
Lei YU8e5d1972018-01-26 17:14:00 +0800255 * @brief The factor of target to get fan rpm
256 */
257 const size_t _factor;
258
259 /**
260 * @brief The offset of target to get fan rpm
261 */
262 const size_t _offset;
263
264 /**
Matt Spinlerabf8da32017-04-27 14:08:45 -0500265 * @brief The input speed, from the Value dbus property
266 */
267 int64_t _tachInput = 0;
268
269 /**
270 * @brief The current target speed, from the Target dbus property
271 * (if applicable)
272 */
273 uint64_t _tachTarget = 0;
274
275 /**
276 * @brief The timeout value to use
277 */
278 const size_t _timeout;
Matt Spinlerebaae612017-04-27 14:21:48 -0500279
280 /**
Matt Spinlera9406a72017-04-27 14:29:24 -0500281 * The timer object
282 */
283 phosphor::fan::util::Timer _timer;
284
285 /**
Matt Spinlerebaae612017-04-27 14:21:48 -0500286 * @brief The match object for the Value properties changed signal
287 */
288 std::unique_ptr<sdbusplus::server::match::match> tachSignal;
289
290 /**
291 * @brief The match object for the Target properties changed signal
292 */
293 std::unique_ptr<sdbusplus::server::match::match> targetSignal;
Matt Spinlerabf8da32017-04-27 14:08:45 -0500294};
295
296}
297}
298}