xref: /openbmc/phosphor-fan-presence/monitor/tach_sensor.hpp (revision 9396bcc3d3a60fdad5875433210038c1b9d20ac5)
1 #pragma once
2 
3 #include <chrono>
4 #include <sdbusplus/bus.hpp>
5 #include <sdbusplus/server.hpp>
6 #include "event.hpp"
7 #include "timer.hpp"
8 
9 namespace phosphor
10 {
11 namespace fan
12 {
13 namespace monitor
14 {
15 
16 class Fan;
17 
18 constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/";
19 
20 /**
21  * The mode fan monitor will run in:
22  *   - init - only do the initialization steps
23  *   - monitor - run normal monitoring algorithm
24  */
25 enum class Mode
26 {
27     init,
28     monitor
29 };
30 
31 /**
32  * @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  */
43 class TachSensor
44 {
45     public:
46 
47         TachSensor() = delete;
48         TachSensor(const TachSensor&) = delete;
49         // TachSensor is not moveable since the this pointer is used as systemd
50         // callback context.
51         TachSensor(TachSensor&&) = delete;
52         TachSensor& operator=(const TachSensor&) = delete;
53         TachSensor& operator=(TachSensor&&) = delete;
54         ~TachSensor() = default;
55 
56         /**
57          * @brief Constructor
58          *
59          * @param[in] mode - mode of fan monitor
60          * @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
65          * @param[in] funcDelay - Delay to mark functional
66          * @param[in] interface - the interface of the target
67          * @param[in] factor - the factor of the sensor target
68          * @param[in] offset - the offset of the sensor target
69          * @param[in] timeout - Normal timeout value to use
70          * @param[in] events - sd_event pointer
71          */
72         TachSensor(Mode mode,
73                    sdbusplus::bus::bus& bus,
74                    Fan& fan,
75                    const std::string& id,
76                    bool hasTarget,
77                    size_t funcDelay,
78                    const std::string& interface,
79                    size_t factor,
80                    size_t offset,
81                    size_t timeout,
82                    phosphor::fan::event::EventPtr& events);
83 
84         /**
85          * @brief Returns the target speed value
86          */
87         uint64_t getTarget() const;
88 
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         /**
106          * @brief Returns the interface of the sensor target
107          */
108         inline std::string getInterface() const
109         {
110             return _interface;
111         }
112 
113         /**
114          * @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         /**
130          * 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         /**
139          * Set the functional status and update inventory to match
140          */
141         void setFunctional(bool functional);
142 
143         /**
144          * @brief Says if the timer is running or not
145          *
146          * @return bool - if timer is currently running
147          */
148         inline bool timerRunning()
149         {
150             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();
170         }
171 
172         /**
173          * @brief Returns the timeout value to use for the sensor
174          */
175         std::chrono::microseconds getTimeout();
176 
177         /**
178          * Returns the sensor name
179          */
180         inline const std::string& name() const
181         {
182             return _name;
183         };
184 
185     private:
186 
187         /**
188          * @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         /**
194          * @brief Reads the Target property and stores in _tachTarget.
195          *        Also calls Fan::tachChanged().
196          *
197          * @param[in] msg - the dbus message
198          */
199         void handleTargetChange(sdbusplus::message::message& msg);
200 
201         /**
202          * @brief Reads the Value property and stores in _tachInput.
203          *        Also calls Fan::tachChanged().
204          *
205          * @param[in] msg - the dbus message
206          */
207         void handleTachChange(sdbusplus::message::message& msg);
208 
209         /**
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);
217 
218         /**
219          * @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         /**
236          * @brief The inventory name of the sensor, including the full path
237          */
238         const std::string _invName;
239 
240         /**
241          * @brief If functional (not too slow).  The parent
242          *        fan object sets this.
243          */
244         bool _functional;
245 
246         /**
247          * @brief If the sensor has a Target property (can set speed)
248          */
249         const bool _hasTarget;
250 
251         /**
252          * @brief Amount of time to delay updating to functional
253          */
254         const size_t _funcDelay;
255 
256         /**
257          * @brief The interface that the target implements
258          */
259         const std::string _interface;
260 
261         /**
262          * @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         /**
272          * @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;
286 
287         /**
288          * The timer object
289          */
290         phosphor::fan::util::Timer _timer;
291 
292         /**
293          * @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;
301 };
302 
303 }
304 }
305 }
306