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 { 33 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 */ 80 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 Get the scale from the sensor. 142 * 143 * @return - Scale value 144 */ 145 inline int64_t getScale(void) const 146 { 147 return _scale; 148 } 149 150 /** 151 * @brief Get the GPIO handle from the sensor. 152 * 153 * @return - Pointer to the GPIO handle interface, can be nullptr. 154 */ 155 inline const gpioplus::HandleInterface* getGpio(void) const 156 { 157 return _handle.get(); 158 } 159 160 /** 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 */ 165 inline bool hasFaultFile(void) const 166 { 167 return _hasFaultFile; 168 } 169 170 private: 171 /** @brief Sensor object's identifiers */ 172 SensorSet::key_type _sensor; 173 174 /** @brief Hwmon sysfs access. */ 175 const hwmonio::HwmonIOInterface* _ioAccess; 176 177 /** @brief Physical device sysfs path. */ 178 const std::string& _devPath; 179 180 /** @brief Structure for storing sensor adjustments */ 181 valueAdjust _sensorAdjusts; 182 183 /** @brief Optional pointer to GPIO handle. */ 184 std::unique_ptr<gpioplus::HandleInterface> _handle; 185 186 /** @brief sensor scale from configuration. */ 187 int64_t _scale; 188 189 /** @brief Tracks whether the sensor has a fault file or not. */ 190 bool _hasFaultFile; 191 }; 192 193 /** 194 * @brief Locks the gpio represented by the handle 195 * 196 * @param[in] handle - The gpio handle to lock 197 */ 198 void gpioLock(const gpioplus::HandleInterface*&& handle); 199 200 /** @brief The type which is responsible for managing the lock */ 201 using GpioLocker = 202 stdplus::Managed<const gpioplus::HandleInterface*>::Handle<gpioLock>; 203 204 /** 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 */ 210 std::optional<GpioLocker> gpioUnlock(const gpioplus::HandleInterface* handle); 211 212 /** 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 */ 230 SensorValueType 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); 237 } // namespace sensor 238