blob: 9d426cb4510a69463f937e871c48ac459d429abc [file] [log] [blame]
#pragma once
#include "hwmonio.hpp"
#include "sensorset.hpp"
#include "types.hpp"
#include <gpioplus/handle.hpp>
#include <stdplus/handle/managed.hpp>
#include <cerrno>
#include <future>
#include <map>
#include <memory>
#include <optional>
#include <unordered_set>
namespace sensor
{
using TimedoutMap = std::map<SensorSet::key_type, std::future<int64_t>>;
struct valueAdjust
{
double gain = 1.0;
int offset = 0;
std::unordered_set<int> 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 identifiers
* @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<ValueObject> 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<StatusObject> 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<AccuracyObject>
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<PriorityObject>
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<gpioplus::HandleInterface> _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<const gpioplus::HandleInterface*>::Handle<gpioLock>;
/**
* @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<GpioLocker> 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