xref: /openbmc/phosphor-fan-presence/monitor/tach_sensor.hpp (revision 8e5d197b840d4498dcb714b60cc1d38202a7a7a7)
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] factor - the factor of the sensor target
66          * @param[in] offset - the offset of the sensor target
67          * @param[in] timeout - Normal timeout value to use
68          * @param[in] events - sd_event pointer
69          */
70         TachSensor(Mode mode,
71                    sdbusplus::bus::bus& bus,
72                    Fan& fan,
73                    const std::string& id,
74                    bool hasTarget,
75                    size_t factor,
76                    size_t offset,
77                    size_t timeout,
78                    phosphor::fan::event::EventPtr& events);
79 
80         /**
81          * @brief Returns the target speed value
82          */
83         uint64_t getTarget() const;
84 
85         /**
86          * @brief Returns the input speed value
87          */
88         inline int64_t getInput() const
89         {
90             return _tachInput;
91         }
92 
93         /**
94          * @brief Returns true if sensor has a target
95          */
96         inline bool hasTarget() const
97         {
98             return _hasTarget;
99         }
100 
101         /**
102          * @brief Returns the factor of the sensor target
103          */
104         inline size_t getFactor() const
105         {
106             return _factor;
107         }
108 
109         /**
110          * @brief Returns the offset of the sensor target
111          */
112         inline size_t getOffset() const
113         {
114             return _offset;
115         }
116 
117         /**
118          * Returns true if the hardware behind this
119          * sensor is considered working OK/functional.
120          */
121         inline bool functional() const
122         {
123             return _functional;
124         }
125 
126         /**
127          * Set the functional status and update inventory to match
128          */
129         void setFunctional(bool functional);
130 
131         /**
132          * @brief Says if the timer is running or not
133          *
134          * @return bool - if timer is currently running
135          */
136         inline bool timerRunning()
137         {
138             return _timer.running();
139         }
140 
141         /**
142          * @brief Starts the timer for the amount of time
143          *        specified in the constructor
144          */
145         inline void startTimer()
146         {
147             _timer.start(
148                     getTimeout(),
149                     phosphor::fan::util::Timer::TimerType::oneshot);
150         }
151 
152         /**
153          * @brief Stops the timer
154          */
155         inline void stopTimer()
156         {
157             _timer.stop();
158         }
159 
160         /**
161          * @brief Returns the timeout value to use for the sensor
162          */
163         std::chrono::microseconds getTimeout();
164 
165         /**
166          * Returns the sensor name
167          */
168         inline const std::string& name() const
169         {
170             return _name;
171         };
172 
173     private:
174 
175         /**
176          * @brief Returns the match string to use for matching
177          *        on a properties changed signal.
178          */
179         std::string getMatchString(const std::string& interface);
180 
181         /**
182          * @brief Reads the Target property and stores in _tachTarget.
183          *        Also calls Fan::tachChanged().
184          *
185          * @param[in] msg - the dbus message
186          */
187         void handleTargetChange(sdbusplus::message::message& msg);
188 
189         /**
190          * @brief Reads the Value property and stores in _tachInput.
191          *        Also calls Fan::tachChanged().
192          *
193          * @param[in] msg - the dbus message
194          */
195         void handleTachChange(sdbusplus::message::message& msg);
196 
197         /**
198          * @brief Updates the Functional property in the inventory
199          *        for this tach sensor based on the value passed in.
200          *
201          * @param[in] functional - If the Functional property should
202          *                         be set to true or false.
203          */
204         void updateInventory(bool functional);
205 
206         /**
207          * @brief the dbus object
208          */
209         sdbusplus::bus::bus& _bus;
210 
211         /**
212          * @brief Reference to the parent Fan object
213          */
214         Fan& _fan;
215 
216         /**
217          * @brief The name of the sensor, including the full path
218          *
219          * For example /xyz/openbmc_project/sensors/fan_tach/fan0
220          */
221         const std::string _name;
222 
223         /**
224          * @brief The inventory name of the sensor, including the full path
225          */
226         const std::string _invName;
227 
228         /**
229          * @brief If functional (not too slow).  The parent
230          *        fan object sets this.
231          */
232         bool _functional;
233 
234         /**
235          * @brief If the sensor has a Target property (can set speed)
236          */
237         const bool _hasTarget;
238 
239         /**
240          * @brief The factor of target to get fan rpm
241          */
242         const size_t _factor;
243 
244         /**
245          * @brief The offset of target to get fan rpm
246          */
247         const size_t _offset;
248 
249         /**
250          * @brief The input speed, from the Value dbus property
251          */
252         int64_t _tachInput = 0;
253 
254         /**
255          * @brief The current target speed, from the Target dbus property
256          *        (if applicable)
257          */
258         uint64_t _tachTarget = 0;
259 
260         /**
261          * @brief The timeout value to use
262          */
263         const size_t _timeout;
264 
265         /**
266          * The timer object
267          */
268         phosphor::fan::util::Timer _timer;
269 
270         /**
271          * @brief The match object for the Value properties changed signal
272          */
273         std::unique_ptr<sdbusplus::server::match::match> tachSignal;
274 
275         /**
276          * @brief The match object for the Target properties changed signal
277          */
278         std::unique_ptr<sdbusplus::server::match::match> targetSignal;
279 };
280 
281 }
282 }
283 }
284