xref: /openbmc/pldm/platform-mc/numeric_sensor.hpp (revision 9825660e73e13e4a353ec2c437ecf4e5233ab3f6)
1  #pragma once
2  
3  #include "libpldm/platform.h"
4  #include "libpldm/pldm.h"
5  
6  #include "common/types.hpp"
7  #include "common/utils.hpp"
8  
9  #include <sdbusplus/server/object.hpp>
10  #include <xyz/openbmc_project/Association/Definitions/server.hpp>
11  #include <xyz/openbmc_project/Inventory/Source/PLDM/Entity/server.hpp>
12  #include <xyz/openbmc_project/Metric/Value/server.hpp>
13  #include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
14  #include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>
15  #include <xyz/openbmc_project/Sensor/Value/server.hpp>
16  #include <xyz/openbmc_project/State/Decorator/Availability/server.hpp>
17  #include <xyz/openbmc_project/State/Decorator/OperationalStatus/server.hpp>
18  
19  #include <string>
20  
21  namespace pldm
22  {
23  namespace platform_mc
24  {
25  
26  constexpr const char* SENSOR_VALUE_INTF = "xyz.openbmc_project.Sensor.Value";
27  constexpr const char* METRIC_VALUE_INTF = "xyz.openbmc_project.Metric.Value";
28  
29  using SensorUnit = sdbusplus::xyz::openbmc_project::Sensor::server::Value::Unit;
30  using ValueIntf = sdbusplus::server::object_t<
31      sdbusplus::xyz::openbmc_project::Sensor::server::Value>;
32  using MetricUnit = sdbusplus::xyz::openbmc_project::Metric::server::Value::Unit;
33  using MetricIntf = sdbusplus::server::object_t<
34      sdbusplus::xyz::openbmc_project::Metric::server::Value>;
35  using ThresholdWarningIntf = sdbusplus::server::object_t<
36      sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning>;
37  using ThresholdCriticalIntf = sdbusplus::server::object_t<
38      sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical>;
39  using OperationalStatusIntf =
40      sdbusplus::server::object_t<sdbusplus::xyz::openbmc_project::State::
41                                      Decorator::server::OperationalStatus>;
42  using AvailabilityIntf = sdbusplus::server::object_t<
43      sdbusplus::xyz::openbmc_project::State::Decorator::server::Availability>;
44  using AssociationDefinitionsInft = sdbusplus::server::object_t<
45      sdbusplus::xyz::openbmc_project::Association::server::Definitions>;
46  using EntityIntf = sdbusplus::server::object_t<
47      sdbusplus::xyz::openbmc_project::Inventory::Source::PLDM::server::Entity>;
48  
49  /**
50   * @brief NumericSensor
51   *
52   * This class handles sensor reading updated by sensor manager and export
53   * status to D-Bus interface.
54   */
55  class NumericSensor
56  {
57    public:
58      NumericSensor(const pldm_tid_t tid, const bool sensorDisabled,
59                    std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr,
60                    std::string& sensorName, std::string& associationPath);
61  
62      NumericSensor(const pldm_tid_t tid, const bool sensorDisabled,
63                    std::shared_ptr<pldm_compact_numeric_sensor_pdr> pdr,
64                    std::string& sensorName, std::string& associationPath);
65  
~NumericSensor()66      ~NumericSensor() {};
67  
68      /** @brief The function called by Sensor Manager to set sensor to
69       * error status.
70       */
71      void handleErrGetSensorReading();
72  
73      /** @brief Updating the sensor status to D-Bus interface
74       */
75      void updateReading(bool available, bool functional, double value = 0);
76  
77      /** @brief ConversionFormula is used to convert raw value to the unit
78       * specified in PDR
79       *
80       *  @param[in] value - raw value
81       *  @return double - converted value
82       */
83      double conversionFormula(double value);
84  
85      /** @brief UnitModifier is used to apply the unit modifier specified in PDR
86       *
87       *  @param[in] value - raw value
88       *  @return double - converted value
89       */
90      double unitModifier(double value);
91  
92      /** @brief Check if value is over threshold.
93       *
94       *  @param[in] alarm - previous alarm state
95       *  @param[in] direction - upper or lower threshold checking
96       *  @param[in] value - raw value
97       *  @param[in] threshold - threshold value
98       *  @param[in] hyst - hysteresis value
99       *  @return bool - new alarm state
100       */
101      bool checkThreshold(bool alarm, bool direction, double value,
102                          double threshold, double hyst);
103  
104      /** @brief Updating the association to D-Bus interface
105       *  @param[in] inventoryPath - inventory path of the entity
106       */
setInventoryPath(const std::string & inventoryPath)107      inline void setInventoryPath(const std::string& inventoryPath)
108      {
109          if (associationDefinitionsIntf)
110          {
111              associationDefinitionsIntf->associations(
112                  {{"chassis", "all_sensors", inventoryPath}});
113          }
114      }
115  
116      /** @brief Get Upper Critical threshold
117       *
118       *  @return double - Upper Critical threshold
119       */
getThresholdUpperCritical()120      double getThresholdUpperCritical()
121      {
122          if (thresholdCriticalIntf)
123          {
124              return thresholdCriticalIntf->criticalHigh();
125          }
126          else
127          {
128              return std::numeric_limits<double>::quiet_NaN();
129          }
130      };
131  
132      /** @brief Get Lower Critical threshold
133       *
134       *  @return double - Lower Critical threshold
135       */
getThresholdLowerCritical()136      double getThresholdLowerCritical()
137      {
138          if (thresholdCriticalIntf)
139          {
140              return thresholdCriticalIntf->criticalLow();
141          }
142          else
143          {
144              return std::numeric_limits<double>::quiet_NaN();
145          }
146      };
147  
148      /** @brief Get Upper Warning threshold
149       *
150       *  @return double - Upper Warning threshold
151       */
getThresholdUpperWarning()152      double getThresholdUpperWarning()
153      {
154          if (thresholdWarningIntf)
155          {
156              return thresholdWarningIntf->warningHigh();
157          }
158          else
159          {
160              return std::numeric_limits<double>::quiet_NaN();
161          }
162      };
163  
164      /** @brief Get Lower Warning threshold
165       *
166       *  @return double - Lower Warning threshold
167       */
getThresholdLowerWarning()168      double getThresholdLowerWarning()
169      {
170          if (thresholdWarningIntf)
171          {
172              return thresholdWarningIntf->warningLow();
173          }
174          else
175          {
176              return std::numeric_limits<double>::quiet_NaN();
177          }
178      };
179  
180      /** @brief Check if value is over threshold.
181       *
182       *  @param[in] eventType - event level in pldm::utils::Level
183       *  @param[in] direction - direction type in pldm::utils::Direction
184       *  @param[in] rawValue - sensor raw value
185       *  @param[in] newAlarm - trigger alarm true/false
186       *  @param[in] assert - event type asserted/deasserted
187       *
188       *  @return PLDM completion code
189       */
190      int triggerThresholdEvent(pldm::utils::Level eventType,
191                                pldm::utils::Direction direction, double rawValue,
192                                bool newAlarm, bool assert);
193  
194      /** @brief Terminus ID which the sensor belongs to */
195      pldm_tid_t tid;
196  
197      /** @brief Sensor ID */
198      uint16_t sensorId;
199  
200      /** @brief  The time stamp since last getSensorReading command in usec */
201      uint64_t timeStamp;
202  
203      /** @brief  The time of sensor update interval in usec */
204      uint64_t updateTime;
205  
206      /** @brief  sensorName */
207      std::string sensorName;
208  
209      /** @brief  sensorNameSpace */
210      std::string sensorNameSpace;
211  
212      /** @brief Sensor Unit */
213      SensorUnit sensorUnit;
214  
215    private:
216      /**
217       * @brief Check sensor reading if any threshold has been crossed and update
218       * Threshold interfaces accordingly
219       */
220      void updateThresholds();
221  
222      /**
223       * @brief Update the object units based on the PDR baseUnit
224       */
225      void setSensorUnit(uint8_t baseUnit);
226  
227      /** @brief Create the sensor inventory path.
228       *
229       *  @param[in] associationPath - sensor association path
230       *  @param[in] sensorName - sensor name
231       *  @param[in] entityType - sensor PDR entity type
232       *  @param[in] entityInstanceNum - sensor PDR entity instance number
233       *  @param[in] containerId - sensor PDR entity container ID
234       *
235       *  @return True when success otherwise return False
236       */
237      inline bool createInventoryPath(
238          const std::string& associationPath, const std::string& sensorName,
239          const uint16_t entityType, const uint16_t entityInstanceNum,
240          const uint16_t containerId);
241  
242      std::unique_ptr<MetricIntf> metricIntf = nullptr;
243      std::unique_ptr<ValueIntf> valueIntf = nullptr;
244      std::unique_ptr<ThresholdWarningIntf> thresholdWarningIntf = nullptr;
245      std::unique_ptr<ThresholdCriticalIntf> thresholdCriticalIntf = nullptr;
246      std::unique_ptr<AvailabilityIntf> availabilityIntf = nullptr;
247      std::unique_ptr<OperationalStatusIntf> operationalStatusIntf = nullptr;
248      std::unique_ptr<AssociationDefinitionsInft> associationDefinitionsIntf =
249          nullptr;
250      std::unique_ptr<EntityIntf> entityIntf = nullptr;
251  
252      /** @brief Amount of hysteresis associated with the sensor thresholds */
253      double hysteresis;
254  
255      /** @brief The resolution of sensor in Units */
256      double resolution;
257  
258      /** @brief A constant value that is added in as part of conversion process
259       * of converting a raw sensor reading to Units */
260      double offset;
261  
262      /** @brief A power-of-10 multiplier for baseUnit */
263      int8_t baseUnitModifier;
264      bool useMetricInterface = false;
265  };
266  } // namespace platform_mc
267  } // namespace pldm
268