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 Add Priority interface and priority property for sensors 142 * @details The Priority interface defines priority levels for sensors. 143 * 144 * @param[in] info - Sensor object information 145 * @param[in] priority - The priority level for the sensor 146 * 147 * @return - Shared pointer to the priority object 148 */ 149 150 std::shared_ptr<PriorityObject> addPriority(ObjectInfo& info, 151 size_t priority); 152 153 /** 154 * @brief Get the scale from the sensor. 155 * 156 * @return - Scale value 157 */ 158 inline int64_t getScale(void) const 159 { 160 return _scale; 161 } 162 163 /** 164 * @brief Get the GPIO handle from the sensor. 165 * 166 * @return - Pointer to the GPIO handle interface, can be nullptr. 167 */ 168 inline const gpioplus::HandleInterface* getGpio(void) const 169 { 170 return _handle.get(); 171 } 172 173 /** 174 * @brief Get whether the sensor has a fault file or not. 175 * 176 * @return - Boolean on whether the sensor has a fault file 177 */ 178 inline bool hasFaultFile(void) const 179 { 180 return _hasFaultFile; 181 } 182 183 private: 184 /** @brief Sensor object's identifiers */ 185 SensorSet::key_type _sensor; 186 187 /** @brief Hwmon sysfs access. */ 188 const hwmonio::HwmonIOInterface* _ioAccess; 189 190 /** @brief Physical device sysfs path. */ 191 const std::string& _devPath; 192 193 /** @brief Structure for storing sensor adjustments */ 194 valueAdjust _sensorAdjusts; 195 196 /** @brief Optional pointer to GPIO handle. */ 197 std::unique_ptr<gpioplus::HandleInterface> _handle; 198 199 /** @brief sensor scale from configuration. */ 200 int64_t _scale; 201 202 /** @brief Tracks whether the sensor has a fault file or not. */ 203 bool _hasFaultFile; 204 }; 205 206 /** 207 * @brief Locks the gpio represented by the handle 208 * 209 * @param[in] handle - The gpio handle to lock 210 */ 211 void gpioLock(const gpioplus::HandleInterface*&& handle); 212 213 /** @brief The type which is responsible for managing the lock */ 214 using GpioLocker = 215 stdplus::Managed<const gpioplus::HandleInterface*>::Handle<gpioLock>; 216 217 /** 218 * @brief Unlocks the gpio and creates a lock object to ensure 219 * the gpio is locked again. 220 * 221 * @param[in] handle - The gpio handle to unlock and wrap 222 */ 223 std::optional<GpioLocker> gpioUnlock(const gpioplus::HandleInterface* handle); 224 225 /** 226 * @brief Asynchronously read a sensor with timeout defined by 227 * ASYNC_READ_TIMEOUT environment variable 228 * 229 * @param[in] sensorSetKey - Sensor object's identifiers 230 * @param[in] ioAccess - Hwmon sysfs access 231 * @param[in] asyncTimeout - Async read timeout in milliseconds 232 * @param[in] timedoutMap - Map to track timed out threads 233 * 234 * (Params needed for HwmonIO::read) 235 * @param[in] type - The hwmon type (ex. temp). 236 * @param[in] id - The hwmon id (ex. 1). 237 * @param[in] sensor - The hwmon sensor (ex. input). 238 * @param[in] retries - The number of times to retry. 239 * @param[in] delay - The time to sleep between retry attempts. 240 * 241 * @return - SensorValueType read asynchronously, will throw if timed out 242 */ 243 SensorValueType asyncRead(const SensorSet::key_type& sensorSetKey, 244 const hwmonio::HwmonIOInterface* ioAccess, 245 std::chrono::milliseconds asyncTimeout, 246 TimedoutMap& timedoutMap, const std::string& type, 247 const std::string& id, const std::string& sensor, 248 const size_t retries, 249 const std::chrono::milliseconds delay); 250 } // namespace sensor 251