hardware: data readers can set up sensor thresholds
We are monitoring some hardware sensors. Some sensor values might be
considered dangerous (e.g. high temperatures). This commit introduces a
way of storing thresholds for data readers and validating measured
sensor values against those thresholds.
This is implemented in a way that each data reader must also implement a
method called thresholds() that returns a mapping of sensor XPath to
a Threshold object. These will be collected in the future by
IETFHardware and used to check obtained sensor values in order to raise
alarms.
Change-Id: I2d3854603f2ec04613906290633151f4d7b034f1
diff --git a/src/ietf-hardware/IETFHardware.h b/src/ietf-hardware/IETFHardware.h
index d807fe8..c1265b3 100644
--- a/src/ietf-hardware/IETFHardware.h
+++ b/src/ietf-hardware/IETFHardware.h
@@ -13,6 +13,7 @@
#include <utility>
#include "ietf-hardware/sysfs/EMMC.h"
#include "ietf-hardware/sysfs/HWMon.h"
+#include "ietf-hardware/thresholds.h"
#include "utils/log-fwd.h"
using namespace std::literals;
@@ -20,6 +21,7 @@
namespace velia::ietf_hardware {
using DataTree = std::map<std::string, std::string>;
+using ThresholdsBySensorPath = std::map<std::string, Thresholds<int64_t>>;
/**
* @brief Readout of hardware-state related data according to RFC 8348 (App. A)
@@ -49,7 +51,12 @@
IETFHardware();
~IETFHardware();
- void registerDataReader(const DataReader& callable);
+
+ template <class DataReaderType>
+ void registerDataReader(const DataReaderType& callable)
+ {
+ m_callbacks.push_back(callable);
+ }
DataTree process();
@@ -89,6 +96,7 @@
struct StaticData : private DataReader {
StaticData(std::string propertyPrefix, std::optional<std::string> parent, DataTree tree);
DataTree operator()() const;
+ ThresholdsBySensorPath thresholds() const;
};
/** @brief Manages fans component. Data is provided by a sysfs::HWMon object. */
@@ -96,10 +104,12 @@
private:
std::shared_ptr<sysfs::HWMon> m_hwmon;
unsigned m_fanChannelsCount;
+ Thresholds<int64_t> m_thresholds;
public:
- Fans(std::string propertyPrefix, std::optional<std::string> parent, std::shared_ptr<sysfs::HWMon> hwmon, unsigned fanChannelsCount);
+ Fans(std::string propertyPrefix, std::optional<std::string> parent, std::shared_ptr<sysfs::HWMon> hwmon, unsigned fanChannelsCount, Thresholds<int64_t> thresholds = {});
DataTree operator()() const;
+ ThresholdsBySensorPath thresholds() const;
};
enum class SensorType {
@@ -117,20 +127,24 @@
private:
std::shared_ptr<sysfs::HWMon> m_hwmon;
std::string m_sysfsFile;
+ Thresholds<int64_t> m_thresholds;
public:
- SysfsValue(std::string propertyPrefix, std::optional<std::string> parent, std::shared_ptr<sysfs::HWMon> hwmon, int sysfsChannelNr);
+ SysfsValue(std::string propertyPrefix, std::optional<std::string> parent, std::shared_ptr<sysfs::HWMon> hwmon, int sysfsChannelNr, Thresholds<int64_t> thresholds = {});
DataTree operator()() const;
+ ThresholdsBySensorPath thresholds() const;
};
/** @brief Manages a single eMMC block device hardware component. Data is provided by a sysfs::EMMC object. */
struct EMMC : private DataReader {
private:
std::shared_ptr<sysfs::EMMC> m_emmc;
+ Thresholds<int64_t> m_thresholds;
public:
- EMMC(std::string propertyPrefix, std::optional<std::string> parent, std::shared_ptr<sysfs::EMMC> emmc);
+ EMMC(std::string propertyPrefix, std::optional<std::string> parent, std::shared_ptr<sysfs::EMMC> emmc, Thresholds<int64_t> thresholds = {});
DataTree operator()() const;
+ ThresholdsBySensorPath thresholds() const;
};
/** @brief Use this when you want to wrap reading several properties in one go and still use it as a single DataReader instance (e.g. in on thread)
@@ -138,10 +152,18 @@
struct Group {
private:
std::vector<IETFHardware::DataReader> m_readers;
+ ThresholdsBySensorPath m_thresholds;
public:
- void registerDataReader(const IETFHardware::DataReader& callable);
DataTree operator()() const;
+ ThresholdsBySensorPath thresholds() const;
+
+ template <class DataReaderType>
+ void registerDataReader(const DataReaderType& callable)
+ {
+ m_readers.push_back(callable);
+ m_thresholds.merge(callable.thresholds());
+ }
};
}