xref: /openbmc/phosphor-pid-control/pid/zone.hpp (revision a076487aab0ee71ea32d53f798d5ca6b31677278)
1 #pragma once
2 
3 #include "conf.hpp"
4 #include "controller.hpp"
5 #include "pidcontroller.hpp"
6 #include "sensors/manager.hpp"
7 #include "sensors/sensor.hpp"
8 #include "tuning.hpp"
9 
10 #include <sdbusplus/bus.hpp>
11 #include <sdbusplus/server.hpp>
12 #include <xyz/openbmc_project/Control/Mode/server.hpp>
13 
14 #include <fstream>
15 #include <map>
16 #include <memory>
17 #include <set>
18 #include <string>
19 #include <vector>
20 
21 template <typename... T>
22 using ServerObject = typename sdbusplus::server::object::object<T...>;
23 using ModeInterface = sdbusplus::xyz::openbmc_project::Control::server::Mode;
24 using ModeObject = ServerObject<ModeInterface>;
25 
26 namespace pid_control
27 {
28 
29 class ZoneInterface
30 {
31   public:
32     virtual ~ZoneInterface() = default;
33 
34     virtual double getCachedValue(const std::string& name) = 0;
35     virtual void addSetPoint(double setpoint) = 0;
36     virtual void addRPMCeiling(double ceiling) = 0;
37     virtual double getMaxSetPointRequest() const = 0;
38     virtual bool getFailSafeMode() const = 0;
39     virtual double getFailSafePercent() const = 0;
40     virtual Sensor* getSensor(const std::string& name) = 0;
41 };
42 
43 /*
44  * The PIDZone inherits from the Mode object so that it can listen for control
45  * mode changes.  It primarily holds all PID loops and holds the sensor value
46  * cache that's used per iteration of the PID loops.
47  */
48 class PIDZone : public ZoneInterface, public ModeObject
49 {
50   public:
51     PIDZone(int64_t zone, double minThermalOutput, double failSafePercent,
52             const SensorManager& mgr, sdbusplus::bus::bus& bus,
53             const char* objPath, bool defer) :
54         ModeObject(bus, objPath, defer),
55         _zoneId(zone), _maximumSetPoint(),
56         _minThermalOutputSetPt(minThermalOutput),
57         _failSafePercent(failSafePercent), _mgr(mgr)
58     {
59         if (loggingEnabled)
60         {
61             _log.open(loggingPath + "/zone_" + std::to_string(zone) + ".log");
62         }
63     }
64 
65     double getMaxSetPointRequest(void) const override;
66     bool getManualMode(void) const;
67 
68     /* Could put lock around this since it's accessed from two threads, but
69      * only one reader/one writer.
70      */
71     void setManualMode(bool mode);
72     bool getFailSafeMode(void) const override;
73     int64_t getZoneID(void) const;
74     void addSetPoint(double setpoint) override;
75     void addRPMCeiling(double ceiling) override;
76     void clearSetPoints(void);
77     void clearRPMCeilings(void);
78     double getFailSafePercent(void) const override;
79     double getMinThermalSetpoint(void) const;
80 
81     Sensor* getSensor(const std::string& name) override;
82     void determineMaxSetPointRequest(void);
83     void updateFanTelemetry(void);
84     void updateSensors(void);
85     void initializeCache(void);
86     void dumpCache(void);
87     void processFans(void);
88     void processThermals(void);
89 
90     void addFanPID(std::unique_ptr<Controller> pid);
91     void addThermalPID(std::unique_ptr<Controller> pid);
92     double getCachedValue(const std::string& name) override;
93     void addFanInput(const std::string& fan);
94     void addThermalInput(const std::string& therm);
95 
96     void initializeLog(void);
97     std::ofstream& getLogHandle(void);
98 
99     /* Method for setting the manual mode over dbus */
100     bool manual(bool value) override;
101     /* Method for reading whether in fail-safe mode over dbus */
102     bool failSafe() const override;
103 
104   private:
105     std::ofstream _log;
106 
107     const int64_t _zoneId;
108     double _maximumSetPoint = 0;
109     bool _manualMode = false;
110     const double _minThermalOutputSetPt;
111     const double _failSafePercent;
112 
113     std::set<std::string> _failSafeSensors;
114 
115     std::vector<double> _SetPoints;
116     std::vector<double> _RPMCeilings;
117     std::vector<std::string> _fanInputs;
118     std::vector<std::string> _thermalInputs;
119     std::map<std::string, double> _cachedValuesByName;
120     const SensorManager& _mgr;
121 
122     std::vector<std::unique_ptr<Controller>> _fans;
123     std::vector<std::unique_ptr<Controller>> _thermals;
124 };
125 
126 } // namespace pid_control
127