1 #pragma once 2 3 #include "hwmonio.hpp" 4 #include "sensorset.hpp" 5 #include "types.hpp" 6 7 #include <cerrno> 8 #include <future> 9 #include <gpioplus/handle.hpp> 10 #include <map> 11 #include <memory> 12 #include <optional> 13 #include <stdplus/handle/managed.hpp> 14 #include <unordered_set> 15 16 namespace sensor 17 { 18 19 using TimedoutMap = std::map<SensorSet::key_type, std::future<int64_t>>; 20 21 struct valueAdjust 22 { 23 double gain = 1.0; 24 int offset = 0; 25 std::unordered_set<int> rmRCs; 26 }; 27 28 /** @brief Custom exception for async sensor reading timeout 29 */ 30 struct 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 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 Get the scale from the sensor. 129 * 130 * @return - Scale value 131 */ 132 inline int64_t getScale(void) const 133 { 134 return _scale; 135 } 136 137 /** 138 * @brief Get the GPIO handle from the sensor. 139 * 140 * @return - Pointer to the GPIO handle interface, can be nullptr. 141 */ 142 inline const gpioplus::HandleInterface* getGpio(void) const 143 { 144 return _handle.get(); 145 } 146 147 /** 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 */ 152 inline bool hasFaultFile(void) const 153 { 154 return _hasFaultFile; 155 } 156 157 private: 158 /** @brief Sensor object's identifiers */ 159 SensorSet::key_type _sensor; 160 161 /** @brief Hwmon sysfs access. */ 162 const hwmonio::HwmonIOInterface* _ioAccess; 163 164 /** @brief Physical device sysfs path. */ 165 const std::string& _devPath; 166 167 /** @brief Structure for storing sensor adjustments */ 168 valueAdjust _sensorAdjusts; 169 170 /** @brief Optional pointer to GPIO handle. */ 171 std::unique_ptr<gpioplus::HandleInterface> _handle; 172 173 /** @brief sensor scale from configuration. */ 174 int64_t _scale; 175 176 /** @brief Tracks whether the sensor has a fault file or not. */ 177 bool _hasFaultFile; 178 }; 179 180 /** 181 * @brief Locks the gpio represented by the handle 182 * 183 * @param[in] handle - The gpio handle to lock 184 */ 185 void gpioLock(const gpioplus::HandleInterface*&& handle); 186 187 /** @brief The type which is responsible for managing the lock */ 188 using GpioLocker = 189 stdplus::Managed<const gpioplus::HandleInterface*>::Handle<gpioLock>; 190 191 /** 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 */ 197 std::optional<GpioLocker> gpioUnlock(const gpioplus::HandleInterface* handle); 198 199 /** 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 */ 217 SensorValueType 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); 224 } // namespace sensor 225