summaryrefslogtreecommitdiffstats
path: root/monitor/trust_group.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'monitor/trust_group.hpp')
-rw-r--r--monitor/trust_group.hpp238
1 files changed, 238 insertions, 0 deletions
diff --git a/monitor/trust_group.hpp b/monitor/trust_group.hpp
new file mode 100644
index 0000000..af7b372
--- /dev/null
+++ b/monitor/trust_group.hpp
@@ -0,0 +1,238 @@
+#pragma once
+#include <memory>
+#include "tach_sensor.hpp"
+
+namespace phosphor
+{
+namespace fan
+{
+namespace trust
+{
+
+/**
+ * @class Group
+ *
+ * An abstract sensor trust group base class.
+ *
+ * Supports the ability to know if a fan speed sensor value can
+ * be trusted or not, where if it isn't trusted then it shouldn't
+ * be used to determine if the fan is faulted or not.
+ *
+ * It's a group in that there can be multiple sensors in the group
+ * and the trust of all sensors depends on something about those sensors.
+ * For example, if all sensors in the group report a speed of zero,
+ * then no sensor in the group is trusted. All sensors in the group
+ * have the same trust value.
+ *
+ * Trust is calculated when checkTrust() is called after a group
+ * sensor's tach value changes.
+ *
+ * A derived class must override checkGroupTrust().
+ */
+class Group
+{
+ public:
+
+ Group() = delete;
+ virtual ~Group() = default;
+ Group(const Group&) = delete;
+ Group& operator=(const Group&) = delete;
+ Group(Group&&) = default;
+ Group& operator=(Group&&) = default;
+
+ /**
+ * Constructor
+ *
+ * @param[in] names - the names of the sensors in the group
+ */
+ explicit Group(const std::vector<std::string>& names) :
+ _names(names)
+ {
+ }
+
+ /**
+ * Used to register a TachSensor object with the group.
+ * It's only added to the group if the sensor's name is
+ * in the group's list of names.
+ *
+ * @param[in] sensor - the TachSensor to register
+ */
+ void registerSensor(std::unique_ptr<monitor::TachSensor>& sensor)
+ {
+ auto found = std::find_if(
+ _names.begin(),
+ _names.end(),
+ [&sensor](const auto& name)
+ {
+ return monitor::FAN_SENSOR_PATH +
+ name == sensor->name();
+ });
+
+ if (found != _names.end())
+ {
+ _sensors.push_back(sensor);
+ }
+ }
+
+ /**
+ * Says if a sensor belongs to the group.
+ *
+ * After all sensors have registered, this can be
+ * used to say if a TachSensor is in the group.
+ *
+ * @param[in] sensor - the TachSensor object
+ */
+ bool inGroup(const monitor::TachSensor& sensor)
+ {
+ return (std::find_if(
+ _sensors.begin(),
+ _sensors.end(),
+ [&sensor](const auto& s)
+ {
+ return sensor.name() == s.get()->name();
+ }) != _sensors.end());
+ }
+
+ /**
+ * Stops the timers on all sensors in the group.
+ *
+ * Called when the group just changed to not trusted,
+ * so that its sensors' timers can't fire a callback
+ * that may cause them to be considered faulted.
+ */
+ void stopTimers()
+ {
+ std::for_each(
+ _sensors.begin(),
+ _sensors.end(),
+ [](const auto& s)
+ {
+ s.get()->stopTimer();
+ });
+ }
+
+ /**
+ * Starts the timers on all functional sensors in the group.
+ *
+ * Called when the group just changed to trusted.
+ */
+ void startTimers()
+ {
+ std::for_each(
+ _sensors.begin(),
+ _sensors.end(),
+ [](const auto& s)
+ {
+ //If a sensor isn't functional, then its timer
+ //already expired so don't bother starting it again
+ if (s.get()->functional())
+ {
+ s.get()->startTimer();
+ }
+ });
+ }
+
+ /**
+ * Determines the trust for this group based on this
+ * sensor's latest status.
+ *
+ * Calls the derived class's checkGroupTrust function
+ * and updates the class with the results.
+ *
+ * If this is called with a sensor not in the group,
+ * it will be considered trusted.
+ *
+ * @param[in] sensor - TachSensor object
+ *
+ * @return tuple<bool, bool> -
+ * field 0 - the trust value
+ * field 1 - if that trust value changed since last call
+ * to checkTrust
+ */
+ auto checkTrust(const monitor::TachSensor& sensor)
+ {
+ if (inGroup(sensor))
+ {
+ auto trust = checkGroupTrust();
+
+ setTrust(trust);
+
+ return std::tuple<bool, bool>(_trusted, _stateChange);
+ }
+ return std::tuple<bool, bool>(true, false);
+ }
+
+ /**
+ * Says if all sensors in the group are currently trusted,
+ * as determined by the last call to checkTrust().
+ *
+ * @return bool - if the group's sensors are trusted or not
+ */
+ inline auto getTrust() const
+ {
+ return _trusted;
+ }
+
+ /**
+ * Says if the trust value changed in the last call to
+ * checkTrust()
+ *
+ * @return bool - if the trust changed or not
+ */
+ inline auto trustChanged() const
+ {
+ return _stateChange;
+ }
+
+ protected:
+
+ /**
+ * The sensor objects in the group.
+ *
+ * Added by registerSensor().
+ */
+ std::vector<std::reference_wrapper<
+ std::unique_ptr<monitor::TachSensor>>> _sensors;
+
+ private:
+
+ /**
+ * Checks if the group's sensors are trusted.
+ *
+ * The derived class must override this function
+ * to provide custom functionality.
+ *
+ * @return bool - if group is trusted or not
+ */
+ virtual bool checkGroupTrust() = 0;
+
+ /**
+ * Sets the trust value on the object.
+ *
+ * @param[in] trust - the new trust value
+ */
+ inline void setTrust(bool trust)
+ {
+ _stateChange = (trust != _trusted);
+ _trusted = trust;
+ }
+
+ /**
+ * The current trust state of the group
+ */
+ bool _trusted = true;
+
+ /**
+ * If the trust value changed in the last call to checkTrust
+ */
+ bool _stateChange = false;
+
+ /**
+ * The names of the sensors that should be added to this group
+ */
+ const std::vector<std::string> _names;
+};
+
+}
+}
+}
OpenPOWER on IntegriCloud