xref: /openbmc/phosphor-pid-control/util.hpp (revision 1fe08952)
1 #pragma once
2 
3 #include "pid/ec/pid.hpp"
4 
5 #include <limits>
6 #include <sdbusplus/bus.hpp>
7 #include <string>
8 
9 /* This program assumes sensors use the Sensor.Value interface
10  * and for sensor->write() I only implemented sysfs as a type,
11  * but -- how would it know whether to use Control.FanSpeed or Control.FanPwm?
12  *
13  * One could get the interface list for the object and search for Control.*
14  * but, it needs to know the maximum, minimum.  The only sensors it wants to
15  * write in this code base are Fans...
16  */
17 enum class IOInterfaceType
18 {
19     NONE, // There is no interface.
20     EXTERNAL,
21     DBUSPASSIVE,
22     DBUSACTIVE, // This means for write that it needs to look up the interface.
23     SYSFS,
24     UNKNOWN
25 };
26 
27 /* WriteInterfaceType is different because Dbusactive/passive. how to know... */
28 IOInterfaceType getWriteInterfaceType(const std::string& path);
29 
30 IOInterfaceType getReadInterfaceType(const std::string& path);
31 
32 void restartControlLoops(void);
33 
34 /*
35  * Given a configuration structure, fill out the information we use within the
36  * PID loop.
37  */
38 void initializePIDStruct(ec::pid_info_t* info, const ec::pidinfo& initial);
39 
40 void dumpPIDStruct(ec::pid_info_t* info);
41 
42 struct SensorProperties
43 {
44     int64_t scale;
45     double value;
46     double min;
47     double max;
48     std::string unit;
49 };
50 
51 struct SensorThresholds
52 {
53     double lowerThreshold = std::numeric_limits<double>::quiet_NaN();
54     double upperThreshold = std::numeric_limits<double>::quiet_NaN();
55 };
56 
57 const std::string sensorintf = "xyz.openbmc_project.Sensor.Value";
58 const std::string criticalThreshInf =
59     "xyz.openbmc_project.Sensor.Threshold.Critical";
60 const std::string propertiesintf = "org.freedesktop.DBus.Properties";
61 
62 class DbusHelperInterface
63 {
64   public:
65     virtual ~DbusHelperInterface() = default;
66 
67     /** @brief Get the service providing the interface for the path.
68      *
69      * @warning Throws exception on dbus failure.
70      */
71     virtual std::string getService(sdbusplus::bus::bus& bus,
72                                    const std::string& intf,
73                                    const std::string& path) = 0;
74 
75     /** @brief Get all Sensor.Value properties for a service and path.
76      *
77      * @param[in] bus - A bus to use for the call.
78      * @param[in] service - The service providing the interface.
79      * @param[in] path - The dbus path.
80      * @param[out] prop - A pointer to a properties struct to fill out.
81      *
82      * @warning Throws exception on dbus failure.
83      */
84     virtual void getProperties(sdbusplus::bus::bus& bus,
85                                const std::string& service,
86                                const std::string& path,
87                                struct SensorProperties* prop) = 0;
88 
89     /** @brief Get Critical Threshold current assert status
90      *
91      * @param[in] bus - A bus to use for the call.
92      * @param[in] service - The service providing the interface.
93      * @param[in] path - The dbus path.
94      */
95     virtual bool thresholdsAsserted(sdbusplus::bus::bus& bus,
96                                     const std::string& service,
97                                     const std::string& path) = 0;
98 };
99 
100 class DbusHelper : public DbusHelperInterface
101 {
102   public:
103     DbusHelper() = default;
104     ~DbusHelper() = default;
105     DbusHelper(const DbusHelper&) = default;
106     DbusHelper& operator=(const DbusHelper&) = default;
107     DbusHelper(DbusHelper&&) = default;
108     DbusHelper& operator=(DbusHelper&&) = default;
109 
110     std::string getService(sdbusplus::bus::bus& bus, const std::string& intf,
111                            const std::string& path) override;
112 
113     void getProperties(sdbusplus::bus::bus& bus, const std::string& service,
114                        const std::string& path,
115                        struct SensorProperties* prop) override;
116 
117     bool thresholdsAsserted(sdbusplus::bus::bus& bus,
118                             const std::string& service,
119                             const std::string& path) override;
120 };
121 
122 std::string getSensorPath(const std::string& type, const std::string& id);
123 std::string getMatch(const std::string& type, const std::string& id);
124 void scaleSensorReading(const double min, const double max, double& value);
125 bool validType(const std::string& type);
126 
127 struct VariantToDoubleVisitor
128 {
129     template <typename T>
130     std::enable_if_t<std::is_arithmetic<T>::value, double>
131         operator()(const T& t) const
132     {
133         return static_cast<double>(t);
134     }
135 
136     template <typename T>
137     std::enable_if_t<!std::is_arithmetic<T>::value, double>
138         operator()(const T& t) const
139     {
140         throw std::invalid_argument("Cannot translate type to double");
141     }
142 };
143 
144 /*
145  * Given a path that optionally has a glob portion, fill it out.
146  */
147 std::string FixupPath(std::string original);
148