blob: 001076b713870d12edc542e8c864ec8d00586ffc [file] [log] [blame]
Matt Spinler78689dd2017-09-28 10:12:07 -05001#pragma once
Matt Spinler78689dd2017-09-28 10:12:07 -05002#include "tach_sensor.hpp"
3
Matthew Barth177fe982020-05-26 11:05:19 -05004#include <memory>
5
Matt Spinler78689dd2017-09-28 10:12:07 -05006namespace phosphor
7{
8namespace fan
9{
10namespace trust
11{
12
Matthew Barth6f31d192018-01-30 13:06:27 -060013constexpr auto sensorName = 0;
14constexpr auto inTrust = 1;
Matthew Barth177fe982020-05-26 11:05:19 -050015using GroupDefinition = std::tuple<std::string, bool>;
Matthew Barth6f31d192018-01-30 13:06:27 -060016
Matthew Bartha1c88322018-02-16 12:38:27 -060017struct GroupSensor
18{
19 std::shared_ptr<monitor::TachSensor> sensor;
20 bool inTrust;
21};
22
Matt Spinler78689dd2017-09-28 10:12:07 -050023/**
24 * @class Group
25 *
26 * An abstract sensor trust group base class.
27 *
28 * Supports the ability to know if a fan speed sensor value can
29 * be trusted or not, where if it isn't trusted then it shouldn't
30 * be used to determine if the fan is faulted or not.
31 *
32 * It's a group in that there can be multiple sensors in the group
33 * and the trust of all sensors depends on something about those sensors.
34 * For example, if all sensors in the group report a speed of zero,
35 * then no sensor in the group is trusted. All sensors in the group
36 * have the same trust value.
37 *
38 * Trust is calculated when checkTrust() is called after a group
39 * sensor's tach value changes.
40 *
41 * A derived class must override checkGroupTrust().
42 */
43class Group
44{
Matthew Barth177fe982020-05-26 11:05:19 -050045 public:
46 Group() = delete;
47 virtual ~Group() = default;
48 Group(const Group&) = delete;
49 Group& operator=(const Group&) = delete;
50 Group(Group&&) = default;
51 Group& operator=(Group&&) = default;
Matt Spinler78689dd2017-09-28 10:12:07 -050052
Matthew Barth177fe982020-05-26 11:05:19 -050053 /**
54 * Constructor
55 *
56 * @param[in] names - the names and inclusion of sensors in the group
57 */
Patrick Williams61b73292023-05-10 07:50:12 -050058 explicit Group(const std::vector<GroupDefinition>& names) : _names(names) {}
Matt Spinler78689dd2017-09-28 10:12:07 -050059
Matthew Barth177fe982020-05-26 11:05:19 -050060 /**
61 * Used to register a TachSensor object with the group.
62 * It's only added to the group if the sensor's name is
63 * in the group's list of names.
64 *
65 * @param[in] sensor - the TachSensor to register
66 */
67 void registerSensor(std::shared_ptr<monitor::TachSensor>& sensor)
68 {
Patrick Williamsdfddd642024-08-16 15:21:51 -040069 auto found = std::find_if(
70 _names.begin(), _names.end(), [&sensor](const auto& name) {
71 return monitor::FAN_SENSOR_PATH + std::get<sensorName>(name) ==
72 sensor->name();
73 });
Matthew Barth177fe982020-05-26 11:05:19 -050074
75 if (found != _names.end())
Matt Spinler78689dd2017-09-28 10:12:07 -050076 {
Matthew Barth177fe982020-05-26 11:05:19 -050077 _sensors.push_back({sensor, std::get<inTrust>(*found)});
Matt Spinler78689dd2017-09-28 10:12:07 -050078 }
Matthew Barth177fe982020-05-26 11:05:19 -050079 }
Matt Spinler78689dd2017-09-28 10:12:07 -050080
Matthew Barth177fe982020-05-26 11:05:19 -050081 /**
82 * Says if a sensor belongs to the group.
83 *
84 * After all sensors have registered, this can be
85 * used to say if a TachSensor is in the group.
86 *
87 * @param[in] sensor - the TachSensor object
88 */
89 bool inGroup(const monitor::TachSensor& sensor)
90 {
91 return (std::find_if(_sensors.begin(), _sensors.end(),
92 [&sensor](const auto& s) {
Patrick Williamsdfddd642024-08-16 15:21:51 -040093 return sensor.name() == s.sensor->name();
94 }) != _sensors.end());
Matthew Barth177fe982020-05-26 11:05:19 -050095 }
Matt Spinler78689dd2017-09-28 10:12:07 -050096
Matthew Barth177fe982020-05-26 11:05:19 -050097 /**
Matthew Barthfcb0dbc2021-02-10 14:23:39 -060098 * Cancels monitoring on all sensors in the group.
Matthew Barth177fe982020-05-26 11:05:19 -050099 *
100 * Called when the group just changed to not trusted,
Matthew Barthfcb0dbc2021-02-10 14:23:39 -0600101 * so that its sensors' monitoring method does not
102 * cause them to be considered faulted.
Matthew Barth177fe982020-05-26 11:05:19 -0500103 */
Matthew Barthfcb0dbc2021-02-10 14:23:39 -0600104 void cancelMonitoring()
Matthew Barth177fe982020-05-26 11:05:19 -0500105 {
106 std::for_each(_sensors.begin(), _sensors.end(),
Matthew Barthfcb0dbc2021-02-10 14:23:39 -0600107 [](const auto& s) { s.sensor->resetMethod(); });
Matthew Barth177fe982020-05-26 11:05:19 -0500108 }
109
110 /**
Matthew Barthfcb0dbc2021-02-10 14:23:39 -0600111 * Starts monitoring on all sensors in the group by processing their current
112 * state
Matthew Barth177fe982020-05-26 11:05:19 -0500113 *
114 * Called when the group just changed to trusted.
115 */
Matthew Barthfcb0dbc2021-02-10 14:23:39 -0600116 void startMonitoring()
Matthew Barth177fe982020-05-26 11:05:19 -0500117 {
Matthew Barthfcb0dbc2021-02-10 14:23:39 -0600118 std::for_each(_sensors.begin(), _sensors.end(),
119 [](const auto& s) { s.sensor->processState(); });
Matthew Barth177fe982020-05-26 11:05:19 -0500120 }
Matt Spinler78689dd2017-09-28 10:12:07 -0500121
Matthew Barth177fe982020-05-26 11:05:19 -0500122 /**
123 * Determines the trust for this group based on this
124 * sensor's latest status.
125 *
126 * Calls the derived class's checkGroupTrust function
127 * and updates the class with the results.
128 *
129 * If this is called with a sensor not in the group,
130 * it will be considered trusted.
131 *
132 * @param[in] sensor - TachSensor object
133 *
134 * @return tuple<bool, bool> -
135 * field 0 - the trust value
136 * field 1 - if that trust value changed since last call
137 * to checkTrust
138 */
139 auto checkTrust(const monitor::TachSensor& sensor)
140 {
141 if (inGroup(sensor))
Matt Spinler78689dd2017-09-28 10:12:07 -0500142 {
Matthew Barth177fe982020-05-26 11:05:19 -0500143 auto trust = checkGroupTrust();
144
145 setTrust(trust);
146
147 return std::tuple<bool, bool>(_trusted, _stateChange);
Matt Spinler78689dd2017-09-28 10:12:07 -0500148 }
Matthew Barth177fe982020-05-26 11:05:19 -0500149 return std::tuple<bool, bool>(true, false);
150 }
Matt Spinler78689dd2017-09-28 10:12:07 -0500151
Matthew Barth177fe982020-05-26 11:05:19 -0500152 /**
153 * Says if all sensors in the group are currently trusted,
154 * as determined by the last call to checkTrust().
155 *
156 * @return bool - if the group's sensors are trusted or not
157 */
158 inline auto getTrust() const
159 {
160 return _trusted;
161 }
Matt Spinler78689dd2017-09-28 10:12:07 -0500162
Matthew Barth177fe982020-05-26 11:05:19 -0500163 /**
164 * Says if the trust value changed in the last call to
165 * checkTrust()
166 *
167 * @return bool - if the trust changed or not
168 */
169 inline auto trustChanged() const
170 {
171 return _stateChange;
172 }
Matt Spinler78689dd2017-09-28 10:12:07 -0500173
Matthew Barth177fe982020-05-26 11:05:19 -0500174 protected:
175 /**
176 * The sensor objects and their trust inclusion in the group.
177 *
178 * Added by registerSensor().
179 */
180 std::vector<GroupSensor> _sensors;
Matt Spinler78689dd2017-09-28 10:12:07 -0500181
Matthew Barth177fe982020-05-26 11:05:19 -0500182 private:
183 /**
184 * Checks if the group's sensors are trusted.
185 *
186 * The derived class must override this function
187 * to provide custom functionality.
188 *
189 * @return bool - if group is trusted or not
190 */
191 virtual bool checkGroupTrust() = 0;
Matt Spinler78689dd2017-09-28 10:12:07 -0500192
Matthew Barth177fe982020-05-26 11:05:19 -0500193 /**
194 * Sets the trust value on the object.
195 *
196 * @param[in] trust - the new trust value
197 */
198 inline void setTrust(bool trust)
199 {
200 _stateChange = (trust != _trusted);
201 _trusted = trust;
202 }
Matt Spinler78689dd2017-09-28 10:12:07 -0500203
Matthew Barth177fe982020-05-26 11:05:19 -0500204 /**
205 * The current trust state of the group
206 */
207 bool _trusted = true;
Matt Spinler78689dd2017-09-28 10:12:07 -0500208
Matthew Barth177fe982020-05-26 11:05:19 -0500209 /**
210 * If the trust value changed in the last call to checkTrust
211 */
212 bool _stateChange = false;
Matt Spinler78689dd2017-09-28 10:12:07 -0500213
Matthew Barth177fe982020-05-26 11:05:19 -0500214 /**
215 * The names of the sensors and whether it is included in
216 * determining trust for this group
217 */
218 const std::vector<GroupDefinition> _names;
Matthew Barthfcb0dbc2021-02-10 14:23:39 -0600219}; // namespace trust
Matt Spinler78689dd2017-09-28 10:12:07 -0500220
Matthew Barth177fe982020-05-26 11:05:19 -0500221} // namespace trust
222} // namespace fan
223} // namespace phosphor