123f091e5SJagpal Singh Gill #pragma once
223f091e5SJagpal Singh Gill 
323f091e5SJagpal Singh Gill #include "health_metric_config.hpp"
423f091e5SJagpal Singh Gill #include "health_utils.hpp"
523f091e5SJagpal Singh Gill 
623f091e5SJagpal Singh Gill #include <xyz/openbmc_project/Association/Definitions/server.hpp>
723f091e5SJagpal Singh Gill #include <xyz/openbmc_project/Inventory/Item/Bmc/server.hpp>
823f091e5SJagpal Singh Gill #include <xyz/openbmc_project/Metric/Value/server.hpp>
923f091e5SJagpal Singh Gill 
1023f091e5SJagpal Singh Gill #include <deque>
1123f091e5SJagpal Singh Gill #include <tuple>
1223f091e5SJagpal Singh Gill 
1323f091e5SJagpal Singh Gill namespace phosphor::health::metric
1423f091e5SJagpal Singh Gill {
1523f091e5SJagpal Singh Gill 
1623f091e5SJagpal Singh Gill using phosphor::health::utils::paths_t;
1723f091e5SJagpal Singh Gill using phosphor::health::utils::startUnit;
1823f091e5SJagpal Singh Gill using AssociationIntf =
1923f091e5SJagpal Singh Gill     sdbusplus::xyz::openbmc_project::Association::server::Definitions;
2023f091e5SJagpal Singh Gill using ValueIntf = sdbusplus::xyz::openbmc_project::Metric::server::Value;
2123f091e5SJagpal Singh Gill using PathIntf =
2223f091e5SJagpal Singh Gill     sdbusplus::common::xyz::openbmc_project::metric::Value::namespace_path;
2323f091e5SJagpal Singh Gill static constexpr auto BmcPath =
2423f091e5SJagpal Singh Gill     sdbusplus::common::xyz::openbmc_project::metric::Value::bmc;
2523f091e5SJagpal Singh Gill using BmcIntf = sdbusplus::xyz::openbmc_project::Inventory::Item::server::Bmc;
2623f091e5SJagpal Singh Gill using MetricIntf =
2723f091e5SJagpal Singh Gill     sdbusplus::server::object_t<ValueIntf, ThresholdIntf, AssociationIntf>;
2823f091e5SJagpal Singh Gill 
2923f091e5SJagpal Singh Gill struct MValue
3023f091e5SJagpal Singh Gill {
316a3884a4SJagpal Singh Gill     /** @brief Current value of metric */
326a3884a4SJagpal Singh Gill     double current;
336a3884a4SJagpal Singh Gill     /** @brief Total value of metric */
346a3884a4SJagpal Singh Gill     double total;
3523f091e5SJagpal Singh Gill };
3623f091e5SJagpal Singh Gill 
3723f091e5SJagpal Singh Gill class HealthMetric : public MetricIntf
3823f091e5SJagpal Singh Gill {
3923f091e5SJagpal Singh Gill   public:
40658efd5fSPatrick Williams     using MType = phosphor::health::metric::Type;
41658efd5fSPatrick Williams 
4223f091e5SJagpal Singh Gill     HealthMetric() = delete;
4323f091e5SJagpal Singh Gill     HealthMetric(const HealthMetric&) = delete;
4423f091e5SJagpal Singh Gill     HealthMetric(HealthMetric&&) = delete;
4523f091e5SJagpal Singh Gill     virtual ~HealthMetric() = default;
4623f091e5SJagpal Singh Gill 
HealthMetric(sdbusplus::bus_t & bus,MType type,const config::HealthMetric & config,const paths_t & bmcPaths)4797582801SJagpal Singh Gill     HealthMetric(sdbusplus::bus_t& bus, MType type,
4823f091e5SJagpal Singh Gill                  const config::HealthMetric& config, const paths_t& bmcPaths) :
4997582801SJagpal Singh Gill         MetricIntf(bus, getPath(type, config.name, config.subType).c_str(),
5097582801SJagpal Singh Gill                    action::defer_emit),
5123f091e5SJagpal Singh Gill         bus(bus), type(type), config(config)
5223f091e5SJagpal Singh Gill     {
5323f091e5SJagpal Singh Gill         create(bmcPaths);
5423f091e5SJagpal Singh Gill         this->emit_object_added();
5523f091e5SJagpal Singh Gill     }
5623f091e5SJagpal Singh Gill 
5723f091e5SJagpal Singh Gill     /** @brief Update the health metric with the given value */
5823f091e5SJagpal Singh Gill     void update(MValue value);
5923f091e5SJagpal Singh Gill 
6023f091e5SJagpal Singh Gill   private:
6123f091e5SJagpal Singh Gill     /** @brief Create a new health metric object */
6223f091e5SJagpal Singh Gill     void create(const paths_t& bmcPaths);
6323f091e5SJagpal Singh Gill     /** @brief Init properties for the health metric object */
6423f091e5SJagpal Singh Gill     void initProperties();
65*b94b122dSJagpal Singh Gill     /** @brief Check if specified value should be notified based on hysteresis
66*b94b122dSJagpal Singh Gill      */
67*b94b122dSJagpal Singh Gill     auto shouldNotify(MValue value) -> bool;
6823f091e5SJagpal Singh Gill     /** @brief Check specified threshold for the given value */
69658efd5fSPatrick Williams     void checkThreshold(Type type, Bound bound, MValue value);
7023f091e5SJagpal Singh Gill     /** @brief Check all thresholds for the given value */
716a3884a4SJagpal Singh Gill     void checkThresholds(MValue value);
7297582801SJagpal Singh Gill     /** @brief Get the object path for the given type, name and subtype */
73658efd5fSPatrick Williams     auto getPath(MType type, std::string name, SubType subType) -> std::string;
7423f091e5SJagpal Singh Gill     /** @brief D-Bus bus connection */
75cfd889feSPatrick Williams     sdbusplus::bus_t& bus;
7623f091e5SJagpal Singh Gill     /** @brief Metric type */
7797582801SJagpal Singh Gill     MType type;
7823f091e5SJagpal Singh Gill     /** @brief Metric configuration */
7923f091e5SJagpal Singh Gill     const config::HealthMetric config;
8023f091e5SJagpal Singh Gill     /** @brief Window for metric history */
8123f091e5SJagpal Singh Gill     std::deque<double> history;
82*b94b122dSJagpal Singh Gill     /** @brief Last notified value for the metric change */
83*b94b122dSJagpal Singh Gill     double lastNotifiedValue = 0;
8423f091e5SJagpal Singh Gill };
8523f091e5SJagpal Singh Gill 
8623f091e5SJagpal Singh Gill } // namespace phosphor::health::metric
87