diff --git a/healthMonitor.cpp b/healthMonitor.cpp
deleted file mode 100644
index 2b4e0c2..0000000
--- a/healthMonitor.cpp
+++ /dev/null
@@ -1,824 +0,0 @@
-#include "config.h"
-
-#include "healthMonitor.hpp"
-
-#include <unistd.h>
-
-#include <boost/asio/steady_timer.hpp>
-#include <sdbusplus/asio/connection.hpp>
-#include <sdbusplus/asio/object_server.hpp>
-#include <sdbusplus/asio/sd_event.hpp>
-#include <sdbusplus/bus/match.hpp>
-#include <sdbusplus/server/manager.hpp>
-#include <sdeventplus/event.hpp>
-
-#include <fstream>
-#include <iostream>
-#include <memory>
-#include <numeric>
-#include <sstream>
-
-extern "C"
-{
-#include <sys/statvfs.h>
-#include <sys/sysinfo.h>
-}
-
-PHOSPHOR_LOG2_USING;
-
-static constexpr bool DEBUG = false;
-static constexpr uint8_t defaultHighThreshold = 100;
-
-// Limit sensor recreation interval to 10s
-bool needUpdate;
-static constexpr int TIMER_INTERVAL = 10;
-std::shared_ptr<boost::asio::steady_timer> sensorRecreateTimer;
-std::shared_ptr<phosphor::health::HealthMon> healthMon;
-
-namespace phosphor
-{
-namespace health
-{
-
-// Example values for iface:
-// BMC_CONFIGURATION
-// BMC_INVENTORY_ITEM
-std::vector<std::string> findPathsWithType(sdbusplus::bus_t& bus,
-                                           const std::string& iface)
-{
-    PHOSPHOR_LOG2_USING;
-    std::vector<std::string> ret;
-
-    // Find all BMCs (DBus objects implementing the
-    // Inventory.Item.Bmc interface that may be created by
-    // configuring the Inventory Manager)
-    sdbusplus::message_t msg = bus.new_method_call(
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths");
-
-    // "/": No limit for paths for all the paths that may be touched
-    // in this daemon
-
-    // 0: Limit the depth to 0 to match both objects created by
-    // EntityManager and by InventoryManager
-
-    // {iface}: The endpoint of the Association Definition must have
-    // the Inventory.Item.Bmc interface
-    msg.append("/", 0, std::vector<std::string>{iface});
-
-    try
-    {
-        bus.call(msg, 0).read(ret);
-
-        if (!ret.empty())
-        {
-            debug("{IFACE} found", "IFACE", iface);
-        }
-        else
-        {
-            debug("{IFACE} not found", "IFACE", iface);
-        }
-    }
-    catch (std::exception& e)
-    {
-        error("Exception occurred while calling {PATH}: {ERROR}", "PATH",
-              InventoryPath, "ERROR", e);
-    }
-    return ret;
-}
-
-enum CPUStatesTime
-{
-    USER_IDX = 0,
-    NICE_IDX,
-    SYSTEM_IDX,
-    IDLE_IDX,
-    IOWAIT_IDX,
-    IRQ_IDX,
-    SOFTIRQ_IDX,
-    STEAL_IDX,
-    GUEST_USER_IDX,
-    GUEST_NICE_IDX,
-    NUM_CPU_STATES_TIME
-};
-
-// # cat /proc/stat|grep 'cpu '
-// cpu  5750423 14827 1572788 9259794 1317 0 28879 0 0 0
-static_assert(NUM_CPU_STATES_TIME == 10);
-
-enum CPUUtilizationType
-{
-    USER = 0,
-    KERNEL,
-    TOTAL
-};
-
-double readCPUUtilization(enum CPUUtilizationType type)
-{
-    auto proc_stat = "/proc/stat";
-    std::ifstream fileStat(proc_stat);
-    if (!fileStat.is_open())
-    {
-        error("cpu file not available: {PATH}", "PATH", proc_stat);
-        return -1;
-    }
-
-    std::string firstLine, labelName;
-    std::size_t timeData[NUM_CPU_STATES_TIME];
-
-    std::getline(fileStat, firstLine);
-    std::stringstream ss(firstLine);
-    ss >> labelName;
-
-    if (DEBUG)
-        debug("CPU stats first Line is: {LINE}", "LINE", firstLine);
-
-    if (labelName.compare("cpu"))
-    {
-        error("CPU data not available");
-        return -1;
-    }
-
-    int i;
-    for (i = 0; i < NUM_CPU_STATES_TIME; i++)
-    {
-        if (!(ss >> timeData[i]))
-            break;
-    }
-
-    if (i != NUM_CPU_STATES_TIME)
-    {
-        error("CPU data not correct");
-        return -1;
-    }
-
-    static std::unordered_map<enum CPUUtilizationType, uint64_t> preActiveTime,
-        preTotalTime;
-
-    // These are actually Jiffies. On the BMC, 1 jiffy usually corresponds to
-    // 0.01 second.
-    uint64_t activeTime = 0, activeTimeDiff = 0, totalTime = 0,
-             totalTimeDiff = 0;
-    double activePercValue = 0;
-
-    if (type == TOTAL)
-    {
-        activeTime = timeData[USER_IDX] + timeData[NICE_IDX] +
-                     timeData[SYSTEM_IDX] + timeData[IRQ_IDX] +
-                     timeData[SOFTIRQ_IDX] + timeData[STEAL_IDX] +
-                     timeData[GUEST_USER_IDX] + timeData[GUEST_NICE_IDX];
-    }
-    else if (type == KERNEL)
-    {
-        activeTime = timeData[SYSTEM_IDX];
-    }
-    else if (type == USER)
-    {
-        activeTime = timeData[USER_IDX];
-    }
-
-    totalTime = std::accumulate(std::begin(timeData), std::end(timeData), 0);
-
-    activeTimeDiff = activeTime - preActiveTime[type];
-    totalTimeDiff = totalTime - preTotalTime[type];
-
-    /* Store current idle and active time for next calculation */
-    preActiveTime[type] = activeTime;
-    preTotalTime[type] = totalTime;
-
-    activePercValue = (100.0 * activeTimeDiff) / totalTimeDiff;
-
-    if (DEBUG)
-        debug("CPU Utilization is {VALUE}", "VALUE", activePercValue);
-
-    return activePercValue;
-}
-
-auto readCPUUtilizationTotal([[maybe_unused]] const std::string& path)
-{
-    return readCPUUtilization(CPUUtilizationType::TOTAL);
-}
-
-auto readCPUUtilizationKernel([[maybe_unused]] const std::string& path)
-{
-    return readCPUUtilization(CPUUtilizationType::KERNEL);
-}
-
-auto readCPUUtilizationUser([[maybe_unused]] const std::string& path)
-{
-    return readCPUUtilization(CPUUtilizationType::USER);
-}
-
-double readMemoryUtilization([[maybe_unused]] const std::string& path)
-{
-    /* Unused var: path */
-    std::ignore = path;
-    std::ifstream meminfo("/proc/meminfo");
-    std::string line;
-    double memTotal = -1;
-    double memAvail = -1;
-
-    while (std::getline(meminfo, line))
-    {
-        std::string name;
-        double value;
-        std::istringstream iss(line);
-
-        if (!(iss >> name >> value))
-        {
-            continue;
-        }
-
-        if (name.starts_with("MemTotal"))
-        {
-            memTotal = value;
-        }
-        else if (name.starts_with("MemAvailable"))
-        {
-            memAvail = value;
-        }
-    }
-
-    if (memTotal <= 0 || memAvail <= 0)
-    {
-        return std::numeric_limits<double>::quiet_NaN();
-    }
-
-    if (DEBUG)
-    {
-        debug("MemTotal: {VALUE}", "VALUE", memTotal);
-        debug("MemAvailable: {VALUE}", "VALUE", memAvail);
-    }
-
-    return (memTotal - memAvail) / memTotal * 100;
-}
-
-double readStorageUtilization([[maybe_unused]] const std::string& path)
-{
-    struct statvfs buffer
-    {};
-    int ret = statvfs(path.c_str(), &buffer);
-    double total = 0;
-    double available = 0;
-    double used = 0;
-    double usedPercentage = 0;
-
-    if (ret != 0)
-    {
-        auto e = errno;
-        error("Error from statvfs: {ERROR}; {PATH}", "ERROR", strerror(e),
-              "PATH", path);
-        return 0;
-    }
-
-    total = buffer.f_blocks * (buffer.f_frsize / 1024);
-    available = buffer.f_bfree * (buffer.f_frsize / 1024);
-    used = total - available;
-    usedPercentage = (used / total) * 100;
-
-    if (DEBUG)
-    {
-        debug("Storage Total: {VALUE}", "VALUE", total);
-        debug("Available: {VALUE}", "VALUE", available);
-        debug("Used: {VALUE}", "VALUE", used);
-        debug("Storage Utilization: {VALUE}", "VALUE", usedPercentage);
-    }
-
-    return usedPercentage;
-}
-
-double readInodeUtilization([[maybe_unused]] const std::string& path)
-{
-    struct statvfs buffer
-    {};
-    int ret = statvfs(path.c_str(), &buffer);
-    double totalInodes = 0;
-    double availableInodes = 0;
-    double used = 0;
-    double usedPercentage = 0;
-
-    if (ret != 0)
-    {
-        auto e = errno;
-        error("Error from statvfs on {PATH}: {ERROR}", "PATH", path, "ERROR",
-              strerror(e));
-        return 0;
-    }
-
-    totalInodes = buffer.f_files;
-    availableInodes = buffer.f_ffree;
-    used = totalInodes - availableInodes;
-    usedPercentage = (used / totalInodes) * 100;
-
-    if (DEBUG)
-    {
-        debug("Total Inodes: {VALUE}", "VALUE", totalInodes);
-        debug("Available Inodes: {VALUE}", "VALUE", availableInodes);
-        debug("Used: {VALUE}", "VALUE", used);
-        debug("Inodes utilization is: {VALUE}", "VALUE", usedPercentage);
-    }
-
-    return usedPercentage;
-}
-
-constexpr auto storage = "Storage";
-constexpr auto inode = "Inode";
-
-/** Map of read function for each health sensors supported
- *
- * The following health sensors are read in the ManagerDiagnosticData
- * Redfish resource:
- *  - CPU_Kernel populates ProcessorStatistics.KernelPercent
- *  - CPU_User populates ProcessorStatistics.UserPercent
- */
-const std::map<std::string, std::function<double(const std::string& path)>>
-    readSensors = {{"CPU", readCPUUtilizationTotal},
-                   {"CPU_Kernel", readCPUUtilizationKernel},
-                   {"CPU_User", readCPUUtilizationUser},
-                   {"Memory", readMemoryUtilization},
-                   {storage, readStorageUtilization},
-                   {inode, readInodeUtilization}};
-
-void HealthSensor::setSensorThreshold(double criticalHigh, double warningHigh)
-{
-    CriticalInterface::criticalHigh(criticalHigh);
-    CriticalInterface::criticalLow(std::numeric_limits<double>::quiet_NaN());
-
-    WarningInterface::warningHigh(warningHigh);
-    WarningInterface::warningLow(std::numeric_limits<double>::quiet_NaN());
-}
-
-void HealthSensor::setSensorValueToDbus(const double value)
-{
-    ValueIface::value(value);
-}
-
-void HealthSensor::initHealthSensor(
-    const std::vector<std::string>& bmcInventoryPaths)
-{
-    info("{SENSOR} Health Sensor initialized", "SENSOR", sensorConfig.name);
-
-    /* Look for sensor read functions and Read Sensor values */
-    auto it = readSensors.find(sensorConfig.name);
-
-    if (sensorConfig.name.rfind(storage, 0) == 0)
-    {
-        it = readSensors.find(storage);
-    }
-    else if (sensorConfig.name.rfind(inode, 0) == 0)
-    {
-        it = readSensors.find(inode);
-    }
-    else if (it == readSensors.end())
-    {
-        error("Sensor read function not available");
-        return;
-    }
-
-    double value = it->second(sensorConfig.path);
-
-    if (value < 0)
-    {
-        error("Reading Sensor Utilization failed: {SENSOR}", "SENSOR",
-              sensorConfig.name);
-        return;
-    }
-
-    /* Initialize unit value (Percent) for utilization sensor */
-    ValueIface::unit(ValueIface::Unit::Percent);
-
-    ValueIface::maxValue(100);
-    ValueIface::minValue(0);
-    ValueIface::value(std::numeric_limits<double>::quiet_NaN());
-
-    // Associate the sensor to chassis
-    // This connects the DBus object to a Chassis.
-
-    std::vector<AssociationTuple> associationTuples;
-    for (const auto& chassisId : bmcInventoryPaths)
-    {
-        // This utilization sensor "is monitoring" the BMC with path chassisId.
-        // The chassisId is "monitored_by" this utilization sensor.
-        associationTuples.push_back({"monitors", "monitored_by", chassisId});
-    }
-    AssociationDefinitionInterface::associations(associationTuples);
-
-    /* Start the timer for reading sensor data at regular interval */
-    readTimer.restart(std::chrono::milliseconds(sensorConfig.freq * 1000));
-}
-
-void HealthSensor::checkSensorThreshold(const double value)
-{
-    if (std::isfinite(sensorConfig.criticalHigh) &&
-        (value > sensorConfig.criticalHigh))
-    {
-        if (!CriticalInterface::criticalAlarmHigh())
-        {
-            CriticalInterface::criticalAlarmHigh(true);
-            if (sensorConfig.criticalLog)
-            {
-                error(
-                    "ASSERT: sensor {SENSOR} is above the upper threshold critical high",
-                    "SENSOR", sensorConfig.name);
-                startUnit(sensorConfig.criticalTgt);
-            }
-        }
-        return;
-    }
-
-    if (CriticalInterface::criticalAlarmHigh())
-    {
-        CriticalInterface::criticalAlarmHigh(false);
-        if (sensorConfig.criticalLog)
-            info(
-                "DEASSERT: sensor {SENSOR} is under the upper threshold critical high",
-                "SENSOR", sensorConfig.name);
-    }
-
-    if (std::isfinite(sensorConfig.warningHigh) &&
-        (value > sensorConfig.warningHigh))
-    {
-        if (!WarningInterface::warningAlarmHigh())
-        {
-            WarningInterface::warningAlarmHigh(true);
-            if (sensorConfig.warningLog)
-            {
-                error(
-                    "ASSERT: sensor {SENSOR} is above the upper threshold warning high",
-                    "SENSOR", sensorConfig.name);
-                startUnit(sensorConfig.warningTgt);
-            }
-        }
-        return;
-    }
-
-    if (WarningInterface::warningAlarmHigh())
-    {
-        WarningInterface::warningAlarmHigh(false);
-        if (sensorConfig.warningLog)
-            info(
-                "DEASSERT: sensor {SENSOR} is under the upper threshold warning high",
-                "SENSOR", sensorConfig.name);
-    }
-}
-
-void HealthSensor::readHealthSensor()
-{
-    /* Read current sensor value */
-    double value;
-
-    if (sensorConfig.name.rfind(storage, 0) == 0)
-    {
-        value = readSensors.find(storage)->second(sensorConfig.path);
-    }
-    else if (sensorConfig.name.rfind(inode, 0) == 0)
-    {
-        value = readSensors.find(inode)->second(sensorConfig.path);
-    }
-    else
-    {
-        value = readSensors.find(sensorConfig.name)->second(sensorConfig.path);
-    }
-
-    if (value < 0)
-    {
-        error("Reading Sensor Utilization failed: {SENSOR}", "SENSOR",
-              sensorConfig.name);
-        return;
-    }
-
-    /* Remove first item from the queue */
-    if (valQueue.size() >= sensorConfig.windowSize)
-    {
-        valQueue.pop_front();
-    }
-    /* Add new item at the back */
-    valQueue.push_back(value);
-    /* Wait until the queue is filled with enough reference*/
-    if (valQueue.size() < sensorConfig.windowSize)
-    {
-        return;
-    }
-
-    /* Calculate average values for the given window size */
-    double avgValue = 0;
-    avgValue = accumulate(valQueue.begin(), valQueue.end(), avgValue);
-    avgValue = avgValue / sensorConfig.windowSize;
-
-    /* Set this new value to dbus */
-    setSensorValueToDbus(avgValue);
-
-    /* Check the sensor threshold  and log required message */
-    checkSensorThreshold(avgValue);
-}
-
-void HealthSensor::startUnit(const std::string& sysdUnit)
-{
-    if (sysdUnit.empty())
-    {
-        return;
-    }
-
-    sdbusplus::message_t msg = bus.new_method_call(
-        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
-        "org.freedesktop.systemd1.Manager", "StartUnit");
-    msg.append(sysdUnit, "replace");
-    bus.call_noreply(msg);
-}
-
-void HealthMon::recreateSensors()
-{
-    PHOSPHOR_LOG2_USING;
-    healthSensors.clear();
-
-    // Find BMC inventory paths and create health sensors
-    std::vector<std::string> bmcInventoryPaths =
-        findPathsWithType(bus, BMC_INVENTORY_ITEM);
-    createHealthSensors(bmcInventoryPaths);
-}
-
-void printConfig(HealthConfig& cfg)
-{
-    debug("Name: {VALUE}", "VALUE", cfg.name);
-    debug("Freq: {VALUE}", "VALUE", cfg.freq);
-    debug("Window Size: {VALUE}", "VALUE", cfg.windowSize);
-    debug("Critical value: {VALUE}", "VALUE", cfg.criticalHigh);
-    debug("warning value: {VALUE}", "VALUE", cfg.warningHigh);
-    debug("Critical log: {VALUE}", "VALUE", cfg.criticalLog);
-    debug("Warning log: {VALUE}", "VALUE", cfg.warningLog);
-    debug("Critical Target: {VALUE}", "VALUE", cfg.criticalTgt);
-    debug("Warning Target: {VALUE}", "VALUE", cfg.warningTgt);
-    debug("Path: {VALUE}", "VALUE", cfg.path);
-}
-
-/* Create dbus utilization sensor object for each configured sensors */
-void HealthMon::createHealthSensors(
-    const std::vector<std::string>& bmcInventoryPaths)
-{
-    for (auto& cfg : sensorConfigs)
-    {
-        std::string objPath = std::string(HEALTH_SENSOR_PATH) + cfg.name;
-        auto healthSensor = std::make_shared<HealthSensor>(
-            bus, objPath.c_str(), cfg, bmcInventoryPaths);
-        healthSensors.emplace(cfg.name, healthSensor);
-
-        info("{SENSOR} Health Sensor created", "SENSOR", cfg.name);
-
-        /* Set configured values of crtical and warning high to dbus */
-        healthSensor->setSensorThreshold(cfg.criticalHigh, cfg.warningHigh);
-    }
-}
-
-/** @brief Parsing Health config JSON file  */
-Json HealthMon::parseConfigFile(std::string configFile)
-{
-    std::ifstream jsonFile(configFile);
-    if (!jsonFile.is_open())
-    {
-        error("config JSON file not found: {PATH}", "PATH", configFile);
-    }
-
-    auto data = Json::parse(jsonFile, nullptr, false);
-    if (data.is_discarded())
-    {
-        error("config readings JSON parser failure: {PATH}", "PATH",
-              configFile);
-    }
-
-    return data;
-}
-
-void HealthMon::getConfigData(Json& data, HealthConfig& cfg)
-{
-    static const Json empty{};
-
-    /* Default frerquency of sensor polling is 1 second */
-    cfg.freq = data.value("Frequency", 1);
-
-    /* Default window size sensor queue is 1 */
-    cfg.windowSize = data.value("Window_size", 1);
-
-    auto threshold = data.value("Threshold", empty);
-    if (!threshold.empty())
-    {
-        auto criticalData = threshold.value("Critical", empty);
-        if (!criticalData.empty())
-        {
-            cfg.criticalHigh = criticalData.value("Value",
-                                                  defaultHighThreshold);
-            cfg.criticalLog = criticalData.value("Log", true);
-            cfg.criticalTgt = criticalData.value("Target", "");
-        }
-        auto warningData = threshold.value("Warning", empty);
-        if (!warningData.empty())
-        {
-            cfg.warningHigh = warningData.value("Value", defaultHighThreshold);
-            cfg.warningLog = warningData.value("Log", false);
-            cfg.warningTgt = warningData.value("Target", "");
-        }
-    }
-    cfg.path = data.value("Path", "");
-}
-
-std::vector<HealthConfig> HealthMon::getHealthConfig()
-{
-    std::vector<HealthConfig> cfgs;
-    auto data = parseConfigFile(HEALTH_CONFIG_FILE);
-
-    // print values
-    if (DEBUG)
-        debug("Config json data: {VALUE}", "VALUE", data.dump(2));
-
-    /* Get data items from config json data*/
-    for (auto& j : data.items())
-    {
-        auto key = j.key();
-        /* key need match default value in map readSensors or match the key
-         * start with "Storage" or "Inode" */
-        bool isStorageOrInode = (key.rfind(storage, 0) == 0 ||
-                                 key.rfind(inode, 0) == 0);
-        if (readSensors.find(key) != readSensors.end() || isStorageOrInode)
-        {
-            HealthConfig cfg = HealthConfig();
-            cfg.name = j.key();
-            getConfigData(j.value(), cfg);
-            if (isStorageOrInode)
-            {
-                struct statvfs buffer
-                {};
-                int ret = statvfs(cfg.path.c_str(), &buffer);
-                if (ret != 0)
-                {
-                    auto e = errno;
-                    error("Error from statvfs: {ERROR}; ({NAME}, {PATH})",
-                          "ERROR", strerror(e), "NAME", cfg.name, "PATH",
-                          cfg.path);
-                    continue;
-                }
-            }
-            cfgs.push_back(cfg);
-            if (DEBUG)
-                printConfig(cfg);
-        }
-        else
-        {
-            error("{SENSOR} Health Sensor not supported", "SENSOR", key);
-        }
-    }
-    return cfgs;
-}
-
-// Two caveats here.
-// 1. The BMC Inventory will only show up by the nearest ObjectMapper polling
-// interval.
-// 2. InterfacesAdded events will are not emitted like they are with E-M.
-void HealthMon::createBmcInventoryIfNotCreated()
-{
-    if (bmcInventory == nullptr)
-    {
-        info("createBmcInventory");
-        bmcInventory = std::make_shared<phosphor::health::BmcInventory>(
-            bus, "/xyz/openbmc_project/inventory/bmc");
-    }
-}
-
-bool HealthMon::bmcInventoryCreated()
-{
-    return bmcInventory != nullptr;
-}
-
-} // namespace health
-} // namespace phosphor
-
-void sensorRecreateTimerCallback(
-    std::shared_ptr<boost::asio::steady_timer> timer, sdbusplus::bus_t& bus)
-{
-    timer->expires_after(std::chrono::seconds(TIMER_INTERVAL));
-    timer->async_wait([timer, &bus](const boost::system::error_code& ec) {
-        if (ec == boost::asio::error::operation_aborted)
-        {
-            info("sensorRecreateTimer aborted");
-            return;
-        }
-
-        // When Entity-manager is already running
-        if (!needUpdate)
-        {
-            if ((!healthMon->bmcInventoryCreated()) &&
-                (!phosphor::health::findPathsWithType(bus, BMC_CONFIGURATION)
-                      .empty()))
-            {
-                healthMon->createBmcInventoryIfNotCreated();
-                needUpdate = true;
-            }
-        }
-        else
-        {
-            // If this daemon maintains its own DBus object, we must make sure
-            // the object is registered to ObjectMapper
-            if (phosphor::health::findPathsWithType(bus, BMC_INVENTORY_ITEM)
-                    .empty())
-            {
-                info(
-                    "BMC inventory item not registered to Object Mapper yet, waiting for next iteration");
-            }
-            else
-            {
-                info(
-                    "BMC inventory item registered to Object Mapper, creating sensors now");
-                healthMon->recreateSensors();
-                needUpdate = false;
-            }
-        }
-        sensorRecreateTimerCallback(timer, bus);
-    });
-}
-
-/**
- * @brief Main
- */
-int main()
-{
-    // The io_context is needed for the timer
-    boost::asio::io_context io;
-
-    // DBus connection
-    auto conn = std::make_shared<sdbusplus::asio::connection>(io);
-
-    conn->request_name(HEALTH_BUS_NAME);
-
-    // Get a default event loop
-    auto event = sdeventplus::Event::get_default();
-
-    // Create an health monitor object
-    healthMon = std::make_shared<phosphor::health::HealthMon>(*conn);
-
-    // Add object manager through object_server
-    sdbusplus::asio::object_server objectServer(conn);
-
-    sdbusplus::asio::sd_event_wrapper sdEvents(io);
-
-    sensorRecreateTimer = std::make_shared<boost::asio::steady_timer>(io);
-
-    // If the SystemInventory does not exist: wait for the InterfaceAdded signal
-    auto interfacesAddedSignalHandler =
-        std::make_unique<sdbusplus::bus::match_t>(
-            static_cast<sdbusplus::bus_t&>(*conn),
-            sdbusplus::bus::match::rules::interfacesAdded(),
-            [conn](sdbusplus::message_t& msg) {
-        using Association = std::tuple<std::string, std::string, std::string>;
-        using InterfacesAdded = std::vector<std::pair<
-            std::string,
-            std::vector<std::pair<std::string,
-                                  std::variant<std::vector<Association>>>>>>;
-
-        sdbusplus::message::object_path o;
-        InterfacesAdded interfacesAdded;
-
-        try
-        {
-            msg.read(o);
-            msg.read(interfacesAdded);
-        }
-        catch (const std::exception& e)
-        {
-            error(
-                "Exception occurred while processing interfacesAdded: {ERROR}",
-                "ERROR", e);
-            return;
-        }
-
-        // Ignore any signal coming from health-monitor itself.
-        if (msg.get_sender() == conn->get_unique_name())
-        {
-            return;
-        }
-
-        // Check if the BMC Inventory is in the interfaces created.
-        bool hasBmcConfiguration = false;
-        for (const auto& x : interfacesAdded)
-        {
-            if (x.first == BMC_CONFIGURATION)
-            {
-                hasBmcConfiguration = true;
-            }
-        }
-
-        if (hasBmcConfiguration)
-        {
-            info(
-                "BMC configuration detected, will create a corresponding Inventory item");
-            healthMon->createBmcInventoryIfNotCreated();
-            needUpdate = true;
-        }
-    });
-
-    // Start the timer
-    boost::asio::post(io, [conn]() {
-        sensorRecreateTimerCallback(sensorRecreateTimer, *conn);
-    });
-    io.run();
-
-    return 0;
-}
diff --git a/healthMonitor.hpp b/healthMonitor.hpp
deleted file mode 100644
index c6e77dd..0000000
--- a/healthMonitor.hpp
+++ /dev/null
@@ -1,202 +0,0 @@
-#include <nlohmann/json.hpp>
-#include <phosphor-logging/lg2.hpp>
-#include <sdbusplus/bus.hpp>
-#include <sdbusplus/message.hpp>
-#include <sdbusplus/server/manager.hpp>
-#include <sdeventplus/clock.hpp>
-#include <sdeventplus/event.hpp>
-#include <sdeventplus/utility/timer.hpp>
-#include <xyz/openbmc_project/Association/Definitions/server.hpp>
-#include <xyz/openbmc_project/Inventory/Item/Bmc/server.hpp>
-#include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
-#include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>
-#include <xyz/openbmc_project/Sensor/Value/server.hpp>
-
-constexpr char BMC_INVENTORY_ITEM[] = "xyz.openbmc_project.Inventory.Item.Bmc";
-constexpr char BMC_CONFIGURATION[] = "xyz.openbmc_project.Configuration.Bmc";
-
-#include <deque>
-#include <limits>
-#include <map>
-#include <string>
-
-namespace phosphor
-{
-namespace health
-{
-
-const char* InventoryPath = "/xyz/openbmc_project/inventory";
-
-// Used for identifying the BMC inventory creation signal
-const char* BMCActivationPath = "/xyz/openbmc_project/inventory/bmc/activation";
-
-bool FindSystemInventoryInObjectMapper(sdbusplus::bus_t& bus)
-{
-    sdbusplus::message_t msg =
-        bus.new_method_call("xyz.openbmc_project.ObjectMapper",
-                            "/xyz/openbmc_project/object_mapper",
-                            "xyz.openbmc_project.ObjectMapper", "GetObject");
-    msg.append(InventoryPath);
-    msg.append(std::vector<std::string>{});
-
-    try
-    {
-        sdbusplus::message_t reply = bus.call(msg, 0);
-        return true;
-    }
-    catch (const std::exception& e)
-    {}
-    return false;
-}
-
-using Json = nlohmann::json;
-using ValueIface = sdbusplus::xyz::openbmc_project::Sensor::server::Value;
-
-using CriticalInterface =
-    sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical;
-
-using WarningInterface =
-    sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning;
-
-using AssociationDefinitionInterface =
-    sdbusplus::xyz::openbmc_project::Association::server::Definitions;
-
-using healthIfaces =
-    sdbusplus::server::object_t<ValueIface, CriticalInterface, WarningInterface,
-                                AssociationDefinitionInterface>;
-
-using BmcInterface = sdbusplus::server::object_t<
-    sdbusplus::xyz::openbmc_project::Inventory::Item::server::Bmc>;
-
-using AssociationTuple = std::tuple<std::string, std::string, std::string>;
-
-struct HealthConfig
-{
-    std::string name;
-    uint16_t freq;
-    uint16_t windowSize;
-    double criticalHigh = std::numeric_limits<double>::quiet_NaN();
-    double warningHigh = std::numeric_limits<double>::quiet_NaN();
-    bool criticalLog;
-    bool warningLog;
-    std::string criticalTgt;
-    std::string warningTgt;
-    std::string path;
-};
-
-class HealthSensor : public healthIfaces
-{
-  public:
-    HealthSensor() = delete;
-    HealthSensor(const HealthSensor&) = delete;
-    HealthSensor& operator=(const HealthSensor&) = delete;
-    HealthSensor(HealthSensor&&) = delete;
-    HealthSensor& operator=(HealthSensor&&) = delete;
-    virtual ~HealthSensor() = default;
-
-    /** @brief Constructs HealthSensor
-     *
-     * @param[in] bus     - Handle to system dbus
-     * @param[in] objPath - The Dbus path of health sensor
-     */
-    HealthSensor(sdbusplus::bus_t& bus, const char* objPath,
-                 HealthConfig& sensorConfig,
-                 const std::vector<std::string>& bmcIds) :
-        healthIfaces(bus, objPath),
-        bus(bus), sensorConfig(sensorConfig),
-        timerEvent(sdeventplus::Event::get_default()),
-        readTimer(timerEvent, std::bind(&HealthSensor::readHealthSensor, this))
-    {
-        initHealthSensor(bmcIds);
-    }
-
-    /** @brief list of sensor data values */
-    std::deque<double> valQueue;
-    /** @brief Initialize sensor, set default value and association */
-    void initHealthSensor(const std::vector<std::string>& bmcIds);
-    /** @brief Set sensor value utilization to health sensor D-bus  */
-    void setSensorValueToDbus(const double value);
-    /** @brief Set Sensor Threshold to D-bus at beginning */
-    void setSensorThreshold(double criticalHigh, double warningHigh);
-    /** @brief Check Sensor threshold and update alarm and log */
-    void checkSensorThreshold(const double value);
-
-  private:
-    /** @brief sdbusplus bus client connection. */
-    sdbusplus::bus_t& bus;
-    /** @brief Sensor config from config file */
-    HealthConfig& sensorConfig;
-    /** @brief the Event Loop structure */
-    sdeventplus::Event timerEvent;
-    /** @brief Sensor Read Timer */
-    sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> readTimer;
-    /** @brief Read sensor at regular intrval */
-    void readHealthSensor();
-    /** @brief Start configured threshold systemd unit */
-    void startUnit(const std::string& sysdUnit);
-};
-
-class BmcInventory : public BmcInterface
-{
-  public:
-    BmcInventory() = delete;
-    BmcInventory(sdbusplus::bus_t& bus, const char* objPath) :
-        BmcInterface(bus, objPath)
-    {}
-};
-
-class HealthMon
-{
-  public:
-    HealthMon() = delete;
-    HealthMon(const HealthMon&) = delete;
-    HealthMon& operator=(const HealthMon&) = delete;
-    HealthMon(HealthMon&&) = delete;
-    HealthMon& operator=(HealthMon&&) = delete;
-    virtual ~HealthMon() = default;
-
-    /** @brief Recreates sensor objects and their association if possible
-     */
-    void recreateSensors();
-
-    /** @brief Constructs HealthMon
-     *
-     * @param[in] bus     - Handle to system dbus
-     */
-    HealthMon(sdbusplus::bus_t& bus) :
-        bus(bus), sensorsObjectManager(bus, "/xyz/openbmc_project/sensors")
-    {
-        // Read JSON file
-        sensorConfigs = getHealthConfig();
-        recreateSensors();
-    }
-
-    /** @brief Parse Health config JSON file  */
-    Json parseConfigFile(std::string configFile);
-
-    /** @brief Read config for each health sensor component */
-    void getConfigData(Json& data, HealthConfig& cfg);
-
-    /** @brief Map of the object HealthSensor */
-    std::unordered_map<std::string, std::shared_ptr<HealthSensor>>
-        healthSensors;
-
-    /** @brief Create sensors for health monitoring */
-    void createHealthSensors(const std::vector<std::string>& bmcIds);
-
-    /** @brief Create the BMC Inventory object */
-    void createBmcInventoryIfNotCreated();
-
-    std::shared_ptr<BmcInventory> bmcInventory;
-
-    bool bmcInventoryCreated();
-
-  private:
-    sdbusplus::bus_t& bus;
-    std::vector<HealthConfig> sensorConfigs;
-    std::vector<HealthConfig> getHealthConfig();
-    sdbusplus::server::manager_t sensorsObjectManager;
-};
-
-} // namespace health
-} // namespace phosphor
diff --git a/health_monitor.cpp b/health_monitor.cpp
new file mode 100644
index 0000000..b839ae7
--- /dev/null
+++ b/health_monitor.cpp
@@ -0,0 +1,66 @@
+#include "health_monitor.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/async.hpp>
+
+PHOSPHOR_LOG2_USING;
+
+namespace phosphor::health::monitor
+{
+
+using namespace phosphor::health::utils;
+
+void HealthMonitor::create()
+{
+    info("Creating Health Monitor with config size {SIZE}", "SIZE",
+         configs.size());
+    constexpr auto BMCInventoryItem = "xyz.openbmc_project.Inventory.Item.Bmc";
+    auto bmcPaths = findPaths(bus, BMCInventoryItem);
+
+    for (auto& [type, collectionConfig] : configs)
+    {
+        info("Creating Health Metric Collection for {TYPE}", "TYPE",
+             std::to_underlying(type));
+        collections[type] =
+            std::make_unique<CollectionIntf::HealthMetricCollection>(
+                bus, type, collectionConfig, bmcPaths);
+    }
+}
+
+void HealthMonitor::run()
+{
+    info("Running Health Monitor");
+    for (auto& [type, collection] : collections)
+    {
+        debug("Reading Health Metric Collection for {TYPE}", "TYPE",
+              std::to_underlying(type));
+        collection->read();
+    }
+}
+
+} // namespace phosphor::health::monitor
+
+using namespace phosphor::health::monitor;
+
+int main()
+{
+    constexpr auto path = MetricIntf::ValueIntf::Value::namespace_path::value;
+    sdbusplus::async::context ctx;
+    sdbusplus::server::manager_t manager{ctx, path};
+    constexpr auto healthMonitorServiceName = "xyz.openbmc_project.HealthMon";
+
+    info("Creating health monitor");
+    HealthMonitor healthMonitor{ctx.get_bus()};
+    ctx.request_name(healthMonitorServiceName);
+
+    ctx.spawn([&]() -> sdbusplus::async::task<> {
+        while (!ctx.stop_requested())
+        {
+            healthMonitor.run();
+            co_await sdbusplus::async::sleep_for(ctx, std::chrono::seconds(5));
+        }
+    }());
+
+    ctx.run();
+    return 0;
+}
diff --git a/health_monitor.hpp b/health_monitor.hpp
new file mode 100644
index 0000000..31d16ba
--- /dev/null
+++ b/health_monitor.hpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#include "health_metric_collection.hpp"
+
+#include <unordered_map>
+
+namespace phosphor::health::monitor
+{
+namespace ConfigIntf = phosphor::health::metric::config;
+namespace MetricIntf = phosphor::health::metric;
+namespace CollectionIntf = phosphor::health::metric::collection;
+class HealthMonitor
+{
+  public:
+    HealthMonitor() = delete;
+
+    HealthMonitor(sdbusplus::bus_t& bus) :
+        bus(bus), configs(ConfigIntf::getHealthMetricConfigs())
+    {
+        create();
+    }
+
+    /** @brief Run the health monitor */
+    void run();
+
+  private:
+    using map_t = std::unordered_map<
+        MetricIntf::Type,
+        std::unique_ptr<CollectionIntf::HealthMetricCollection>>;
+    /** @brief Create a new health monitor object */
+    void create();
+    /** @brief D-Bus bus connection */
+    sdbusplus::bus_t& bus;
+    /** @brief Health metric configs */
+    ConfigIntf::HealthMetric::map_t configs;
+    map_t collections;
+};
+
+} // namespace phosphor::health::monitor
diff --git a/health_utils.cpp b/health_utils.cpp
index 163fc8c..a60db8b 100644
--- a/health_utils.cpp
+++ b/health_utils.cpp
@@ -20,4 +20,29 @@
     bus.call_noreply(msg);
 }
 
+auto findPaths(sdbusplus::bus_t& bus, const std::string& iface) -> paths_t
+{
+    sdbusplus::message_t msg = bus.new_method_call(
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths");
+    const char* inventoryPath = "/xyz/openbmc_project/inventory";
+
+    msg.append("/", 0, std::vector<std::string>{iface});
+
+    try
+    {
+        auto paths = bus.call(msg, int32_t(0)).unpack<paths_t>();
+        debug("Found {COUNT} paths for {IFACE}", "COUNT", paths.size(), "IFACE",
+              iface);
+        return paths;
+    }
+    catch (std::exception& e)
+    {
+        error("Exception occurred for GetSubTreePaths for {PATH}: {ERROR}",
+              "PATH", inventoryPath, "ERROR", e);
+    }
+    return {};
+}
+
 } // namespace phosphor::health::utils
diff --git a/health_utils.hpp b/health_utils.hpp
index b89d8e5..ded0159 100644
--- a/health_utils.hpp
+++ b/health_utils.hpp
@@ -12,5 +12,7 @@
 
 /** @brief Start a systemd unit */
 void startUnit(sdbusplus::bus_t& bus, const std::string& sysdUnit);
+/** @brief Find D-Bus paths for given interface */
+auto findPaths(sdbusplus::bus_t& bus, const std::string& iface) -> paths_t;
 
 } // namespace phosphor::health::utils
diff --git a/meson.build b/meson.build
index 09ef147..f56e3f5 100644
--- a/meson.build
+++ b/meson.build
@@ -24,11 +24,11 @@
 executable(
     'health-monitor',
     [
-        'healthMonitor.cpp',
         'health_metric_config.cpp',
         'health_metric.cpp',
         'health_utils.cpp',
         'health_metric_collection.cpp',
+        'health_monitor.cpp',
     ],
     dependencies: [
         base_deps
