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 { AsyncSensorReadTimeOutsensor::AsyncSensorReadTimeOut33 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 identifiers 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 */ getAdjusts() const80 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( 111 const RetryIO& retryIO, ObjectInfo& info, TimedoutMap& timedoutMap); 112 113 /** 114 * @brief Add status interface and functional property for sensor 115 * @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. 119 * 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); 125 126 /** 127 * @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 */ 136 std::shared_ptr<AccuracyObject> 137 addAccuracy(ObjectInfo& info, double accuracy); 138 139 /** 140 * @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 149 std::shared_ptr<PriorityObject> 150 addPriority(ObjectInfo& info, size_t priority); 151 152 /** 153 * @brief Get the scale from the sensor. 154 * 155 * @return - Scale value 156 */ getScale(void) const157 inline int64_t getScale(void) const 158 { 159 return _scale; 160 } 161 162 /** 163 * @brief Get the GPIO handle from the sensor. 164 * 165 * @return - Pointer to the GPIO handle interface, can be nullptr. 166 */ getGpio(void) const167 inline const gpioplus::HandleInterface* getGpio(void) const 168 { 169 return _handle.get(); 170 } 171 172 /** 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 */ hasFaultFile(void) const177 inline bool hasFaultFile(void) const 178 { 179 return _hasFaultFile; 180 } 181 182 private: 183 /** @brief Sensor object's identifiers */ 184 SensorSet::key_type _sensor; 185 186 /** @brief Hwmon sysfs access. */ 187 const hwmonio::HwmonIOInterface* _ioAccess; 188 189 /** @brief Physical device sysfs path. */ 190 const std::string& _devPath; 191 192 /** @brief Structure for storing sensor adjustments */ 193 valueAdjust _sensorAdjusts; 194 195 /** @brief Optional pointer to GPIO handle. */ 196 std::unique_ptr<gpioplus::HandleInterface> _handle; 197 198 /** @brief sensor scale from configuration. */ 199 int64_t _scale; 200 201 /** @brief Tracks whether the sensor has a fault file or not. */ 202 bool _hasFaultFile; 203 }; 204 205 /** 206 * @brief Locks the gpio represented by the handle 207 * 208 * @param[in] handle - The gpio handle to lock 209 */ 210 void gpioLock(const gpioplus::HandleInterface*&& handle); 211 212 /** @brief The type which is responsible for managing the lock */ 213 using GpioLocker = 214 stdplus::Managed<const gpioplus::HandleInterface*>::Handle<gpioLock>; 215 216 /** 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 */ 222 std::optional<GpioLocker> gpioUnlock(const gpioplus::HandleInterface* handle); 223 224 /** 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 */ 242 SensorValueType 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); 248 } // namespace sensor 249