1abf8da36SMatt Spinler #pragma once
2abf8da36SMatt Spinler 
30d0e3554SMatthew Barth #include <phosphor-logging/log.hpp>
4abf8da36SMatt Spinler #include <sdbusplus/bus.hpp>
53ea9ec2bSPatrick Williams #include <sdbusplus/bus/match.hpp>
68fd879fbSWilliam A. Kennington III #include <sdeventplus/clock.hpp>
71cfc2f11SWilliam A. Kennington III #include <sdeventplus/event.hpp>
88fd879fbSWilliam A. Kennington III #include <sdeventplus/utility/timer.hpp>
9abf8da36SMatt Spinler 
10177fe986SMatthew Barth #include <chrono>
117b34ee0fSMike Capps #include <deque>
12*fbf4703fSPatrick Williams #include <format>
138a8aa442SMatthew Barth #include <optional>
147c23a049SMatthew Barth #include <utility>
15177fe986SMatthew Barth 
16abf8da36SMatt Spinler namespace phosphor
17abf8da36SMatt Spinler {
18abf8da36SMatt Spinler namespace fan
19abf8da36SMatt Spinler {
20abf8da36SMatt Spinler namespace monitor
21abf8da36SMatt Spinler {
22abf8da36SMatt Spinler 
23abf8da36SMatt Spinler class Fan;
24abf8da36SMatt Spinler 
2578689dd7SMatt Spinler constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/";
26abf8da36SMatt Spinler 
27abf8da36SMatt Spinler /**
280a9fe160SMatthew Barth  * The mode fan monitor will run in:
290a9fe160SMatthew Barth  *   - init - only do the initialization steps
300a9fe160SMatthew Barth  *   - monitor - run normal monitoring algorithm
310a9fe160SMatthew Barth  */
320a9fe160SMatthew Barth enum class Mode
330a9fe160SMatthew Barth {
340a9fe160SMatthew Barth     init,
350a9fe160SMatthew Barth     monitor
360a9fe160SMatthew Barth };
370a9fe160SMatthew Barth 
380a9fe160SMatthew Barth /**
393800ae71SMatthew Barth  * The mode that the timer is running in:
403800ae71SMatthew Barth  *   - func - Transition to functional state timer
413800ae71SMatthew Barth  *   - nonfunc - Transition to nonfunctional state timer
423800ae71SMatthew Barth  */
433800ae71SMatthew Barth enum class TimerMode
443800ae71SMatthew Barth {
453800ae71SMatthew Barth     func,
463800ae71SMatthew Barth     nonfunc
473800ae71SMatthew Barth };
483800ae71SMatthew Barth 
493800ae71SMatthew Barth /**
5069f2f48eSJolie Ku  * The mode that the method is running in:
5169f2f48eSJolie Ku  *   - time - Use a percentage based deviation
5269f2f48eSJolie Ku  *   - count - Run up/down count fault detection
5369f2f48eSJolie Ku  */
5469f2f48eSJolie Ku enum MethodMode
5569f2f48eSJolie Ku {
5669f2f48eSJolie Ku     timebased = 0,
5769f2f48eSJolie Ku     count
5869f2f48eSJolie Ku };
5969f2f48eSJolie Ku 
6069f2f48eSJolie Ku /**
61abf8da36SMatt Spinler  * @class TachSensor
62abf8da36SMatt Spinler  *
63abf8da36SMatt Spinler  * This class represents the sensor that reads a tach value.
64abf8da36SMatt Spinler  * It may also support a Target, which is the property used to
65abf8da36SMatt Spinler  * set a speed.  Since it doesn't necessarily have a Target, it
66abf8da36SMatt Spinler  * won't for sure know if it is running too slow, so it leaves
67abf8da36SMatt Spinler  * that determination to other code.
68abf8da36SMatt Spinler  *
69abf8da36SMatt Spinler  * This class has a parent Fan object that knows about all
70abf8da36SMatt Spinler  * sensors for that fan.
71abf8da36SMatt Spinler  */
72abf8da36SMatt Spinler class TachSensor
73abf8da36SMatt Spinler {
74abf8da36SMatt Spinler   public:
75abf8da36SMatt Spinler     TachSensor() = delete;
76abf8da36SMatt Spinler     TachSensor(const TachSensor&) = delete;
77fa0766e3SBrad Bishop     // TachSensor is not moveable since the this pointer is used as systemd
78fa0766e3SBrad Bishop     // callback context.
79fa0766e3SBrad Bishop     TachSensor(TachSensor&&) = delete;
80abf8da36SMatt Spinler     TachSensor& operator=(const TachSensor&) = delete;
81fa0766e3SBrad Bishop     TachSensor& operator=(TachSensor&&) = delete;
82abf8da36SMatt Spinler     ~TachSensor() = default;
83abf8da36SMatt Spinler 
84abf8da36SMatt Spinler     /**
85abf8da36SMatt Spinler      * @brief Constructor
86abf8da36SMatt Spinler      *
870a9fe160SMatthew Barth      * @param[in] mode - mode of fan monitor
88abf8da36SMatt Spinler      * @param[in] bus - the dbus object
89abf8da36SMatt Spinler      * @param[in] fan - the parent fan object
90abf8da36SMatt Spinler      * @param[in] id - the id of the sensor
91abf8da36SMatt Spinler      * @param[in] hasTarget - if the sensor supports
92abf8da36SMatt Spinler      *                        setting the speed
939396bcc3SMatthew Barth      * @param[in] funcDelay - Delay to mark functional
9480f271b2SLei YU      * @param[in] interface - the interface of the target
9527cc39f1SChau Ly      * @param[in] path - the object path of the sensor target
968e5d197bSLei YU      * @param[in] factor - the factor of the sensor target
978e5d197bSLei YU      * @param[in] offset - the offset of the sensor target
9869f2f48eSJolie Ku      * @param[in] method - the method of out of range
9969f2f48eSJolie Ku      * @param[in] threshold - the threshold of counter method
1008a8aa442SMatthew Barth      * @param[in] ignoreAboveMax - whether to ignore being above max or not
101abf8da36SMatt Spinler      * @param[in] timeout - Normal timeout value to use
102f13b42e2SMatt Spinler      * @param[in] errorDelay - Delay in seconds before creating an error
103f13b42e2SMatt Spinler      *                         or std::nullopt if no errors.
104fdfcc679SMatt Spinler      * @param[in] countInterval - In count mode interval
105f13b42e2SMatt Spinler      *
1061cfc2f11SWilliam A. Kennington III      * @param[in] event - Event loop reference
107abf8da36SMatt Spinler      */
108cb356d48SPatrick Williams     TachSensor(Mode mode, sdbusplus::bus_t& bus, Fan& fan,
109177fe986SMatthew Barth                const std::string& id, bool hasTarget, size_t funcDelay,
11027cc39f1SChau Ly                const std::string& interface, const std::string& path,
11127cc39f1SChau Ly                double factor, int64_t offset, size_t method, size_t threshold,
11227cc39f1SChau Ly                bool ignoreAboveMax, size_t timeout,
11327cc39f1SChau Ly                const std::optional<size_t>& errorDelay, size_t countInterval,
11427cc39f1SChau Ly                const sdeventplus::Event& event);
115abf8da36SMatt Spinler 
116abf8da36SMatt Spinler     /**
117c8c8ccf3SMatthew Barth      * @brief Reads a property from the input message and stores it in value.
118c8c8ccf3SMatthew Barth      *        T is the value type.
119c8c8ccf3SMatthew Barth      *
120c8c8ccf3SMatthew Barth      *        Note: This can only be called once per message.
121c8c8ccf3SMatthew Barth      *
122c8c8ccf3SMatthew Barth      * @param[in] msg - the dbus message that contains the data
123c8c8ccf3SMatthew Barth      * @param[in] interface - the interface the property is on
124c8c8ccf3SMatthew Barth      * @param[in] propertName - the name of the property
125c8c8ccf3SMatthew Barth      * @param[out] value - the value to store the property value in
126c8c8ccf3SMatthew Barth      */
127c8c8ccf3SMatthew Barth     template <typename T>
readPropertyFromMessage(sdbusplus::message_t & msg,const std::string & interface,const std::string & propertyName,T & value)128cb356d48SPatrick Williams     static void readPropertyFromMessage(sdbusplus::message_t& msg,
129c8c8ccf3SMatthew Barth                                         const std::string& interface,
130c8c8ccf3SMatthew Barth                                         const std::string& propertyName,
131c8c8ccf3SMatthew Barth                                         T& value)
132c8c8ccf3SMatthew Barth     {
133c8c8ccf3SMatthew Barth         std::string sensor;
134c8c8ccf3SMatthew Barth         std::map<std::string, std::variant<T>> data;
135c8c8ccf3SMatthew Barth         msg.read(sensor, data);
136c8c8ccf3SMatthew Barth 
137c8c8ccf3SMatthew Barth         if (sensor.compare(interface) == 0)
138c8c8ccf3SMatthew Barth         {
139c8c8ccf3SMatthew Barth             auto propertyMap = data.find(propertyName);
140c8c8ccf3SMatthew Barth             if (propertyMap != data.end())
141c8c8ccf3SMatthew Barth             {
142c8c8ccf3SMatthew Barth                 value = std::get<T>(propertyMap->second);
143c8c8ccf3SMatthew Barth             }
144c8c8ccf3SMatthew Barth         }
145c8c8ccf3SMatthew Barth     }
146c8c8ccf3SMatthew Barth 
147c8c8ccf3SMatthew Barth     /**
148abf8da36SMatt Spinler      * @brief Returns the target speed value
149abf8da36SMatt Spinler      */
150f552ea5cSMatthew Barth     uint64_t getTarget() const;
151abf8da36SMatt Spinler 
152abf8da36SMatt Spinler     /**
153abf8da36SMatt Spinler      * @brief Returns the input speed value
154abf8da36SMatt Spinler      */
getInput() const1550891e3b3SMatthew Barth     inline double getInput() const
156abf8da36SMatt Spinler     {
157abf8da36SMatt Spinler         return _tachInput;
158abf8da36SMatt Spinler     }
159abf8da36SMatt Spinler 
160abf8da36SMatt Spinler     /**
161abf8da36SMatt Spinler      * @brief Returns true if sensor has a target
162abf8da36SMatt Spinler      */
hasTarget() const163abf8da36SMatt Spinler     inline bool hasTarget() const
164abf8da36SMatt Spinler     {
165abf8da36SMatt Spinler         return _hasTarget;
166abf8da36SMatt Spinler     }
167abf8da36SMatt Spinler 
168abf8da36SMatt Spinler     /**
16980f271b2SLei YU      * @brief Returns the interface of the sensor target
17080f271b2SLei YU      */
getInterface() const17180f271b2SLei YU     inline std::string getInterface() const
17280f271b2SLei YU     {
17380f271b2SLei YU         return _interface;
17480f271b2SLei YU     }
17580f271b2SLei YU 
17680f271b2SLei YU     /**
177fdcd5db3SMike Capps      * @brief Returns true if sensor has a D-Bus owner
178fdcd5db3SMike Capps      */
hasOwner() const179fdcd5db3SMike Capps     inline bool hasOwner() const
180fdcd5db3SMike Capps     {
181fdcd5db3SMike Capps         return _hasOwner;
182fdcd5db3SMike Capps     }
183fdcd5db3SMike Capps 
184fdcd5db3SMike Capps     /**
185fdcd5db3SMike Capps      * @brief sets D-Bus owner status
186fdcd5db3SMike Capps      *
187fdcd5db3SMike Capps      * @param[in] val - new owner status
188fdcd5db3SMike Capps      */
setOwner(bool val)189fdcd5db3SMike Capps     inline void setOwner(bool val)
190fdcd5db3SMike Capps     {
191fdcd5db3SMike Capps         _hasOwner = val;
192fdcd5db3SMike Capps     }
193fdcd5db3SMike Capps 
194fdcd5db3SMike Capps     /**
1958e5d197bSLei YU      * @brief Returns the factor of the sensor target
1968e5d197bSLei YU      */
getFactor() const1975e7298c5SMatthew Barth     inline double getFactor() const
1988e5d197bSLei YU     {
1998e5d197bSLei YU         return _factor;
2008e5d197bSLei YU     }
2018e5d197bSLei YU 
2028e5d197bSLei YU     /**
203fdcd5db3SMike Capps      * @brief Returns a reference to the sensor's Fan object
204fdcd5db3SMike Capps      */
getFan() const205fdcd5db3SMike Capps     inline Fan& getFan() const
206fdcd5db3SMike Capps     {
207fdcd5db3SMike Capps         return _fan;
208fdcd5db3SMike Capps     }
209fdcd5db3SMike Capps 
210fdcd5db3SMike Capps     /**
2118e5d197bSLei YU      * @brief Returns the offset of the sensor target
2128e5d197bSLei YU      */
getOffset() const2134eac3cf9SLei YU     inline int64_t getOffset() const
2148e5d197bSLei YU     {
2158e5d197bSLei YU         return _offset;
2168e5d197bSLei YU     }
2178e5d197bSLei YU 
2188e5d197bSLei YU     /**
21969f2f48eSJolie Ku      * @brief Returns the method of out of range
22069f2f48eSJolie Ku      */
getMethod() const22169f2f48eSJolie Ku     inline size_t getMethod() const
22269f2f48eSJolie Ku     {
22369f2f48eSJolie Ku         return _method;
22469f2f48eSJolie Ku     }
22569f2f48eSJolie Ku 
22669f2f48eSJolie Ku     /**
22769f2f48eSJolie Ku      * @brief Returns the threshold of count method
22869f2f48eSJolie Ku      */
getThreshold() const22969f2f48eSJolie Ku     inline size_t getThreshold() const
23069f2f48eSJolie Ku     {
23169f2f48eSJolie Ku         return _threshold;
23269f2f48eSJolie Ku     }
23369f2f48eSJolie Ku 
23469f2f48eSJolie Ku     /**
23569f2f48eSJolie Ku      * Set the sensor faulted counter
23669f2f48eSJolie Ku      */
23769f2f48eSJolie Ku     void setCounter(bool count);
23869f2f48eSJolie Ku 
23969f2f48eSJolie Ku     /**
24069f2f48eSJolie Ku      * @brief Returns the sensor faulted count
24169f2f48eSJolie Ku      */
getCounter() const24269f2f48eSJolie Ku     inline size_t getCounter() const
24369f2f48eSJolie Ku     {
24469f2f48eSJolie Ku         return _counter;
24569f2f48eSJolie Ku     }
24669f2f48eSJolie Ku 
24769f2f48eSJolie Ku     /**
248abf8da36SMatt Spinler      * Returns true if the hardware behind this
249abf8da36SMatt Spinler      * sensor is considered working OK/functional.
250abf8da36SMatt Spinler      */
functional() const251abf8da36SMatt Spinler     inline bool functional() const
252abf8da36SMatt Spinler     {
253abf8da36SMatt Spinler         return _functional;
254abf8da36SMatt Spinler     }
255abf8da36SMatt Spinler 
256abf8da36SMatt Spinler     /**
257d199dcdfSMatthew Barth      * Set the functional status and update inventory to match
258ae01b5fcSMatt Spinler      *
259ae01b5fcSMatt Spinler      * @param[in] functional - The new state
260ae01b5fcSMatt Spinler      * @param[in] skipErrorTimer - If setting the sensor to
261ae01b5fcSMatt Spinler      *            nonfunctional, don't start the error timer.
262abf8da36SMatt Spinler      */
263ae01b5fcSMatt Spinler     void setFunctional(bool functional, bool skipErrorTimer = false);
264abf8da36SMatt Spinler 
265a9406a77SMatt Spinler     /**
2666fa181c7SMatt Spinler      * @brief Says if the timer is running or not
2676fa181c7SMatt Spinler      *
2686fa181c7SMatt Spinler      * @return bool - if timer is currently running
269a9406a77SMatt Spinler      */
timerRunning()2706fa181c7SMatt Spinler     inline bool timerRunning()
271a9406a77SMatt Spinler     {
2728fd879fbSWilliam A. Kennington III         return _timer.isEnabled();
2736fa181c7SMatt Spinler     }
2746fa181c7SMatt Spinler 
2756fa181c7SMatt Spinler     /**
2763800ae71SMatthew Barth      * @brief Stops the timer when the given mode differs and starts
2773800ae71SMatthew Barth      * the associated timer for the mode given if not already running
2783800ae71SMatthew Barth      *
2793800ae71SMatthew Barth      * @param[in] mode - mode of timer to start
2806fa181c7SMatt Spinler      */
2813800ae71SMatthew Barth     void startTimer(TimerMode mode);
2826fa181c7SMatt Spinler 
2836fa181c7SMatt Spinler     /**
2846fa181c7SMatt Spinler      * @brief Stops the timer
2856fa181c7SMatt Spinler      */
stopTimer()2866fa181c7SMatt Spinler     inline void stopTimer()
2876fa181c7SMatt Spinler     {
2881d7379eaSMatt Spinler         phosphor::logging::log<phosphor::logging::level::DEBUG>(
289*fbf4703fSPatrick Williams             std::format("Stop running timer on tach sensor {}.", _name)
2900d0e3554SMatthew Barth                 .c_str());
2918fd879fbSWilliam A. Kennington III         _timer.setEnabled(false);
292a9406a77SMatt Spinler     }
293a9406a77SMatt Spinler 
294a9406a77SMatt Spinler     /**
295fdfcc679SMatt Spinler      * @brief Says if the count timer is running
296fdfcc679SMatt Spinler      *
297fdfcc679SMatt Spinler      * @return bool - If count timer running
298fdfcc679SMatt Spinler      */
countTimerRunning() const299fdfcc679SMatt Spinler     inline bool countTimerRunning() const
300fdfcc679SMatt Spinler     {
301fdfcc679SMatt Spinler         return _countTimer && _countTimer->isEnabled();
302fdfcc679SMatt Spinler     }
303fdfcc679SMatt Spinler 
304fdfcc679SMatt Spinler     /**
305fdfcc679SMatt Spinler      * @brief Stops the count timer
306fdfcc679SMatt Spinler      */
307fdfcc679SMatt Spinler     void stopCountTimer();
308fdfcc679SMatt Spinler 
309fdfcc679SMatt Spinler     /**
310fdfcc679SMatt Spinler      * @brief Starts the count timer
311fdfcc679SMatt Spinler      */
312fdfcc679SMatt Spinler     void startCountTimer();
313fdfcc679SMatt Spinler 
314fdfcc679SMatt Spinler     /**
3153800ae71SMatthew Barth      * @brief Return the given timer mode's delay time
3163800ae71SMatthew Barth      *
3173800ae71SMatthew Barth      * @param[in] mode - mode of timer to get delay time for
318a9406a77SMatt Spinler      */
3193800ae71SMatthew Barth     std::chrono::microseconds getDelay(TimerMode mode);
320a9406a77SMatt Spinler 
321ce75b511SMatt Spinler     /**
322ce75b511SMatt Spinler      * Returns the sensor name
323ce75b511SMatt Spinler      */
name() const324ce75b511SMatt Spinler     inline const std::string& name() const
325ce75b511SMatt Spinler     {
326ce75b511SMatt Spinler         return _name;
327ce75b511SMatt Spinler     };
328ce75b511SMatt Spinler 
329f13b42e2SMatt Spinler     /**
330f13b42e2SMatt Spinler      * @brief Says if the error timer is running
331f13b42e2SMatt Spinler      *
332f13b42e2SMatt Spinler      * @return bool - If the timer is running
333f13b42e2SMatt Spinler      */
errorTimerRunning() const334f13b42e2SMatt Spinler     bool errorTimerRunning() const
335f13b42e2SMatt Spinler     {
336f13b42e2SMatt Spinler         if (_errorTimer && _errorTimer->isEnabled())
337f13b42e2SMatt Spinler         {
338f13b42e2SMatt Spinler             return true;
339f13b42e2SMatt Spinler         }
340f13b42e2SMatt Spinler         return false;
341f13b42e2SMatt Spinler     }
342f13b42e2SMatt Spinler 
3437c23a049SMatthew Barth     /**
3447c23a049SMatthew Barth      * @brief Get the current allowed range of speeds
3457c23a049SMatthew Barth      *
346f724c16bSMatt Spinler      * @param[in] lowerDeviation - The configured lower deviation(in percent)
347f724c16bSMatt Spinler      *                             allowed
348f724c16bSMatt Spinler      * @param[in] upperDeviation - The configured upper deviation(in percent)
349f724c16bSMatt Spinler      *                             allowed
3507c23a049SMatthew Barth      *
3518a8aa442SMatthew Barth      * @return pair - Min/Max(optional) range of speeds allowed
3527c23a049SMatthew Barth      */
3538a8aa442SMatthew Barth     std::pair<uint64_t, std::optional<uint64_t>>
354f724c16bSMatt Spinler         getRange(const size_t lowerDeviation,
355f724c16bSMatt Spinler                  const size_t upperDeviation) const;
3567c23a049SMatthew Barth 
357fcb0dbcbSMatthew Barth     /**
358fcb0dbcbSMatthew Barth      * @brief Processes the current state of the sensor
359fcb0dbcbSMatthew Barth      */
360fcb0dbcbSMatthew Barth     void processState();
361fcb0dbcbSMatthew Barth 
362fcb0dbcbSMatthew Barth     /**
363fcb0dbcbSMatthew Barth      * @brief Resets the monitoring method of the sensor
364fcb0dbcbSMatthew Barth      */
365fcb0dbcbSMatthew Barth     void resetMethod();
366fcb0dbcbSMatthew Barth 
3674283c5d5SMatt Spinler     /**
3684283c5d5SMatt Spinler      * @brief Refreshes the tach input and target values by
3694283c5d5SMatt Spinler      *        reading them from D-Bus.
3704283c5d5SMatt Spinler      */
3714283c5d5SMatt Spinler     void updateTachAndTarget();
3724283c5d5SMatt Spinler 
3737b34ee0fSMike Capps     /**
3747b34ee0fSMike Capps      * @brief return the previous tach values
3757b34ee0fSMike Capps      */
getPrevTach() const3767b34ee0fSMike Capps     const std::deque<uint64_t>& getPrevTach() const
3777b34ee0fSMike Capps     {
3787b34ee0fSMike Capps         return _prevTachs;
3797b34ee0fSMike Capps     }
3807b34ee0fSMike Capps 
3817b34ee0fSMike Capps     /**
3827b34ee0fSMike Capps      * @brief return the previous target values
3837b34ee0fSMike Capps      */
getPrevTarget() const3847b34ee0fSMike Capps     const std::deque<uint64_t>& getPrevTarget() const
3857b34ee0fSMike Capps     {
3867b34ee0fSMike Capps         return _prevTargets;
3877b34ee0fSMike Capps     }
3887b34ee0fSMike Capps 
389abf8da36SMatt Spinler   private:
390abf8da36SMatt Spinler     /**
391ebaae611SMatt Spinler      * @brief Returns the match string to use for matching
392ebaae611SMatt Spinler      *        on a properties changed signal.
393ebaae611SMatt Spinler      */
39427cc39f1SChau Ly     std::string getMatchString(const std::optional<std::string> path,
39527cc39f1SChau Ly                                const std::string& interface);
396ebaae611SMatt Spinler 
397ebaae611SMatt Spinler     /**
398ebaae611SMatt Spinler      * @brief Reads the Target property and stores in _tachTarget.
399ebaae611SMatt Spinler      *        Also calls Fan::tachChanged().
400ebaae611SMatt Spinler      *
401ebaae611SMatt Spinler      * @param[in] msg - the dbus message
402ebaae611SMatt Spinler      */
403cb356d48SPatrick Williams     void handleTargetChange(sdbusplus::message_t& msg);
404ebaae611SMatt Spinler 
405ebaae611SMatt Spinler     /**
406ebaae611SMatt Spinler      * @brief Reads the Value property and stores in _tachInput.
407ebaae611SMatt Spinler      *        Also calls Fan::tachChanged().
408ebaae611SMatt Spinler      *
409ebaae611SMatt Spinler      * @param[in] msg - the dbus message
410ebaae611SMatt Spinler      */
411cb356d48SPatrick Williams     void handleTachChange(sdbusplus::message_t& msg);
412ebaae611SMatt Spinler 
4134d982856SMatthew Barth     /**
4144d982856SMatthew Barth      * @brief Updates the Functional property in the inventory
4154d982856SMatthew Barth      *        for this tach sensor based on the value passed in.
4164d982856SMatthew Barth      *
4174d982856SMatthew Barth      * @param[in] functional - If the Functional property should
4184d982856SMatthew Barth      *                         be set to true or false.
4194d982856SMatthew Barth      */
4204d982856SMatthew Barth     void updateInventory(bool functional);
421ebaae611SMatt Spinler 
422ebaae611SMatt Spinler     /**
423abf8da36SMatt Spinler      * @brief the dbus object
424abf8da36SMatt Spinler      */
425cb356d48SPatrick Williams     sdbusplus::bus_t& _bus;
426abf8da36SMatt Spinler 
427abf8da36SMatt Spinler     /**
428abf8da36SMatt Spinler      * @brief Reference to the parent Fan object
429abf8da36SMatt Spinler      */
430abf8da36SMatt Spinler     Fan& _fan;
431abf8da36SMatt Spinler 
432abf8da36SMatt Spinler     /**
433abf8da36SMatt Spinler      * @brief The name of the sensor, including the full path
434abf8da36SMatt Spinler      *
435abf8da36SMatt Spinler      * For example /xyz/openbmc_project/sensors/fan_tach/fan0
436abf8da36SMatt Spinler      */
437abf8da36SMatt Spinler     const std::string _name;
438abf8da36SMatt Spinler 
439abf8da36SMatt Spinler     /**
4404d982856SMatthew Barth      * @brief The inventory name of the sensor, including the full path
4414d982856SMatthew Barth      */
4424d982856SMatthew Barth     const std::string _invName;
4434d982856SMatthew Barth 
4444d982856SMatthew Barth     /**
445abf8da36SMatt Spinler      * @brief If functional (not too slow).  The parent
446abf8da36SMatt Spinler      *        fan object sets this.
447abf8da36SMatt Spinler      */
448ae01b5fcSMatt Spinler     bool _functional = true;
449abf8da36SMatt Spinler 
450abf8da36SMatt Spinler     /**
451abf8da36SMatt Spinler      * @brief If the sensor has a Target property (can set speed)
452abf8da36SMatt Spinler      */
453abf8da36SMatt Spinler     const bool _hasTarget;
454abf8da36SMatt Spinler 
455abf8da36SMatt Spinler     /**
456fdcd5db3SMike Capps      * @brief If the sensor has a D-Bus owner
457fdcd5db3SMike Capps      */
458fdcd5db3SMike Capps     bool _hasOwner = true;
459fdcd5db3SMike Capps 
460fdcd5db3SMike Capps     /**
4619396bcc3SMatthew Barth      * @brief Amount of time to delay updating to functional
4629396bcc3SMatthew Barth      */
4639396bcc3SMatthew Barth     const size_t _funcDelay;
4649396bcc3SMatthew Barth 
4659396bcc3SMatthew Barth     /**
46680f271b2SLei YU      * @brief The interface that the target implements
46780f271b2SLei YU      */
46880f271b2SLei YU     const std::string _interface;
46980f271b2SLei YU 
47080f271b2SLei YU     /**
47127cc39f1SChau Ly      * @brief The object path to set sensor's target
47227cc39f1SChau Ly      */
47327cc39f1SChau Ly     const std::string _path;
47427cc39f1SChau Ly 
47527cc39f1SChau Ly     /**
4768e5d197bSLei YU      * @brief The factor of target to get fan rpm
4778e5d197bSLei YU      */
4785e7298c5SMatthew Barth     const double _factor;
4798e5d197bSLei YU 
4808e5d197bSLei YU     /**
4818e5d197bSLei YU      * @brief The offset of target to get fan rpm
4828e5d197bSLei YU      */
4834eac3cf9SLei YU     const int64_t _offset;
4848e5d197bSLei YU 
4858e5d197bSLei YU     /**
48669f2f48eSJolie Ku      * @brief The method of out of range
48769f2f48eSJolie Ku      */
48869f2f48eSJolie Ku     const size_t _method;
48969f2f48eSJolie Ku 
49069f2f48eSJolie Ku     /**
49169f2f48eSJolie Ku      * @brief The threshold for count method
49269f2f48eSJolie Ku      */
49369f2f48eSJolie Ku     const size_t _threshold;
49469f2f48eSJolie Ku 
49569f2f48eSJolie Ku     /**
4968a8aa442SMatthew Barth      * @brief Whether to ignore being above the max or not
4978a8aa442SMatthew Barth      */
4988a8aa442SMatthew Barth     const bool _ignoreAboveMax;
4998a8aa442SMatthew Barth 
5008a8aa442SMatthew Barth     /**
50169f2f48eSJolie Ku      * @brief The counter for count method
50269f2f48eSJolie Ku      */
50369f2f48eSJolie Ku     size_t _counter = 0;
50469f2f48eSJolie Ku 
50569f2f48eSJolie Ku     /**
506abf8da36SMatt Spinler      * @brief The input speed, from the Value dbus property
507abf8da36SMatt Spinler      */
5080891e3b3SMatthew Barth     double _tachInput = 0;
509abf8da36SMatt Spinler 
510abf8da36SMatt Spinler     /**
511abf8da36SMatt Spinler      * @brief The current target speed, from the Target dbus property
512abf8da36SMatt Spinler      *        (if applicable)
513abf8da36SMatt Spinler      */
514abf8da36SMatt Spinler     uint64_t _tachTarget = 0;
515abf8da36SMatt Spinler 
516abf8da36SMatt Spinler     /**
517abf8da36SMatt Spinler      * @brief The timeout value to use
518abf8da36SMatt Spinler      */
519abf8da36SMatt Spinler     const size_t _timeout;
520ebaae611SMatt Spinler 
521ebaae611SMatt Spinler     /**
5223800ae71SMatthew Barth      * @brief Mode that current timer is in
5233800ae71SMatthew Barth      */
5243800ae71SMatthew Barth     TimerMode _timerMode;
5253800ae71SMatthew Barth 
5263800ae71SMatthew Barth     /**
527a9406a77SMatt Spinler      * The timer object
528a9406a77SMatt Spinler      */
5298fd879fbSWilliam A. Kennington III     sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _timer;
530a9406a77SMatt Spinler 
531a9406a77SMatt Spinler     /**
532ebaae611SMatt Spinler      * @brief The match object for the Value properties changed signal
533ebaae611SMatt Spinler      */
5343ea9ec2bSPatrick Williams     std::unique_ptr<sdbusplus::bus::match_t> tachSignal;
535ebaae611SMatt Spinler 
536ebaae611SMatt Spinler     /**
537ebaae611SMatt Spinler      * @brief The match object for the Target properties changed signal
538ebaae611SMatt Spinler      */
5393ea9ec2bSPatrick Williams     std::unique_ptr<sdbusplus::bus::match_t> targetSignal;
540f13b42e2SMatt Spinler 
541f13b42e2SMatt Spinler     /**
542f13b42e2SMatt Spinler      * @brief The number of seconds to wait between a sensor being set
543f13b42e2SMatt Spinler      *        to nonfunctional and creating an error for it.
544f13b42e2SMatt Spinler      *
545f13b42e2SMatt Spinler      * If std::nullopt, no errors will be created.
546f13b42e2SMatt Spinler      */
547f13b42e2SMatt Spinler     const std::optional<size_t> _errorDelay;
548f13b42e2SMatt Spinler 
549f13b42e2SMatt Spinler     /**
550f13b42e2SMatt Spinler      * @brief The timer that uses _errorDelay.  When it expires an error
551f13b42e2SMatt Spinler      *        will be created for a faulted fan sensor (rotor).
552f13b42e2SMatt Spinler      *
553f13b42e2SMatt Spinler      * If _errorDelay is std::nullopt, then this won't be created.
554f13b42e2SMatt Spinler      */
555f13b42e2SMatt Spinler     std::unique_ptr<
556f13b42e2SMatt Spinler         sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
557f13b42e2SMatt Spinler         _errorTimer;
558fdfcc679SMatt Spinler 
559fdfcc679SMatt Spinler     /**
560fdfcc679SMatt Spinler      * @brief The interval, in seconds, to use for the timer that runs
561fdfcc679SMatt Spinler      *        the checks when using the 'count' method.
562fdfcc679SMatt Spinler      */
563fdfcc679SMatt Spinler     size_t _countInterval;
564fdfcc679SMatt Spinler 
565fdfcc679SMatt Spinler     /**
566fdfcc679SMatt Spinler      * @brief The timer used by the 'count' method for determining
567fdfcc679SMatt Spinler      *        functional status.
568fdfcc679SMatt Spinler      */
569fdfcc679SMatt Spinler     std::unique_ptr<
570fdfcc679SMatt Spinler         sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
571fdfcc679SMatt Spinler         _countTimer;
5727b34ee0fSMike Capps 
5737b34ee0fSMike Capps     /**
5747b34ee0fSMike Capps      * @brief record of previous targets
5757b34ee0fSMike Capps      */
5767b34ee0fSMike Capps     std::deque<uint64_t> _prevTargets;
5777b34ee0fSMike Capps 
5787b34ee0fSMike Capps     /**
5797b34ee0fSMike Capps      * @brief record of previous tach readings
5807b34ee0fSMike Capps      */
5817b34ee0fSMike Capps     std::deque<uint64_t> _prevTachs;
582abf8da36SMatt Spinler };
583abf8da36SMatt Spinler 
584177fe986SMatthew Barth } // namespace monitor
585177fe986SMatthew Barth } // namespace fan
586177fe986SMatthew Barth } // namespace phosphor
587