xref: /openbmc/phosphor-hwmon/sensor.hpp (revision 47fb49ac)
1 #pragma once
2 
3 #include "hwmonio.hpp"
4 #include "sensorset.hpp"
5 #include "types.hpp"
6 
7 #include <gpioplus/handle.hpp>
8 #include <stdplus/handle/managed.hpp>
9 
10 #include <cerrno>
11 #include <future>
12 #include <map>
13 #include <memory>
14 #include <optional>
15 #include <unordered_set>
16 
17 namespace sensor
18 {
19 
20 using TimedoutMap = std::map<SensorSet::key_type, std::future<int64_t>>;
21 
22 struct valueAdjust
23 {
24     double gain = 1.0;
25     int offset = 0;
26     std::unordered_set<int> rmRCs;
27 };
28 
29 /** @brief Custom exception for async sensor reading timeout
30  */
31 struct AsyncSensorReadTimeOut : public std::system_error
32 {
AsyncSensorReadTimeOutsensor::AsyncSensorReadTimeOut33     AsyncSensorReadTimeOut() :
34         system_error(std::error_code(ETIMEDOUT, std::system_category()),
35                      "Async sensor read timed out")
36     {}
37 };
38 
39 /** @class Sensor
40  *  @brief Sensor object based on a SensorSet container's key type
41  *  @details Sensor object to create and modify an associated device's sensor
42  *  attributes based on the key type of each sensor in the set provided by the
43  *  device.
44  */
45 class Sensor
46 {
47   public:
48     Sensor() = delete;
49     Sensor(const Sensor&) = delete;
50     Sensor(Sensor&&) = default;
51     Sensor& operator=(const Sensor&) = delete;
52     Sensor& operator=(Sensor&&) = default;
53     ~Sensor() = default;
54 
55     /**
56      * @brief Constructs Sensor object
57      *
58      * @param[in] sensor - A pair of sensor indentifiers
59      * @param[in] ioAccess - Hwmon sysfs access
60      * @param[in] devPath - Device sysfs path
61      */
62     explicit Sensor(const SensorSet::key_type& sensor,
63                     const hwmonio::HwmonIOInterface* ioAccess,
64                     const std::string& devPath);
65 
66     /**
67      * @brief Adds any sensor removal return codes for the sensor
68      * @details Add all return codes defined within a device's config file
69      * for the entire device or for the specific sensor.
70      *
71      * @param[in] rcList - List of return codes found for the sensor
72      */
73     void addRemoveRCs(const std::string& rcList);
74 
75     /**
76      * @brief Get the adjustments struct for the sensor
77      *
78      * @return - Sensor adjustment struct
79      */
getAdjusts() const80     inline const valueAdjust& getAdjusts() const
81     {
82         return _sensorAdjusts;
83     }
84 
85     /**
86      * @brief Adjusts a sensor value
87      * @details Adjusts the value given by any gain and/or offset defined
88      * for this sensor object and returns that adjusted value.
89      *
90      * @param[in] value - Value to be adjusted
91      *
92      * @return - Adjusted sensor value
93      */
94     SensorValueType adjustValue(SensorValueType value);
95 
96     /**
97      * @brief Add value interface and value property for sensor
98      * @details When a sensor has an associated input file, the Sensor.Value
99      * interface is added along with setting the Value property to the
100      * corresponding value found in the input file.
101      *
102      * @param[in] retryIO - Hwmon sysfs file retry constraints
103      *                      (number of and delay between)
104      * @param[in] info - Sensor object information
105      *
106      * @param[in] timedoutMap - Map to track timed out threads
107      *
108      * @return - Shared pointer to the value object
109      */
110     std::shared_ptr<ValueObject> addValue(const RetryIO& retryIO,
111                                           ObjectInfo& info,
112                                           TimedoutMap& timedoutMap);
113 
114     /**
115      * @brief Add status interface and functional property for sensor
116      * @details OperationalStatus interface is added and the Functional property
117      * is set depending on whether a fault file exists and if it does it will
118      * also depend on the content of the fault file. _hasFaultFile will also be
119      * set to true if fault file exists.
120      *
121      * @param[in] info - Sensor object information
122      *
123      * @return - Shared pointer to the status object
124      */
125     std::shared_ptr<StatusObject> addStatus(ObjectInfo& info);
126 
127     /**
128      * @brief Add Accuracy interface and accuracy property for sensor
129      * @details Accuracy interface is the accuracy range (+/-) of the sensor
130      * Value as a percentage, with a value between 0 and 100.
131      *
132      * @param[in] info     - Sensor object information
133      * @param[in] accuracy - The accuracy value for sensor readings
134      *
135      * @return - Shared pointer to the accuracy object
136      */
137     std::shared_ptr<AccuracyObject> addAccuracy(ObjectInfo& info,
138                                                 double accuracy);
139 
140     /**
141      * @brief Add Priority interface and priority property for sensors
142      * @details The Priority interface defines priority levels for sensors.
143      *
144      * @param[in] info     - Sensor object information
145      * @param[in] priority - The priority level for the sensor
146      *
147      * @return - Shared pointer to the priority object
148      */
149 
150     std::shared_ptr<PriorityObject> addPriority(ObjectInfo& info,
151                                                 size_t priority);
152 
153     /**
154      * @brief Get the scale from the sensor.
155      *
156      * @return - Scale value
157      */
getScale(void) const158     inline int64_t getScale(void) const
159     {
160         return _scale;
161     }
162 
163     /**
164      * @brief Get the GPIO handle from the sensor.
165      *
166      * @return - Pointer to the GPIO handle interface, can be nullptr.
167      */
getGpio(void) const168     inline const gpioplus::HandleInterface* getGpio(void) const
169     {
170         return _handle.get();
171     }
172 
173     /**
174      * @brief Get whether the sensor has a fault file or not.
175      *
176      * @return - Boolean on whether the sensor has a fault file
177      */
hasFaultFile(void) const178     inline bool hasFaultFile(void) const
179     {
180         return _hasFaultFile;
181     }
182 
183   private:
184     /** @brief Sensor object's identifiers */
185     SensorSet::key_type _sensor;
186 
187     /** @brief Hwmon sysfs access. */
188     const hwmonio::HwmonIOInterface* _ioAccess;
189 
190     /** @brief Physical device sysfs path. */
191     const std::string& _devPath;
192 
193     /** @brief Structure for storing sensor adjustments */
194     valueAdjust _sensorAdjusts;
195 
196     /** @brief Optional pointer to GPIO handle. */
197     std::unique_ptr<gpioplus::HandleInterface> _handle;
198 
199     /** @brief sensor scale from configuration. */
200     int64_t _scale;
201 
202     /** @brief Tracks whether the sensor has a fault file or not. */
203     bool _hasFaultFile;
204 };
205 
206 /**
207  * @brief Locks the gpio represented by the handle
208  *
209  * @param[in] handle - The gpio handle to lock
210  */
211 void gpioLock(const gpioplus::HandleInterface*&& handle);
212 
213 /** @brief The type which is responsible for managing the lock */
214 using GpioLocker =
215     stdplus::Managed<const gpioplus::HandleInterface*>::Handle<gpioLock>;
216 
217 /**
218  * @brief Unlocks the gpio and creates a lock object to ensure
219  *        the gpio is locked again.
220  *
221  * @param[in] handle - The gpio handle to unlock and wrap
222  */
223 std::optional<GpioLocker> gpioUnlock(const gpioplus::HandleInterface* handle);
224 
225 /**
226  * @brief Asynchronously read a sensor with timeout defined by
227  *        ASYNC_READ_TIMEOUT environment variable
228  *
229  * @param[in] sensorSetKey - Sensor object's identifiers
230  * @param[in] ioAccess - Hwmon sysfs access
231  * @param[in] asyncTimeout - Async read timeout in milliseconds
232  * @param[in] timedoutMap - Map to track timed out threads
233  *
234  * (Params needed for HwmonIO::read)
235  * @param[in] type - The hwmon type (ex. temp).
236  * @param[in] id - The hwmon id (ex. 1).
237  * @param[in] sensor - The hwmon sensor (ex. input).
238  * @param[in] retries - The number of times to retry.
239  * @param[in] delay - The time to sleep between retry attempts.
240  *
241  * @return - SensorValueType read asynchronously, will throw if timed out
242  */
243 SensorValueType asyncRead(const SensorSet::key_type& sensorSetKey,
244                           const hwmonio::HwmonIOInterface* ioAccess,
245                           std::chrono::milliseconds asyncTimeout,
246                           TimedoutMap& timedoutMap, const std::string& type,
247                           const std::string& id, const std::string& sensor,
248                           const size_t retries,
249                           const std::chrono::milliseconds delay);
250 } // namespace sensor
251