blob: a1e05241069f80fcec5f5bb5e8444d36a9b489ed [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
Brandon Kim6d50c3e2019-08-09 15:38:53 -07007#include <cerrno>
8#include <future>
Patrick Ventureb28f4322018-09-14 10:19:14 -07009#include <gpioplus/handle.hpp>
Brandon Kim6d50c3e2019-08-09 15:38:53 -070010#include <map>
Patrick Venture2864b062018-12-19 08:13:41 -080011#include <memory>
William A. Kennington III2227bd52019-06-19 11:32:22 -070012#include <optional>
13#include <stdplus/handle/managed.hpp>
Patrick Venture043d3232018-08-31 10:10:53 -070014#include <unordered_set>
Matthew Barth35819382018-04-18 14:53:01 -050015
16namespace sensor
17{
18
Brandon Kim6d50c3e2019-08-09 15:38:53 -070019using TimedoutMap = std::map<SensorSet::key_type, std::future<int64_t>>;
20
Matthew Barthcb3daaf2018-05-07 15:03:16 -050021struct valueAdjust
22{
23 double gain = 1.0;
24 int offset = 0;
25 std::unordered_set<int> rmRCs;
26};
27
Brandon Kim6d50c3e2019-08-09 15:38:53 -070028/** @brief Custom exception for async sensor reading timeout
29 */
30struct AsyncSensorReadTimeOut : public std::system_error
31{
32 AsyncSensorReadTimeOut() :
33 system_error(std::error_code(ETIMEDOUT, std::system_category()),
34 "Async sensor read timed out")
35 {
36 }
37};
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 /**
James Feistee73f5b2018-08-01 16:31:42 -0700128 * @brief Get the scale from the sensor.
129 *
130 * @return - Scale value
131 */
Kun Yi15492e72019-07-15 22:04:34 -0700132 inline int64_t getScale(void) const
James Feistee73f5b2018-08-01 16:31:42 -0700133 {
Patrick Venture12659aa2018-12-19 13:58:43 -0800134 return _scale;
James Feistee73f5b2018-08-01 16:31:42 -0700135 }
136
Brandon Kimdb76d492019-06-17 11:53:04 -0700137 /**
138 * @brief Get the GPIO handle from the sensor.
139 *
140 * @return - Pointer to the GPIO handle interface, can be nullptr.
141 */
Kun Yi15492e72019-07-15 22:04:34 -0700142 inline const gpioplus::HandleInterface* getGpio(void) const
Brandon Kimdb76d492019-06-17 11:53:04 -0700143 {
144 return _handle.get();
145 }
146
Brandon Kim86dcac82019-06-18 17:48:51 -0700147 /**
148 * @brief Get whether the sensor has a fault file or not.
149 *
150 * @return - Boolean on whether the sensor has a fault file
151 */
Kun Yi15492e72019-07-15 22:04:34 -0700152 inline bool hasFaultFile(void) const
Brandon Kim86dcac82019-06-18 17:48:51 -0700153 {
154 return _hasFaultFile;
155 }
156
Patrick Venture043d3232018-08-31 10:10:53 -0700157 private:
158 /** @brief Sensor object's identifiers */
Patrick Venture12659aa2018-12-19 13:58:43 -0800159 SensorSet::key_type _sensor;
Matthew Barth9c431062018-05-07 13:55:29 -0500160
Patrick Venture043d3232018-08-31 10:10:53 -0700161 /** @brief Hwmon sysfs access. */
Patrick Venture12659aa2018-12-19 13:58:43 -0800162 const hwmonio::HwmonIOInterface* _ioAccess;
Matthew Barth2e41b132018-05-07 14:15:45 -0500163
Patrick Venture043d3232018-08-31 10:10:53 -0700164 /** @brief Physical device sysfs path. */
Patrick Venture12659aa2018-12-19 13:58:43 -0800165 const std::string& _devPath;
Matthew Barthcb3daaf2018-05-07 15:03:16 -0500166
Patrick Venture043d3232018-08-31 10:10:53 -0700167 /** @brief Structure for storing sensor adjustments */
Patrick Venture12659aa2018-12-19 13:58:43 -0800168 valueAdjust _sensorAdjusts;
Patrick Ventureb28f4322018-09-14 10:19:14 -0700169
170 /** @brief Optional pointer to GPIO handle. */
Patrick Venture12659aa2018-12-19 13:58:43 -0800171 std::unique_ptr<gpioplus::HandleInterface> _handle;
Patrick Ventureb28f4322018-09-14 10:19:14 -0700172
James Feistee73f5b2018-08-01 16:31:42 -0700173 /** @brief sensor scale from configuration. */
Patrick Venture12659aa2018-12-19 13:58:43 -0800174 int64_t _scale;
Brandon Kim86dcac82019-06-18 17:48:51 -0700175
176 /** @brief Tracks whether the sensor has a fault file or not. */
177 bool _hasFaultFile;
Matthew Barth2e41b132018-05-07 14:15:45 -0500178};
Matthew Barth35819382018-04-18 14:53:01 -0500179
William A. Kennington III2227bd52019-06-19 11:32:22 -0700180/**
181 * @brief Locks the gpio represented by the handle
182 *
183 * @param[in] handle - The gpio handle to lock
Brandon Kimdb76d492019-06-17 11:53:04 -0700184 */
William A. Kennington III2227bd52019-06-19 11:32:22 -0700185void gpioLock(const gpioplus::HandleInterface*&& handle);
Brandon Kimdb76d492019-06-17 11:53:04 -0700186
William A. Kennington III2227bd52019-06-19 11:32:22 -0700187/** @brief The type which is responsible for managing the lock */
188using GpioLocker =
189 stdplus::Managed<const gpioplus::HandleInterface*>::Handle<gpioLock>;
Brandon Kimdb76d492019-06-17 11:53:04 -0700190
William A. Kennington III2227bd52019-06-19 11:32:22 -0700191/**
192 * @brief Unlocks the gpio and creates a lock object to ensure
193 * the gpio is locked again.
194 *
195 * @param[in] handle - The gpio handle to unlock and wrap
196 */
197std::optional<GpioLocker> gpioUnlock(const gpioplus::HandleInterface* handle);
Brandon Kimdb76d492019-06-17 11:53:04 -0700198
Brandon Kim6d50c3e2019-08-09 15:38:53 -0700199/**
200 * @brief Asynchronously read a sensor with timeout defined by
201 * ASYNC_READ_TIMEOUT environment variable
202 *
203 * @param[in] sensorSetKey - Sensor object's identifiers
204 * @param[in] ioAccess - Hwmon sysfs access
205 * @param[in] asyncTimeout - Async read timeout in milliseconds
206 * @param[in] timedoutMap - Map to track timed out threads
207 *
208 * (Params needed for HwmonIO::read)
209 * @param[in] type - The hwmon type (ex. temp).
210 * @param[in] id - The hwmon id (ex. 1).
211 * @param[in] sensor - The hwmon sensor (ex. input).
212 * @param[in] retries - The number of times to retry.
213 * @param[in] delay - The time to sleep between retry attempts.
214 *
215 * @return - SensorValueType read asynchronously, will throw if timed out
216 */
217SensorValueType asyncRead(const SensorSet::key_type& sensorSetKey,
218 const hwmonio::HwmonIOInterface* ioAccess,
219 std::chrono::milliseconds asyncTimeout,
220 TimedoutMap& timedoutMap, const std::string& type,
221 const std::string& id, const std::string& sensor,
222 const size_t retries,
223 const std::chrono::milliseconds delay);
Matthew Barth35819382018-04-18 14:53:01 -0500224} // namespace sensor