blob: f2ffd3f111441fcfb8d8b16f63a04ce7afe839f7 [file] [log] [blame]
Patrick Venturee6206562018-03-08 15:36:53 -08001#pragma once
2
James Feist0c8223b2019-05-08 15:33:33 -07003#include "pid/ec/pid.hpp"
4
James Feist5ec20272019-07-10 11:59:57 -07005#include <phosphor-logging/log.hpp>
James Feist0c8223b2019-05-08 15:33:33 -07006#include <sdbusplus/bus.hpp>
Patrick Venturea83a3ec2020-08-04 09:52:05 -07007
8#include <limits>
Patrick Ventureda064282018-06-12 19:33:47 -07009#include <string>
10
Patrick Venturea0764872020-08-08 07:48:43 -070011namespace pid_control
12{
13
Yong Li298a95c2020-04-07 15:11:02 +080014void tryRestartControlLoops(void);
James Feist1fe08952019-05-07 09:17:16 -070015
James Feist0c8223b2019-05-08 15:33:33 -070016/*
17 * Given a configuration structure, fill out the information we use within the
18 * PID loop.
19 */
20void initializePIDStruct(ec::pid_info_t* info, const ec::pidinfo& initial);
21
22void dumpPIDStruct(ec::pid_info_t* info);
23
24struct SensorProperties
25{
26 int64_t scale;
27 double value;
28 double min;
29 double max;
30 std::string unit;
31};
32
33struct SensorThresholds
34{
35 double lowerThreshold = std::numeric_limits<double>::quiet_NaN();
36 double upperThreshold = std::numeric_limits<double>::quiet_NaN();
37};
38
39const std::string sensorintf = "xyz.openbmc_project.Sensor.Value";
40const std::string criticalThreshInf =
41 "xyz.openbmc_project.Sensor.Threshold.Critical";
42const std::string propertiesintf = "org.freedesktop.DBus.Properties";
43
44class DbusHelperInterface
45{
46 public:
47 virtual ~DbusHelperInterface() = default;
48
49 /** @brief Get the service providing the interface for the path.
50 *
51 * @warning Throws exception on dbus failure.
52 */
53 virtual std::string getService(sdbusplus::bus::bus& bus,
54 const std::string& intf,
55 const std::string& path) = 0;
56
57 /** @brief Get all Sensor.Value properties for a service and path.
58 *
59 * @param[in] bus - A bus to use for the call.
60 * @param[in] service - The service providing the interface.
61 * @param[in] path - The dbus path.
62 * @param[out] prop - A pointer to a properties struct to fill out.
63 *
64 * @warning Throws exception on dbus failure.
65 */
66 virtual void getProperties(sdbusplus::bus::bus& bus,
67 const std::string& service,
68 const std::string& path,
69 struct SensorProperties* prop) = 0;
70
71 /** @brief Get Critical Threshold current assert status
72 *
73 * @param[in] bus - A bus to use for the call.
74 * @param[in] service - The service providing the interface.
75 * @param[in] path - The dbus path.
76 */
77 virtual bool thresholdsAsserted(sdbusplus::bus::bus& bus,
78 const std::string& service,
79 const std::string& path) = 0;
80};
81
82class DbusHelper : public DbusHelperInterface
83{
84 public:
85 DbusHelper() = default;
86 ~DbusHelper() = default;
87 DbusHelper(const DbusHelper&) = default;
88 DbusHelper& operator=(const DbusHelper&) = default;
89 DbusHelper(DbusHelper&&) = default;
90 DbusHelper& operator=(DbusHelper&&) = default;
91
92 std::string getService(sdbusplus::bus::bus& bus, const std::string& intf,
93 const std::string& path) override;
94
95 void getProperties(sdbusplus::bus::bus& bus, const std::string& service,
96 const std::string& path,
97 struct SensorProperties* prop) override;
98
99 bool thresholdsAsserted(sdbusplus::bus::bus& bus,
100 const std::string& service,
101 const std::string& path) override;
James Feist5ec20272019-07-10 11:59:57 -0700102
103 template <typename T>
104 void getProperty(sdbusplus::bus::bus& bus, const std::string& service,
105 const std::string& path, const std::string& interface,
106 const std::string& propertyName, T& prop)
107 {
108 namespace log = phosphor::logging;
109
110 auto msg = bus.new_method_call(service.c_str(), path.c_str(),
111 propertiesintf.c_str(), "Get");
112
113 msg.append(interface, propertyName);
114
115 std::variant<T> result;
116 try
117 {
118 auto valueResponseMsg = bus.call(msg);
119 valueResponseMsg.read(result);
120 }
121 catch (const sdbusplus::exception::SdBusError& ex)
122 {
123 log::log<log::level::ERR>("Get Property Failed",
124 log::entry("WHAT=%s", ex.what()));
125 throw;
126 }
127
128 prop = std::get<T>(result);
129 }
James Feist0c8223b2019-05-08 15:33:33 -0700130};
131
132std::string getSensorPath(const std::string& type, const std::string& id);
133std::string getMatch(const std::string& type, const std::string& id);
134void scaleSensorReading(const double min, const double max, double& value);
135bool validType(const std::string& type);
136
137struct VariantToDoubleVisitor
138{
139 template <typename T>
140 std::enable_if_t<std::is_arithmetic<T>::value, double>
141 operator()(const T& t) const
142 {
143 return static_cast<double>(t);
144 }
145
146 template <typename T>
147 std::enable_if_t<!std::is_arithmetic<T>::value, double>
148 operator()(const T& t) const
149 {
150 throw std::invalid_argument("Cannot translate type to double");
151 }
152};
153
154/*
155 * Given a path that optionally has a glob portion, fill it out.
156 */
157std::string FixupPath(std::string original);
Patrick Venturea0764872020-08-08 07:48:43 -0700158
159} // namespace pid_control