1 #pragma once 2 3 #include "health_metric_config.hpp" 4 #include "health_utils.hpp" 5 6 #include <xyz/openbmc_project/Association/Definitions/server.hpp> 7 #include <xyz/openbmc_project/Inventory/Item/Bmc/server.hpp> 8 #include <xyz/openbmc_project/Metric/Value/server.hpp> 9 10 #include <deque> 11 #include <tuple> 12 13 namespace phosphor::health::metric 14 { 15 16 using phosphor::health::utils::paths_t; 17 using phosphor::health::utils::startUnit; 18 using AssociationIntf = 19 sdbusplus::xyz::openbmc_project::Association::server::Definitions; 20 using ValueIntf = sdbusplus::xyz::openbmc_project::Metric::server::Value; 21 using PathIntf = 22 sdbusplus::common::xyz::openbmc_project::metric::Value::namespace_path; 23 static constexpr auto BmcPath = 24 sdbusplus::common::xyz::openbmc_project::metric::Value::bmc; 25 using BmcIntf = sdbusplus::xyz::openbmc_project::Inventory::Item::server::Bmc; 26 using MetricIntf = 27 sdbusplus::server::object_t<ValueIntf, ThresholdIntf, AssociationIntf>; 28 29 struct MValue 30 { 31 /** @brief Current value of metric */ 32 double current; 33 /** @brief Total value of metric */ 34 double total; 35 }; 36 37 class HealthMetric : public MetricIntf 38 { 39 public: 40 using MType = phosphor::health::metric::Type; 41 42 HealthMetric() = delete; 43 HealthMetric(const HealthMetric&) = delete; 44 HealthMetric(HealthMetric&&) = delete; 45 virtual ~HealthMetric() = default; 46 HealthMetric(sdbusplus::bus_t & bus,MType type,const config::HealthMetric & config,const paths_t & bmcPaths)47 HealthMetric(sdbusplus::bus_t& bus, MType type, 48 const config::HealthMetric& config, const paths_t& bmcPaths) : 49 MetricIntf(bus, getPath(type, config.name, config.subType).c_str(), 50 action::defer_emit), 51 bus(bus), type(type), config(config) 52 { 53 create(bmcPaths); 54 this->emit_object_added(); 55 } 56 57 /** @brief Update the health metric with the given value */ 58 void update(MValue value); 59 60 private: 61 /** @brief Create a new health metric object */ 62 void create(const paths_t& bmcPaths); 63 /** @brief Init properties for the health metric object */ 64 void initProperties(); 65 /** @brief Check if specified value should be notified based on hysteresis 66 */ 67 auto shouldNotify(MValue value) -> bool; 68 /** @brief Check specified threshold for the given value */ 69 void checkThreshold(Type type, Bound bound, MValue value); 70 /** @brief Check all thresholds for the given value */ 71 void checkThresholds(MValue value); 72 /** @brief Get the object path for the given type, name and subtype */ 73 auto getPath(MType type, std::string name, SubType subType) -> std::string; 74 /** @brief D-Bus bus connection */ 75 sdbusplus::bus_t& bus; 76 /** @brief Metric type */ 77 MType type; 78 /** @brief Metric configuration */ 79 const config::HealthMetric config; 80 /** @brief Window for metric history */ 81 std::deque<double> history; 82 /** @brief Last notified value for the metric change */ 83 double lastNotifiedValue = 0; 84 }; 85 86 } // namespace phosphor::health::metric 87