xref: /openbmc/phosphor-hwmon/sensor.hpp (revision 02e598ab)
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(
111         const RetryIO& retryIO, ObjectInfo& info, TimedoutMap& timedoutMap);
112 
113     /**
114      * @brief Add status interface and functional property for sensor
115      * @details OperationalStatus interface is added and the Functional property
116      * is set depending on whether a fault file exists and if it does it will
117      * also depend on the content of the fault file. _hasFaultFile will also be
118      * set to true if fault file exists.
119      *
120      * @param[in] info - Sensor object information
121      *
122      * @return - Shared pointer to the status object
123      */
124     std::shared_ptr<StatusObject> addStatus(ObjectInfo& info);
125 
126     /**
127      * @brief Add Accuracy interface and accuracy property for sensor
128      * @details Accuracy interface is the accuracy range (+/-) of the sensor
129      * Value as a percentage, with a value between 0 and 100.
130      *
131      * @param[in] info     - Sensor object information
132      * @param[in] accuracy - The accuracy value for sensor readings
133      *
134      * @return - Shared pointer to the accuracy object
135      */
136     std::shared_ptr<AccuracyObject>
137         addAccuracy(ObjectInfo& info, double accuracy);
138 
139     /**
140      * @brief Add Priority interface and priority property for sensors
141      * @details The Priority interface defines priority levels for sensors.
142      *
143      * @param[in] info     - Sensor object information
144      * @param[in] priority - The priority level for the sensor
145      *
146      * @return - Shared pointer to the priority object
147      */
148 
149     std::shared_ptr<PriorityObject>
150         addPriority(ObjectInfo& info, size_t priority);
151 
152     /**
153      * @brief Get the scale from the sensor.
154      *
155      * @return - Scale value
156      */
getScale(void) const157     inline int64_t getScale(void) const
158     {
159         return _scale;
160     }
161 
162     /**
163      * @brief Get the GPIO handle from the sensor.
164      *
165      * @return - Pointer to the GPIO handle interface, can be nullptr.
166      */
getGpio(void) const167     inline const gpioplus::HandleInterface* getGpio(void) const
168     {
169         return _handle.get();
170     }
171 
172     /**
173      * @brief Get whether the sensor has a fault file or not.
174      *
175      * @return - Boolean on whether the sensor has a fault file
176      */
hasFaultFile(void) const177     inline bool hasFaultFile(void) const
178     {
179         return _hasFaultFile;
180     }
181 
182   private:
183     /** @brief Sensor object's identifiers */
184     SensorSet::key_type _sensor;
185 
186     /** @brief Hwmon sysfs access. */
187     const hwmonio::HwmonIOInterface* _ioAccess;
188 
189     /** @brief Physical device sysfs path. */
190     const std::string& _devPath;
191 
192     /** @brief Structure for storing sensor adjustments */
193     valueAdjust _sensorAdjusts;
194 
195     /** @brief Optional pointer to GPIO handle. */
196     std::unique_ptr<gpioplus::HandleInterface> _handle;
197 
198     /** @brief sensor scale from configuration. */
199     int64_t _scale;
200 
201     /** @brief Tracks whether the sensor has a fault file or not. */
202     bool _hasFaultFile;
203 };
204 
205 /**
206  * @brief Locks the gpio represented by the handle
207  *
208  * @param[in] handle - The gpio handle to lock
209  */
210 void gpioLock(const gpioplus::HandleInterface*&& handle);
211 
212 /** @brief The type which is responsible for managing the lock */
213 using GpioLocker =
214     stdplus::Managed<const gpioplus::HandleInterface*>::Handle<gpioLock>;
215 
216 /**
217  * @brief Unlocks the gpio and creates a lock object to ensure
218  *        the gpio is locked again.
219  *
220  * @param[in] handle - The gpio handle to unlock and wrap
221  */
222 std::optional<GpioLocker> gpioUnlock(const gpioplus::HandleInterface* handle);
223 
224 /**
225  * @brief Asynchronously read a sensor with timeout defined by
226  *        ASYNC_READ_TIMEOUT environment variable
227  *
228  * @param[in] sensorSetKey - Sensor object's identifiers
229  * @param[in] ioAccess - Hwmon sysfs access
230  * @param[in] asyncTimeout - Async read timeout in milliseconds
231  * @param[in] timedoutMap - Map to track timed out threads
232  *
233  * (Params needed for HwmonIO::read)
234  * @param[in] type - The hwmon type (ex. temp).
235  * @param[in] id - The hwmon id (ex. 1).
236  * @param[in] sensor - The hwmon sensor (ex. input).
237  * @param[in] retries - The number of times to retry.
238  * @param[in] delay - The time to sleep between retry attempts.
239  *
240  * @return - SensorValueType read asynchronously, will throw if timed out
241  */
242 SensorValueType asyncRead(
243     const SensorSet::key_type& sensorSetKey,
244     const hwmonio::HwmonIOInterface* ioAccess,
245     std::chrono::milliseconds asyncTimeout, TimedoutMap& timedoutMap,
246     const std::string& type, const std::string& id, const std::string& sensor,
247     const size_t retries, const std::chrono::milliseconds delay);
248 } // namespace sensor
249