blob: 9d426cb4510a69463f937e871c48ac459d429abc [file] [log] [blame]
Matthew Barth35819382018-04-18 14:53:01 -05001#pragma once
2
Matthew Barth9c431062018-05-07 13:55:29 -05003#include "hwmonio.hpp"
Patrick Venture043d3232018-08-31 10:10:53 -07004#include "sensorset.hpp"
5#include "types.hpp"
6
Patrick Williamse8771fd2023-05-10 07:51:06 -05007#include <gpioplus/handle.hpp>
8#include <stdplus/handle/managed.hpp>
9
Brandon Kim6d50c3e2019-08-09 15:38:53 -070010#include <cerrno>
11#include <future>
Brandon Kim6d50c3e2019-08-09 15:38:53 -070012#include <map>
Patrick Venture2864b062018-12-19 08:13:41 -080013#include <memory>
William A. Kennington III2227bd52019-06-19 11:32:22 -070014#include <optional>
Patrick Venture043d3232018-08-31 10:10:53 -070015#include <unordered_set>
Matthew Barth35819382018-04-18 14:53:01 -050016
17namespace sensor
18{
19
Brandon Kim6d50c3e2019-08-09 15:38:53 -070020using TimedoutMap = std::map<SensorSet::key_type, std::future<int64_t>>;
21
Matthew Barthcb3daaf2018-05-07 15:03:16 -050022struct valueAdjust
23{
24 double gain = 1.0;
25 int offset = 0;
26 std::unordered_set<int> rmRCs;
27};
28
Brandon Kim6d50c3e2019-08-09 15:38:53 -070029/** @brief Custom exception for async sensor reading timeout
30 */
31struct AsyncSensorReadTimeOut : public std::system_error
32{
33 AsyncSensorReadTimeOut() :
34 system_error(std::error_code(ETIMEDOUT, std::system_category()),
35 "Async sensor read timed out")
Patrick Williamse8771fd2023-05-10 07:51:06 -050036 {}
Brandon Kim6d50c3e2019-08-09 15:38:53 -070037};
38
Matthew Barth9c431062018-05-07 13:55:29 -050039/** @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 */
45class Sensor
46{
Patrick Venture043d3232018-08-31 10:10:53 -070047 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;
Matthew Barth9c431062018-05-07 13:55:29 -050054
Patrick Venture043d3232018-08-31 10:10:53 -070055 /**
56 * @brief Constructs Sensor object
57 *
Manojkiran Eda30cab622024-06-17 14:50:58 +053058 * @param[in] sensor - A pair of sensor identifiers
Patrick Venture043d3232018-08-31 10:10:53 -070059 * @param[in] ioAccess - Hwmon sysfs access
60 * @param[in] devPath - Device sysfs path
61 */
62 explicit Sensor(const SensorSet::key_type& sensor,
Patrick Venture2864b062018-12-19 08:13:41 -080063 const hwmonio::HwmonIOInterface* ioAccess,
Patrick Venture043d3232018-08-31 10:10:53 -070064 const std::string& devPath);
Matthew Barth2e41b132018-05-07 14:15:45 -050065
Patrick Venture043d3232018-08-31 10:10:53 -070066 /**
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);
Matthew Barthcb3daaf2018-05-07 15:03:16 -050074
Patrick Venture043d3232018-08-31 10:10:53 -070075 /**
76 * @brief Get the adjustments struct for the sensor
77 *
78 * @return - Sensor adjustment struct
79 */
Kun Yi15492e72019-07-15 22:04:34 -070080 inline const valueAdjust& getAdjusts() const
Patrick Venture043d3232018-08-31 10:10:53 -070081 {
Patrick Venture12659aa2018-12-19 13:58:43 -080082 return _sensorAdjusts;
Patrick Venture043d3232018-08-31 10:10:53 -070083 }
Matthew Barthac473092018-05-07 14:41:46 -050084
Patrick Venture043d3232018-08-31 10:10:53 -070085 /**
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 */
James Feistee73f5b2018-08-01 16:31:42 -070094 SensorValueType adjustValue(SensorValueType value);
Matthew Barthcb3daaf2018-05-07 15:03:16 -050095
Patrick Venture043d3232018-08-31 10:10:53 -070096 /**
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 *
Brandon Kim6d50c3e2019-08-09 15:38:53 -0700106 * @param[in] timedoutMap - Map to track timed out threads
107 *
Patrick Venture043d3232018-08-31 10:10:53 -0700108 * @return - Shared pointer to the value object
109 */
Patrick Williams02e598a2024-08-16 15:21:23 -0400110 std::shared_ptr<ValueObject> addValue(
111 const RetryIO& retryIO, ObjectInfo& info, TimedoutMap& timedoutMap);
Matthew Barthcb3daaf2018-05-07 15:03:16 -0500112
Patrick Venture043d3232018-08-31 10:10:53 -0700113 /**
114 * @brief Add status interface and functional property for sensor
Brandon Kim86dcac82019-06-18 17:48:51 -0700115 * @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.
Patrick Venture043d3232018-08-31 10:10:53 -0700119 *
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);
Matthew Barth9c431062018-05-07 13:55:29 -0500125
Patrick Ventureb28f4322018-09-14 10:19:14 -0700126 /**
George Liuc9d61612022-10-12 14:31:39 +0800127 * @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 */
Patrick Williams02e598a2024-08-16 15:21:23 -0400136 std::shared_ptr<AccuracyObject>
137 addAccuracy(ObjectInfo& info, double accuracy);
George Liuc9d61612022-10-12 14:31:39 +0800138
139 /**
Lakshmi Yadlapati47fb49a2023-10-19 14:47:08 -0500140 * @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
Patrick Williams02e598a2024-08-16 15:21:23 -0400149 std::shared_ptr<PriorityObject>
150 addPriority(ObjectInfo& info, size_t priority);
Lakshmi Yadlapati47fb49a2023-10-19 14:47:08 -0500151
152 /**
James Feistee73f5b2018-08-01 16:31:42 -0700153 * @brief Get the scale from the sensor.
154 *
155 * @return - Scale value
156 */
Kun Yi15492e72019-07-15 22:04:34 -0700157 inline int64_t getScale(void) const
James Feistee73f5b2018-08-01 16:31:42 -0700158 {
Patrick Venture12659aa2018-12-19 13:58:43 -0800159 return _scale;
James Feistee73f5b2018-08-01 16:31:42 -0700160 }
161
Brandon Kimdb76d492019-06-17 11:53:04 -0700162 /**
163 * @brief Get the GPIO handle from the sensor.
164 *
165 * @return - Pointer to the GPIO handle interface, can be nullptr.
166 */
Kun Yi15492e72019-07-15 22:04:34 -0700167 inline const gpioplus::HandleInterface* getGpio(void) const
Brandon Kimdb76d492019-06-17 11:53:04 -0700168 {
169 return _handle.get();
170 }
171
Brandon Kim86dcac82019-06-18 17:48:51 -0700172 /**
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 */
Kun Yi15492e72019-07-15 22:04:34 -0700177 inline bool hasFaultFile(void) const
Brandon Kim86dcac82019-06-18 17:48:51 -0700178 {
179 return _hasFaultFile;
180 }
181
Patrick Venture043d3232018-08-31 10:10:53 -0700182 private:
183 /** @brief Sensor object's identifiers */
Patrick Venture12659aa2018-12-19 13:58:43 -0800184 SensorSet::key_type _sensor;
Matthew Barth9c431062018-05-07 13:55:29 -0500185
Patrick Venture043d3232018-08-31 10:10:53 -0700186 /** @brief Hwmon sysfs access. */
Patrick Venture12659aa2018-12-19 13:58:43 -0800187 const hwmonio::HwmonIOInterface* _ioAccess;
Matthew Barth2e41b132018-05-07 14:15:45 -0500188
Patrick Venture043d3232018-08-31 10:10:53 -0700189 /** @brief Physical device sysfs path. */
Patrick Venture12659aa2018-12-19 13:58:43 -0800190 const std::string& _devPath;
Matthew Barthcb3daaf2018-05-07 15:03:16 -0500191
Patrick Venture043d3232018-08-31 10:10:53 -0700192 /** @brief Structure for storing sensor adjustments */
Patrick Venture12659aa2018-12-19 13:58:43 -0800193 valueAdjust _sensorAdjusts;
Patrick Ventureb28f4322018-09-14 10:19:14 -0700194
195 /** @brief Optional pointer to GPIO handle. */
Patrick Venture12659aa2018-12-19 13:58:43 -0800196 std::unique_ptr<gpioplus::HandleInterface> _handle;
Patrick Ventureb28f4322018-09-14 10:19:14 -0700197
James Feistee73f5b2018-08-01 16:31:42 -0700198 /** @brief sensor scale from configuration. */
Patrick Venture12659aa2018-12-19 13:58:43 -0800199 int64_t _scale;
Brandon Kim86dcac82019-06-18 17:48:51 -0700200
201 /** @brief Tracks whether the sensor has a fault file or not. */
202 bool _hasFaultFile;
Matthew Barth2e41b132018-05-07 14:15:45 -0500203};
Matthew Barth35819382018-04-18 14:53:01 -0500204
William A. Kennington III2227bd52019-06-19 11:32:22 -0700205/**
206 * @brief Locks the gpio represented by the handle
207 *
208 * @param[in] handle - The gpio handle to lock
Brandon Kimdb76d492019-06-17 11:53:04 -0700209 */
William A. Kennington III2227bd52019-06-19 11:32:22 -0700210void gpioLock(const gpioplus::HandleInterface*&& handle);
Brandon Kimdb76d492019-06-17 11:53:04 -0700211
William A. Kennington III2227bd52019-06-19 11:32:22 -0700212/** @brief The type which is responsible for managing the lock */
213using GpioLocker =
214 stdplus::Managed<const gpioplus::HandleInterface*>::Handle<gpioLock>;
Brandon Kimdb76d492019-06-17 11:53:04 -0700215
William A. Kennington III2227bd52019-06-19 11:32:22 -0700216/**
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 */
222std::optional<GpioLocker> gpioUnlock(const gpioplus::HandleInterface* handle);
Brandon Kimdb76d492019-06-17 11:53:04 -0700223
Brandon Kim6d50c3e2019-08-09 15:38:53 -0700224/**
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 */
Patrick Williams02e598a2024-08-16 15:21:23 -0400242SensorValueType 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);
Matthew Barth35819382018-04-18 14:53:01 -0500248} // namespace sensor