xref: /openbmc/phosphor-pid-control/util.hpp (revision 0c8223b5)
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 /*
33  * Given a configuration structure, fill out the information we use within the
34  * PID loop.
35  */
36 void initializePIDStruct(ec::pid_info_t* info, const ec::pidinfo& initial);
37 
38 void dumpPIDStruct(ec::pid_info_t* info);
39 
40 struct SensorProperties
41 {
42     int64_t scale;
43     double value;
44     double min;
45     double max;
46     std::string unit;
47 };
48 
49 struct SensorThresholds
50 {
51     double lowerThreshold = std::numeric_limits<double>::quiet_NaN();
52     double upperThreshold = std::numeric_limits<double>::quiet_NaN();
53 };
54 
55 const std::string sensorintf = "xyz.openbmc_project.Sensor.Value";
56 const std::string criticalThreshInf =
57     "xyz.openbmc_project.Sensor.Threshold.Critical";
58 const std::string propertiesintf = "org.freedesktop.DBus.Properties";
59 
60 class DbusHelperInterface
61 {
62   public:
63     virtual ~DbusHelperInterface() = default;
64 
65     /** @brief Get the service providing the interface for the path.
66      *
67      * @warning Throws exception on dbus failure.
68      */
69     virtual std::string getService(sdbusplus::bus::bus& bus,
70                                    const std::string& intf,
71                                    const std::string& path) = 0;
72 
73     /** @brief Get all Sensor.Value properties for a service and path.
74      *
75      * @param[in] bus - A bus to use for the call.
76      * @param[in] service - The service providing the interface.
77      * @param[in] path - The dbus path.
78      * @param[out] prop - A pointer to a properties struct to fill out.
79      *
80      * @warning Throws exception on dbus failure.
81      */
82     virtual void getProperties(sdbusplus::bus::bus& bus,
83                                const std::string& service,
84                                const std::string& path,
85                                struct SensorProperties* prop) = 0;
86 
87     /** @brief Get Critical Threshold current assert status
88      *
89      * @param[in] bus - A bus to use for the call.
90      * @param[in] service - The service providing the interface.
91      * @param[in] path - The dbus path.
92      */
93     virtual bool thresholdsAsserted(sdbusplus::bus::bus& bus,
94                                     const std::string& service,
95                                     const std::string& path) = 0;
96 };
97 
98 class DbusHelper : public DbusHelperInterface
99 {
100   public:
101     DbusHelper() = default;
102     ~DbusHelper() = default;
103     DbusHelper(const DbusHelper&) = default;
104     DbusHelper& operator=(const DbusHelper&) = default;
105     DbusHelper(DbusHelper&&) = default;
106     DbusHelper& operator=(DbusHelper&&) = default;
107 
108     std::string getService(sdbusplus::bus::bus& bus, const std::string& intf,
109                            const std::string& path) override;
110 
111     void getProperties(sdbusplus::bus::bus& bus, const std::string& service,
112                        const std::string& path,
113                        struct SensorProperties* prop) override;
114 
115     bool thresholdsAsserted(sdbusplus::bus::bus& bus,
116                             const std::string& service,
117                             const std::string& path) override;
118 };
119 
120 std::string getSensorPath(const std::string& type, const std::string& id);
121 std::string getMatch(const std::string& type, const std::string& id);
122 void scaleSensorReading(const double min, const double max, double& value);
123 bool validType(const std::string& type);
124 
125 struct VariantToDoubleVisitor
126 {
127     template <typename T>
128     std::enable_if_t<std::is_arithmetic<T>::value, double>
129         operator()(const T& t) const
130     {
131         return static_cast<double>(t);
132     }
133 
134     template <typename T>
135     std::enable_if_t<!std::is_arithmetic<T>::value, double>
136         operator()(const T& t) const
137     {
138         throw std::invalid_argument("Cannot translate type to double");
139     }
140 };
141 
142 /*
143  * Given a path that optionally has a glob portion, fill it out.
144  */
145 std::string FixupPath(std::string original);
146