#pragma once #include "hwmonio.hpp" #include "sensorset.hpp" #include "types.hpp" #include #include #include #include #include #include #include #include namespace sensor { using TimedoutMap = std::map>; struct valueAdjust { double gain = 1.0; int offset = 0; std::unordered_set rmRCs; }; /** @brief Custom exception for async sensor reading timeout */ struct AsyncSensorReadTimeOut : public std::system_error { AsyncSensorReadTimeOut() : system_error(std::error_code(ETIMEDOUT, std::system_category()), "Async sensor read timed out") {} }; /** @class Sensor * @brief Sensor object based on a SensorSet container's key type * @details Sensor object to create and modify an associated device's sensor * attributes based on the key type of each sensor in the set provided by the * device. */ class Sensor { public: Sensor() = delete; Sensor(const Sensor&) = delete; Sensor(Sensor&&) = default; Sensor& operator=(const Sensor&) = delete; Sensor& operator=(Sensor&&) = default; ~Sensor() = default; /** * @brief Constructs Sensor object * * @param[in] sensor - A pair of sensor indentifiers * @param[in] ioAccess - Hwmon sysfs access * @param[in] devPath - Device sysfs path */ explicit Sensor(const SensorSet::key_type& sensor, const hwmonio::HwmonIOInterface* ioAccess, const std::string& devPath); /** * @brief Adds any sensor removal return codes for the sensor * @details Add all return codes defined within a device's config file * for the entire device or for the specific sensor. * * @param[in] rcList - List of return codes found for the sensor */ void addRemoveRCs(const std::string& rcList); /** * @brief Get the adjustments struct for the sensor * * @return - Sensor adjustment struct */ inline const valueAdjust& getAdjusts() const { return _sensorAdjusts; } /** * @brief Adjusts a sensor value * @details Adjusts the value given by any gain and/or offset defined * for this sensor object and returns that adjusted value. * * @param[in] value - Value to be adjusted * * @return - Adjusted sensor value */ SensorValueType adjustValue(SensorValueType value); /** * @brief Add value interface and value property for sensor * @details When a sensor has an associated input file, the Sensor.Value * interface is added along with setting the Value property to the * corresponding value found in the input file. * * @param[in] retryIO - Hwmon sysfs file retry constraints * (number of and delay between) * @param[in] info - Sensor object information * * @param[in] timedoutMap - Map to track timed out threads * * @return - Shared pointer to the value object */ std::shared_ptr addValue(const RetryIO& retryIO, ObjectInfo& info, TimedoutMap& timedoutMap); /** * @brief Add status interface and functional property for sensor * @details OperationalStatus interface is added and the Functional property * is set depending on whether a fault file exists and if it does it will * also depend on the content of the fault file. _hasFaultFile will also be * set to true if fault file exists. * * @param[in] info - Sensor object information * * @return - Shared pointer to the status object */ std::shared_ptr addStatus(ObjectInfo& info); /** * @brief Add Accuracy interface and accuracy property for sensor * @details Accuracy interface is the accuracy range (+/-) of the sensor * Value as a percentage, with a value between 0 and 100. * * @param[in] info - Sensor object information * @param[in] accuracy - The accuracy value for sensor readings * * @return - Shared pointer to the accuracy object */ std::shared_ptr addAccuracy(ObjectInfo& info, double accuracy); /** * @brief Add Priority interface and priority property for sensors * @details The Priority interface defines priority levels for sensors. * * @param[in] info - Sensor object information * @param[in] priority - The priority level for the sensor * * @return - Shared pointer to the priority object */ std::shared_ptr addPriority(ObjectInfo& info, size_t priority); /** * @brief Get the scale from the sensor. * * @return - Scale value */ inline int64_t getScale(void) const { return _scale; } /** * @brief Get the GPIO handle from the sensor. * * @return - Pointer to the GPIO handle interface, can be nullptr. */ inline const gpioplus::HandleInterface* getGpio(void) const { return _handle.get(); } /** * @brief Get whether the sensor has a fault file or not. * * @return - Boolean on whether the sensor has a fault file */ inline bool hasFaultFile(void) const { return _hasFaultFile; } private: /** @brief Sensor object's identifiers */ SensorSet::key_type _sensor; /** @brief Hwmon sysfs access. */ const hwmonio::HwmonIOInterface* _ioAccess; /** @brief Physical device sysfs path. */ const std::string& _devPath; /** @brief Structure for storing sensor adjustments */ valueAdjust _sensorAdjusts; /** @brief Optional pointer to GPIO handle. */ std::unique_ptr _handle; /** @brief sensor scale from configuration. */ int64_t _scale; /** @brief Tracks whether the sensor has a fault file or not. */ bool _hasFaultFile; }; /** * @brief Locks the gpio represented by the handle * * @param[in] handle - The gpio handle to lock */ void gpioLock(const gpioplus::HandleInterface*&& handle); /** @brief The type which is responsible for managing the lock */ using GpioLocker = stdplus::Managed::Handle; /** * @brief Unlocks the gpio and creates a lock object to ensure * the gpio is locked again. * * @param[in] handle - The gpio handle to unlock and wrap */ std::optional gpioUnlock(const gpioplus::HandleInterface* handle); /** * @brief Asynchronously read a sensor with timeout defined by * ASYNC_READ_TIMEOUT environment variable * * @param[in] sensorSetKey - Sensor object's identifiers * @param[in] ioAccess - Hwmon sysfs access * @param[in] asyncTimeout - Async read timeout in milliseconds * @param[in] timedoutMap - Map to track timed out threads * * (Params needed for HwmonIO::read) * @param[in] type - The hwmon type (ex. temp). * @param[in] id - The hwmon id (ex. 1). * @param[in] sensor - The hwmon sensor (ex. input). * @param[in] retries - The number of times to retry. * @param[in] delay - The time to sleep between retry attempts. * * @return - SensorValueType read asynchronously, will throw if timed out */ SensorValueType asyncRead(const SensorSet::key_type& sensorSetKey, const hwmonio::HwmonIOInterface* ioAccess, std::chrono::milliseconds asyncTimeout, TimedoutMap& timedoutMap, const std::string& type, const std::string& id, const std::string& sensor, const size_t retries, const std::chrono::milliseconds delay); } // namespace sensor