1abf8da36SMatt Spinler #pragma once 2abf8da36SMatt Spinler 3b0412d07SMatt Spinler #include "config.h" 4b0412d07SMatt Spinler 5abf8da36SMatt Spinler #include "tach_sensor.hpp" 6c39e859bSMatt Spinler #include "trust_manager.hpp" 7abf8da36SMatt Spinler #include "types.hpp" 8abf8da36SMatt Spinler 9177fe986SMatthew Barth #include <sdbusplus/bus.hpp> 10177fe986SMatthew Barth #include <sdeventplus/event.hpp> 11177fe986SMatthew Barth 12177fe986SMatthew Barth #include <tuple> 13177fe986SMatthew Barth #include <vector> 14177fe986SMatthew Barth 15abf8da36SMatt Spinler namespace phosphor 16abf8da36SMatt Spinler { 17abf8da36SMatt Spinler namespace fan 18abf8da36SMatt Spinler { 19abf8da36SMatt Spinler namespace monitor 20abf8da36SMatt Spinler { 21abf8da36SMatt Spinler 22b0412d07SMatt Spinler class System; 23b0412d07SMatt Spinler 24edaeb31cSBrad Bishop /** 25edaeb31cSBrad Bishop * @class InvalidSensorError 26edaeb31cSBrad Bishop * 27edaeb31cSBrad Bishop * An exception type for sensors that don't exist or 28edaeb31cSBrad Bishop * are otherwise inaccessible. 29edaeb31cSBrad Bishop */ 30177fe986SMatthew Barth class InvalidSensorError : public std::exception 31177fe986SMatthew Barth {}; 32abf8da36SMatt Spinler 33abf8da36SMatt Spinler /** 34abf8da36SMatt Spinler * @class Fan 35abf8da36SMatt Spinler * 36abf8da36SMatt Spinler * Represents a fan, which can contain 1 or more sensors which 37abf8da36SMatt Spinler * loosely correspond to rotors. See below. 38abf8da36SMatt Spinler * 39abf8da36SMatt Spinler * There is a sensor when hwmon exposes one, which means there is a 40abf8da36SMatt Spinler * speed value to be read. Sometimes there is a sensor per rotor, 41abf8da36SMatt Spinler * and other times multiple rotors just use 1 sensor total where 42abf8da36SMatt Spinler * the sensor reports the slowest speed of all of the rotors. 43abf8da36SMatt Spinler * 44abf8da36SMatt Spinler * A rotor's speed is set by writing the Target value of a sensor. 45abf8da36SMatt Spinler * Sometimes each sensor in a fan supports having a Target, and other 46abf8da36SMatt Spinler * times not all of them do. A TachSensor object knows if it supports 47abf8da36SMatt Spinler * the Target property. 48abf8da36SMatt Spinler * 49abf8da36SMatt Spinler * The strategy for monitoring fan speeds is as follows: 50abf8da36SMatt Spinler * 51abf8da36SMatt Spinler * Every time a Target (new speed written) or Input (actual speed read) 52abf8da36SMatt Spinler * sensor changes, check if the input value is within some range of the target 53abf8da36SMatt Spinler * value. If it isn't, start a timer at the end of which the sensor will be 54abf8da36SMatt Spinler * set to not functional. If enough sensors in the fan are now nonfunctional, 55abf8da36SMatt Spinler * set the whole fan to nonfunctional in the inventory. 56abf8da36SMatt Spinler * 57abf8da36SMatt Spinler * When sensor inputs come back within a specified range of the target, 58abf8da36SMatt Spinler * stop its timer if running, make the sensor functional again if it wasn't, 59abf8da36SMatt Spinler * and if enough sensors in the fan are now functional set the whole fan 60abf8da36SMatt Spinler * back to functional in the inventory. 61abf8da36SMatt Spinler */ 62abf8da36SMatt Spinler class Fan 63abf8da36SMatt Spinler { 64b1e18514SMatt Spinler using Property = std::string; 65c21d0b36SPatrick Williams using Value = std::variant<bool>; 66b1e18514SMatt Spinler using PropertyMap = std::map<Property, Value>; 67b1e18514SMatt Spinler 68b1e18514SMatt Spinler using Interface = std::string; 69b1e18514SMatt Spinler using InterfaceMap = std::map<Interface, PropertyMap>; 70b1e18514SMatt Spinler 71b1e18514SMatt Spinler using Object = sdbusplus::message::object_path; 72b1e18514SMatt Spinler using ObjectMap = std::map<Object, InterfaceMap>; 73abf8da36SMatt Spinler 74abf8da36SMatt Spinler public: 75abf8da36SMatt Spinler Fan() = delete; 76abf8da36SMatt Spinler Fan(const Fan&) = delete; 77abf8da36SMatt Spinler Fan(Fan&&) = default; 78abf8da36SMatt Spinler Fan& operator=(const Fan&) = delete; 79abf8da36SMatt Spinler Fan& operator=(Fan&&) = default; 80abf8da36SMatt Spinler ~Fan() = default; 81abf8da36SMatt Spinler 82abf8da36SMatt Spinler /** 83abf8da36SMatt Spinler * @brief Constructor 84abf8da36SMatt Spinler * 856ad28430SMatthew Barth * @param mode - mode of fan monitor 86abf8da36SMatt Spinler * @param bus - the dbus object 871cfc2f11SWilliam A. Kennington III * @param event - event loop reference 88c39e859bSMatt Spinler * @param trust - the tach trust manager 89abf8da36SMatt Spinler * @param def - the fan definition structure 90b0412d07SMatt Spinler * @param system - Reference to the system object 91abf8da36SMatt Spinler */ 92177fe986SMatthew Barth Fan(Mode mode, sdbusplus::bus::bus& bus, const sdeventplus::Event& event, 93b0412d07SMatt Spinler std::unique_ptr<trust::Manager>& trust, const FanDefinition& def, 94b0412d07SMatt Spinler System& system); 95abf8da36SMatt Spinler 96ebaae611SMatt Spinler /** 97ebaae611SMatt Spinler * @brief Callback function for when an input sensor changes 98ebaae611SMatt Spinler * 99ebaae611SMatt Spinler * Starts a timer, where if it expires then the sensor 100a9406a77SMatt Spinler * was out of range for too long and can be considered not functional. 101ebaae611SMatt Spinler */ 102ebaae611SMatt Spinler void tachChanged(TachSensor& sensor); 103ebaae611SMatt Spinler 104ebaae611SMatt Spinler /** 105ebaae611SMatt Spinler * @brief Calls tachChanged(sensor) on each sensor 106ebaae611SMatt Spinler */ 107ebaae611SMatt Spinler void tachChanged(); 108abf8da36SMatt Spinler 109a9406a77SMatt Spinler /** 11069f2f48eSJolie Ku * @brief The callback function for the method 111a9406a77SMatt Spinler * 112a9406a77SMatt Spinler * Sets the sensor to not functional. 113a9406a77SMatt Spinler * If enough sensors are now not functional, 114a9406a77SMatt Spinler * updates the functional status of the whole 115a9406a77SMatt Spinler * fan in the inventory. 116a9406a77SMatt Spinler * 11769f2f48eSJolie Ku * @param[in] sensor - the sensor for state update 118a9406a77SMatt Spinler */ 11969f2f48eSJolie Ku void updateState(TachSensor& sensor); 120a9406a77SMatt Spinler 1214d982856SMatthew Barth /** 1224d982856SMatthew Barth * @brief Get the name of the fan 1234d982856SMatthew Barth * 1244d982856SMatthew Barth * @return - The fan name 1254d982856SMatthew Barth */ 1264d982856SMatthew Barth inline const std::string& getName() const 1274d982856SMatthew Barth { 1284d982856SMatthew Barth return _name; 1294d982856SMatthew Barth } 1304d982856SMatthew Barth 131f552ea5cSMatthew Barth /** 132f552ea5cSMatthew Barth * @brief Finds the target speed of this fan 133f552ea5cSMatthew Barth * 134f552ea5cSMatthew Barth * Finds the target speed from the list of sensors that make up this 135f552ea5cSMatthew Barth * fan. At least one sensor should contain a target speed value. 136f552ea5cSMatthew Barth * 137f552ea5cSMatthew Barth * @return - The target speed found from the list of sensors on the fan 138f552ea5cSMatthew Barth */ 139f552ea5cSMatthew Barth uint64_t findTargetSpeed(); 140f552ea5cSMatthew Barth 141b63aa09eSMatt Spinler /** 142b63aa09eSMatt Spinler * @brief Returns the contained TachSensor objects 143b63aa09eSMatt Spinler * 144b63aa09eSMatt Spinler * @return std::vector<std::shared_ptr<TachSensor>> - The sensors 145b63aa09eSMatt Spinler */ 146b63aa09eSMatt Spinler const std::vector<std::shared_ptr<TachSensor>>& sensors() const 147b63aa09eSMatt Spinler { 148b63aa09eSMatt Spinler return _sensors; 149b63aa09eSMatt Spinler } 150b63aa09eSMatt Spinler 151b63aa09eSMatt Spinler /** 152b63aa09eSMatt Spinler * @brief Returns the presence status of the fan 153b63aa09eSMatt Spinler * 154b63aa09eSMatt Spinler * @return bool - If the fan is present or not 155b63aa09eSMatt Spinler */ 156b63aa09eSMatt Spinler bool present() const 157b63aa09eSMatt Spinler { 158b63aa09eSMatt Spinler return _present; 159b63aa09eSMatt Spinler } 160b63aa09eSMatt Spinler 161f13b42e2SMatt Spinler /** 162f13b42e2SMatt Spinler * @brief Called from TachSensor when its error timer expires 163f13b42e2SMatt Spinler * so an event log calling out the fan can be created. 164f13b42e2SMatt Spinler * 165f13b42e2SMatt Spinler * @param[in] sensor - The nonfunctional sensor 166f13b42e2SMatt Spinler */ 167f13b42e2SMatt Spinler void sensorErrorTimerExpired(const TachSensor& sensor); 168f13b42e2SMatt Spinler 169*fcb0dbcbSMatthew Barth /** 170*fcb0dbcbSMatthew Barth * @brief Process the state of the given tach sensor without checking 171*fcb0dbcbSMatthew Barth * any trust groups the sensor may be included in 172*fcb0dbcbSMatthew Barth * 173*fcb0dbcbSMatthew Barth * @param[in] sensor - Tach sensor to process 174*fcb0dbcbSMatthew Barth * 175*fcb0dbcbSMatthew Barth * This function is intended to check the current state of a tach sensor 176*fcb0dbcbSMatthew Barth * regardless of whether or not the tach sensor is configured to be in any 177*fcb0dbcbSMatthew Barth * trust groups. 178*fcb0dbcbSMatthew Barth */ 179*fcb0dbcbSMatthew Barth void process(TachSensor& sensor); 180*fcb0dbcbSMatthew Barth 181abf8da36SMatt Spinler private: 182abf8da36SMatt Spinler /** 183abf8da36SMatt Spinler * @brief Returns true if the sensor input is not within 184abf8da36SMatt Spinler * some deviation of the target. 185abf8da36SMatt Spinler * 186abf8da36SMatt Spinler * @param[in] sensor - the sensor to check 187abf8da36SMatt Spinler */ 188abf8da36SMatt Spinler bool outOfRange(const TachSensor& sensor); 189abf8da36SMatt Spinler 190abf8da36SMatt Spinler /** 1917c23a049SMatthew Barth * @brief Returns the number sensors that are nonfunctional 192abf8da36SMatt Spinler */ 1937c23a049SMatthew Barth size_t countNonFunctionalSensors(); 194abf8da36SMatt Spinler 195b1e18514SMatt Spinler /** 196b1e18514SMatt Spinler * @brief Updates the Functional property in the inventory 197b1e18514SMatt Spinler * for the fan based on the value passed in. 198b1e18514SMatt Spinler * 199b1e18514SMatt Spinler * @param[in] functional - If the Functional property should 200b1e18514SMatt Spinler * be set to true or false. 201b1e18514SMatt Spinler */ 202b1e18514SMatt Spinler void updateInventory(bool functional); 203b1e18514SMatt Spinler 204b1e18514SMatt Spinler /** 205b0412d07SMatt Spinler * @brief Called by _monitorTimer to start fan monitoring some 206b0412d07SMatt Spinler * amount of time after startup. 207b0412d07SMatt Spinler */ 208b0412d07SMatt Spinler void startMonitor(); 209b0412d07SMatt Spinler 210b0412d07SMatt Spinler /** 211b63aa09eSMatt Spinler * @brief Called when the fan presence property changes on D-Bus 212b63aa09eSMatt Spinler * 213b63aa09eSMatt Spinler * @param[in] msg - The message from the propertiesChanged signal 214b63aa09eSMatt Spinler */ 215b63aa09eSMatt Spinler void presenceChanged(sdbusplus::message::message& msg); 216b63aa09eSMatt Spinler 217b63aa09eSMatt Spinler /** 218abf8da36SMatt Spinler * @brief the dbus object 219abf8da36SMatt Spinler */ 220abf8da36SMatt Spinler sdbusplus::bus::bus& _bus; 221abf8da36SMatt Spinler 222abf8da36SMatt Spinler /** 223abf8da36SMatt Spinler * @brief The inventory name of the fan 224abf8da36SMatt Spinler */ 225abf8da36SMatt Spinler const std::string _name; 226abf8da36SMatt Spinler 227abf8da36SMatt Spinler /** 228abf8da36SMatt Spinler * @brief The percentage that the input speed must be below 229abf8da36SMatt Spinler * the target speed to be considered an error. 230abf8da36SMatt Spinler * Between 0 and 100. 231abf8da36SMatt Spinler */ 232abf8da36SMatt Spinler const size_t _deviation; 233abf8da36SMatt Spinler 234abf8da36SMatt Spinler /** 235abf8da36SMatt Spinler * The number of sensors that must be nonfunctional at the 236abf8da36SMatt Spinler * same time in order for the fan to be set to nonfunctional 237abf8da36SMatt Spinler * in the inventory. 238abf8da36SMatt Spinler */ 239abf8da36SMatt Spinler const size_t _numSensorFailsForNonFunc; 240abf8da36SMatt Spinler 241abf8da36SMatt Spinler /** 2425d564a9fSJolie Ku * The number of failed sensors 2435d564a9fSJolie Ku */ 2445d564a9fSJolie Ku size_t _numFailedSensor = 0; 2455d564a9fSJolie Ku 2465d564a9fSJolie Ku /** 247abf8da36SMatt Spinler * @brief The current functional state of the fan 248abf8da36SMatt Spinler */ 249abf8da36SMatt Spinler bool _functional = true; 250abf8da36SMatt Spinler 251abf8da36SMatt Spinler /** 252abf8da36SMatt Spinler * The sensor objects for the fan 253abf8da36SMatt Spinler */ 25432affb98SMatthew Barth std::vector<std::shared_ptr<TachSensor>> _sensors; 255c39e859bSMatt Spinler 256c39e859bSMatt Spinler /** 257c39e859bSMatt Spinler * The tach trust manager object 258c39e859bSMatt Spinler */ 259c39e859bSMatt Spinler std::unique_ptr<trust::Manager>& _trustManager; 260b0412d07SMatt Spinler 261b0412d07SMatt Spinler #ifdef MONITOR_USE_JSON 262b0412d07SMatt Spinler /** 263b0412d07SMatt Spinler * @brief The number of seconds to wait after startup until 264b0412d07SMatt Spinler * fan sensors should checked against their targets. 265b0412d07SMatt Spinler */ 266b0412d07SMatt Spinler size_t _monitorDelay; 267b0412d07SMatt Spinler 268b0412d07SMatt Spinler /** 269b0412d07SMatt Spinler * @brief Expires after _monitorDelay to start fan monitoring. 270b0412d07SMatt Spinler */ 271b0412d07SMatt Spinler sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _monitorTimer; 272b0412d07SMatt Spinler #endif 273b0412d07SMatt Spinler 274b0412d07SMatt Spinler /** 275b0412d07SMatt Spinler * @brief Set to true when monitoring can start. 276b0412d07SMatt Spinler */ 277b0412d07SMatt Spinler bool _monitorReady = false; 278b0412d07SMatt Spinler 279b0412d07SMatt Spinler /** 280b0412d07SMatt Spinler * @brief Reference to the System object 281b0412d07SMatt Spinler */ 282b0412d07SMatt Spinler System& _system; 283b63aa09eSMatt Spinler 284b63aa09eSMatt Spinler /** 285b63aa09eSMatt Spinler * @brief The match object for propertiesChanged signals 286b63aa09eSMatt Spinler * for the inventory item interface to track the 287b63aa09eSMatt Spinler * Present property. 288b63aa09eSMatt Spinler */ 289b63aa09eSMatt Spinler sdbusplus::bus::match::match _presenceMatch; 290b63aa09eSMatt Spinler 291b63aa09eSMatt Spinler /** 292b63aa09eSMatt Spinler * @brief The current presence state 293b63aa09eSMatt Spinler */ 294b63aa09eSMatt Spinler bool _present = false; 29527f6b686SMatt Spinler 29627f6b686SMatt Spinler /** 29727f6b686SMatt Spinler * @brief The number of seconds to wait after a fan is removed before 29827f6b686SMatt Spinler * creating an event log for it. If std::nullopt, then no 29927f6b686SMatt Spinler * event log will be created. 30027f6b686SMatt Spinler */ 30127f6b686SMatt Spinler const std::optional<size_t> _fanMissingErrorDelay; 30227f6b686SMatt Spinler 30327f6b686SMatt Spinler /** 30427f6b686SMatt Spinler * @brief The timer that uses the _fanMissingErrorDelay timeout, 30527f6b686SMatt Spinler * at the end of which an event log will be created. 30627f6b686SMatt Spinler */ 30727f6b686SMatt Spinler std::unique_ptr< 30827f6b686SMatt Spinler sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>> 30927f6b686SMatt Spinler _fanMissingErrorTimer; 310abf8da36SMatt Spinler }; 311abf8da36SMatt Spinler 312177fe986SMatthew Barth } // namespace monitor 313177fe986SMatthew Barth } // namespace fan 314177fe986SMatthew Barth } // namespace phosphor 315