blob: 6f7aa59bfc561e86396880bb71b1a7288e461f1a [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 *
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,
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 */
110 std::shared_ptr<ValueObject> addValue(const RetryIO& retryIO,
Brandon Kim6d50c3e2019-08-09 15:38:53 -0700111 ObjectInfo& info,
112 TimedoutMap& timedoutMap);
Matthew Barthcb3daaf2018-05-07 15:03:16 -0500113
Patrick Venture043d3232018-08-31 10:10:53 -0700114 /**
115 * @brief Add status interface and functional property for sensor
Brandon Kim86dcac82019-06-18 17:48:51 -0700116 * @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.
Patrick Venture043d3232018-08-31 10:10:53 -0700120 *
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);
Matthew Barth9c431062018-05-07 13:55:29 -0500126
Patrick Ventureb28f4322018-09-14 10:19:14 -0700127 /**
George Liuc9d61612022-10-12 14:31:39 +0800128 * @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 /**
James Feistee73f5b2018-08-01 16:31:42 -0700141 * @brief Get the scale from the sensor.
142 *
143 * @return - Scale value
144 */
Kun Yi15492e72019-07-15 22:04:34 -0700145 inline int64_t getScale(void) const
James Feistee73f5b2018-08-01 16:31:42 -0700146 {
Patrick Venture12659aa2018-12-19 13:58:43 -0800147 return _scale;
James Feistee73f5b2018-08-01 16:31:42 -0700148 }
149
Brandon Kimdb76d492019-06-17 11:53:04 -0700150 /**
151 * @brief Get the GPIO handle from the sensor.
152 *
153 * @return - Pointer to the GPIO handle interface, can be nullptr.
154 */
Kun Yi15492e72019-07-15 22:04:34 -0700155 inline const gpioplus::HandleInterface* getGpio(void) const
Brandon Kimdb76d492019-06-17 11:53:04 -0700156 {
157 return _handle.get();
158 }
159
Brandon Kim86dcac82019-06-18 17:48:51 -0700160 /**
161 * @brief Get whether the sensor has a fault file or not.
162 *
163 * @return - Boolean on whether the sensor has a fault file
164 */
Kun Yi15492e72019-07-15 22:04:34 -0700165 inline bool hasFaultFile(void) const
Brandon Kim86dcac82019-06-18 17:48:51 -0700166 {
167 return _hasFaultFile;
168 }
169
Patrick Venture043d3232018-08-31 10:10:53 -0700170 private:
171 /** @brief Sensor object's identifiers */
Patrick Venture12659aa2018-12-19 13:58:43 -0800172 SensorSet::key_type _sensor;
Matthew Barth9c431062018-05-07 13:55:29 -0500173
Patrick Venture043d3232018-08-31 10:10:53 -0700174 /** @brief Hwmon sysfs access. */
Patrick Venture12659aa2018-12-19 13:58:43 -0800175 const hwmonio::HwmonIOInterface* _ioAccess;
Matthew Barth2e41b132018-05-07 14:15:45 -0500176
Patrick Venture043d3232018-08-31 10:10:53 -0700177 /** @brief Physical device sysfs path. */
Patrick Venture12659aa2018-12-19 13:58:43 -0800178 const std::string& _devPath;
Matthew Barthcb3daaf2018-05-07 15:03:16 -0500179
Patrick Venture043d3232018-08-31 10:10:53 -0700180 /** @brief Structure for storing sensor adjustments */
Patrick Venture12659aa2018-12-19 13:58:43 -0800181 valueAdjust _sensorAdjusts;
Patrick Ventureb28f4322018-09-14 10:19:14 -0700182
183 /** @brief Optional pointer to GPIO handle. */
Patrick Venture12659aa2018-12-19 13:58:43 -0800184 std::unique_ptr<gpioplus::HandleInterface> _handle;
Patrick Ventureb28f4322018-09-14 10:19:14 -0700185
James Feistee73f5b2018-08-01 16:31:42 -0700186 /** @brief sensor scale from configuration. */
Patrick Venture12659aa2018-12-19 13:58:43 -0800187 int64_t _scale;
Brandon Kim86dcac82019-06-18 17:48:51 -0700188
189 /** @brief Tracks whether the sensor has a fault file or not. */
190 bool _hasFaultFile;
Matthew Barth2e41b132018-05-07 14:15:45 -0500191};
Matthew Barth35819382018-04-18 14:53:01 -0500192
William A. Kennington III2227bd52019-06-19 11:32:22 -0700193/**
194 * @brief Locks the gpio represented by the handle
195 *
196 * @param[in] handle - The gpio handle to lock
Brandon Kimdb76d492019-06-17 11:53:04 -0700197 */
William A. Kennington III2227bd52019-06-19 11:32:22 -0700198void gpioLock(const gpioplus::HandleInterface*&& handle);
Brandon Kimdb76d492019-06-17 11:53:04 -0700199
William A. Kennington III2227bd52019-06-19 11:32:22 -0700200/** @brief The type which is responsible for managing the lock */
201using GpioLocker =
202 stdplus::Managed<const gpioplus::HandleInterface*>::Handle<gpioLock>;
Brandon Kimdb76d492019-06-17 11:53:04 -0700203
William A. Kennington III2227bd52019-06-19 11:32:22 -0700204/**
205 * @brief Unlocks the gpio and creates a lock object to ensure
206 * the gpio is locked again.
207 *
208 * @param[in] handle - The gpio handle to unlock and wrap
209 */
210std::optional<GpioLocker> gpioUnlock(const gpioplus::HandleInterface* handle);
Brandon Kimdb76d492019-06-17 11:53:04 -0700211
Brandon Kim6d50c3e2019-08-09 15:38:53 -0700212/**
213 * @brief Asynchronously read a sensor with timeout defined by
214 * ASYNC_READ_TIMEOUT environment variable
215 *
216 * @param[in] sensorSetKey - Sensor object's identifiers
217 * @param[in] ioAccess - Hwmon sysfs access
218 * @param[in] asyncTimeout - Async read timeout in milliseconds
219 * @param[in] timedoutMap - Map to track timed out threads
220 *
221 * (Params needed for HwmonIO::read)
222 * @param[in] type - The hwmon type (ex. temp).
223 * @param[in] id - The hwmon id (ex. 1).
224 * @param[in] sensor - The hwmon sensor (ex. input).
225 * @param[in] retries - The number of times to retry.
226 * @param[in] delay - The time to sleep between retry attempts.
227 *
228 * @return - SensorValueType read asynchronously, will throw if timed out
229 */
230SensorValueType asyncRead(const SensorSet::key_type& sensorSetKey,
231 const hwmonio::HwmonIOInterface* ioAccess,
232 std::chrono::milliseconds asyncTimeout,
233 TimedoutMap& timedoutMap, const std::string& type,
234 const std::string& id, const std::string& sensor,
235 const size_t retries,
236 const std::chrono::milliseconds delay);
Matthew Barth35819382018-04-18 14:53:01 -0500237} // namespace sensor