1 #include "dbusSensor.hpp"
2 #include "exprtk.hpp"
3 
4 #include <nlohmann/json.hpp>
5 #include <sdbusplus/bus.hpp>
6 #include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
7 #include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>
8 #include <xyz/openbmc_project/Sensor/Value/server.hpp>
9 
10 #include <map>
11 #include <string>
12 
13 namespace phosphor
14 {
15 namespace virtualSensor
16 {
17 
18 using Json = nlohmann::json;
19 using ValueIface = sdbusplus::xyz::openbmc_project::Sensor::server::Value;
20 
21 using CriticalInterface =
22     sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical;
23 
24 using WarningInterface =
25     sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning;
26 
27 using sensorIfaces =
28     sdbusplus::server::object::object<ValueIface, CriticalInterface,
29                                       WarningInterface>;
30 
31 class SensorParam
32 {
33   public:
34     SensorParam() = delete;
35     virtual ~SensorParam() = default;
36 
37     enum ParamType
38     {
39         constParam,
40         dbusParam
41     };
42 
43     /** @brief Constructs SensorParam (type = constParam)
44      *
45      * @param[in] value - Value of constant parameter
46      */
47     explicit SensorParam(double value) : value(value), paramType(constParam)
48     {}
49 
50     /** @brief Constructs SensorParam (type = dbusParam)
51      *
52      * @param[in] bus     - Handle to system dbus
53      * @param[in] path    - The Dbus path of sensor
54      */
55     SensorParam(sdbusplus::bus::bus& bus, std::string path) :
56         dbusSensor(std::make_unique<DbusSensor>(bus, path)),
57         paramType(dbusParam)
58     {}
59 
60     /** @brief Get sensor value property from D-bus interface */
61     double getParamValue();
62 
63   private:
64     std::unique_ptr<DbusSensor> dbusSensor = nullptr;
65     double value = 0;
66     ParamType paramType;
67 };
68 
69 class VirtualSensor : public sensorIfaces
70 {
71   public:
72     VirtualSensor() = delete;
73     virtual ~VirtualSensor() = default;
74 
75     /** @brief Constructs VirtualSensor
76      *
77      * @param[in] bus          - Handle to system dbus
78      * @param[in] objPath      - The Dbus path of sensor
79      * @param[in] sensorConfig - Json object for sensor config
80      */
81     VirtualSensor(sdbusplus::bus::bus& bus, const char* objPath,
82                   const Json& sensorConfig) :
83         sensorIfaces(bus, objPath),
84         bus(bus)
85     {
86         initVirtualSensor(sensorConfig);
87     }
88 
89     struct Threshold
90     {
91         double criticalHigh;
92         double criticalLow;
93         double warningHigh;
94         double warningLow;
95     };
96 
97     /** @brief Set sensor value */
98     void setSensorValue(double value);
99     /** @brief Update sensor at regular intrval */
100     void updateVirtualSensor();
101 
102     /** @brief Map of list of parameters */
103     using ParamMap =
104         std::unordered_map<std::string, std::unique_ptr<SensorParam>>;
105     ParamMap paramMap;
106 
107   private:
108     /** @brief sdbusplus bus client connection. */
109     sdbusplus::bus::bus& bus;
110     /** @brief Expression string for virtual sensor value calculations */
111     std::string exprStr;
112     /** @brief Sensor Threshold config values */
113     struct Threshold sensorThreshold;
114     /** @brief symbol table from exprtk */
115     exprtk::symbol_table<double> symbols{};
116     /** @brief expression from exprtk to calculate sensor value */
117     exprtk::expression<double> expression{};
118 
119     /** @brief Read config from json object and initialize sensor data
120      * for each virtual sensor
121      */
122     void initVirtualSensor(const Json& sensorConfig);
123     /** @brief Set Sensor Threshold to D-bus at beginning */
124     void setSensorThreshold();
125 };
126 
127 class VirtualSensors
128 {
129   public:
130     VirtualSensors() = delete;
131     virtual ~VirtualSensors() = default;
132 
133     /** @brief Constructs VirtualSensors
134      *
135      * @param[in] bus     - Handle to system dbus
136      */
137     explicit VirtualSensors(sdbusplus::bus::bus& bus) : bus(bus)
138     {
139         createVirtualSensors();
140     }
141 
142   private:
143     /** @brief sdbusplus bus client connection. */
144     sdbusplus::bus::bus& bus;
145     /** @brief Parsing virtual sensor config JSON file  */
146     Json parseConfigFile(const std::string configFile);
147 
148     /** @brief Map of the object VirtualSensor */
149     std::unordered_map<std::string, std::unique_ptr<VirtualSensor>>
150         virtualSensorsMap;
151 
152     /** @brief Create list of virtual sensors */
153     void createVirtualSensors();
154 };
155 
156 } // namespace virtualSensor
157 } // namespace phosphor
158