diff --git a/src/nvidia-gpu/NvidiaGpuSensor.cpp b/src/nvidia-gpu/NvidiaGpuSensor.cpp
index 86b356b..1626545 100644
--- a/src/nvidia-gpu/NvidiaGpuSensor.cpp
+++ b/src/nvidia-gpu/NvidiaGpuSensor.cpp
@@ -14,25 +14,19 @@
 #include <bits/basic_string.h>
 
 #include <MctpRequester.hpp>
+#include <NvidiaDeviceDiscovery.hpp>
 #include <NvidiaGpuMctpVdm.hpp>
 #include <OcpMctpVdm.hpp>
-#include <boost/asio/io_context.hpp>
-#include <boost/container/flat_map.hpp>
 #include <phosphor-logging/lg2.hpp>
 #include <sdbusplus/asio/connection.hpp>
 #include <sdbusplus/asio/object_server.hpp>
-#include <sdbusplus/message.hpp>
-#include <sdbusplus/message/native_types.hpp>
 
-#include <algorithm>
-#include <chrono>
 #include <cstddef>
 #include <cstdint>
 #include <functional>
 #include <memory>
 #include <string>
 #include <utility>
-#include <variant>
 #include <vector>
 
 using namespace std::literals;
@@ -41,19 +35,17 @@
 static constexpr double gpuTempSensorMaxReading = 127;
 static constexpr double gpuTempSensorMinReading = -128;
 
-GpuTempSensor::GpuTempSensor(
+NvidiaGpuTempSensor::NvidiaGpuTempSensor(
     std::shared_ptr<sdbusplus::asio::connection>& conn,
-    boost::asio::io_context& io, mctp::MctpRequester& mctpRequester,
-    const std::string& name, const std::string& sensorConfiguration,
+    mctp::MctpRequester& mctpRequester, const std::string& name,
+    const std::string& sensorConfiguration, const uint8_t eid,
     sdbusplus::asio::object_server& objectServer,
-    std::vector<thresholds::Threshold>&& thresholdData,
-    std::chrono::milliseconds pollRate) :
+    std::vector<thresholds::Threshold>&& thresholdData) :
     Sensor(escapeName(name), std::move(thresholdData), sensorConfiguration,
            "temperature", false, true, gpuTempSensorMaxReading,
            gpuTempSensorMinReading, conn),
-    sensorId{gpuTempSensorId}, sensorPollMs(pollRate),
-    waitTimer(io, std::chrono::steady_clock::duration(0)),
-    mctpRequester(mctpRequester), conn(conn), objectServer(objectServer)
+    eid(eid), sensorId{gpuTempSensorId}, mctpRequester(mctpRequester),
+    objectServer(objectServer)
 {
     std::string dbusPath =
         sensorPathPrefix + "temperature/"s + escapeName(name);
@@ -70,12 +62,11 @@
 
     association = objectServer.add_interface(dbusPath, association::interface);
 
-    discoverGpus();
+    setInitialProperties(sensor_paths::unitDegreesC);
 }
 
-GpuTempSensor::~GpuTempSensor()
+NvidiaGpuTempSensor::~NvidiaGpuTempSensor()
 {
-    waitTimer.cancel();
     for (const auto& iface : thresholdInterfaces)
     {
         objectServer.remove_interface(iface);
@@ -84,72 +75,18 @@
     objectServer.remove_interface(sensorInterface);
 }
 
-void GpuTempSensor::checkThresholds()
+void NvidiaGpuTempSensor::checkThresholds()
 {
     thresholds::checkThresholds(this);
 }
 
-void GpuTempSensor::queryEndpoints(const boost::system::error_code& ec,
-                                   const GetSubTreeType& ret)
-{
-    if (ec)
-    {
-        lg2::error("Error querying endoints :{ERROR}", "ERROR", ec.message());
-        return;
-    }
-
-    if (ret.empty())
-    {
-        return;
-    }
-
-    for (const auto& [objPath, services] : ret)
-    {
-        for (const auto& [service, ifaces] : services)
-        {
-            for (const auto& iface : ifaces)
-            {
-                if (iface == "xyz.openbmc_project.MCTP.Endpoint")
-                {
-                    conn->async_method_call(
-                        [this](const boost::system::error_code& ec,
-                               const SensorBaseConfigMap& configs) {
-                            this->processEndpoint(ec, configs);
-                        },
-                        service, objPath, "org.freedesktop.DBus.Properties",
-                        "GetAll", iface);
-                }
-            }
-        }
-    }
-}
-
-void GpuTempSensor::read()
-{
-    update();
-
-    waitTimer.expires_after(std::chrono::milliseconds(sensorPollMs));
-    waitTimer.async_wait(
-        [weakPtrToThis = std::weak_ptr<GpuTempSensor>{shared_from_this()}](
-            const boost::system::error_code& ec) {
-            if (ec)
-            {
-                return;
-            }
-            if (auto ptr = weakPtrToThis.lock())
-            {
-                ptr->read();
-            }
-        });
-}
-
-void GpuTempSensor::processResponse(int sendRecvMsgResult)
+void NvidiaGpuTempSensor::processResponse(int sendRecvMsgResult)
 {
     if (sendRecvMsgResult != 0)
     {
         lg2::error(
-            "Error updating Temperature Sensor: sending message over MCTP failed, rc={RC}",
-            "RC", sendRecvMsgResult);
+            "Error updating Temperature Sensor for eid {EID} and sensor id {SID} : sending message over MCTP failed, rc={RC}",
+            "EID", eid, "SID", sensorId, "RC", sendRecvMsgResult);
         return;
     }
 
@@ -163,264 +100,29 @@
     if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
     {
         lg2::error(
-            "Error updating Temperature Sensor: decode failed, rc={RC}, cc={CC}, reasonCode={RESC}",
-            "RC", rc, "CC", cc, "RESC", reasonCode);
+            "Error updating Temperature Sensor for eid {EID} and sensor id {SID} : decode failed. "
+            "rc={RC}, cc={CC}, reasonCode={RESC}",
+            "EID", eid, "SID", sensorId, "RC", rc, "CC", cc, "RESC",
+            reasonCode);
         return;
     }
 
     updateValue(tempValue);
 }
 
-void GpuTempSensor::update()
+void NvidiaGpuTempSensor::update()
 {
     auto rc = gpu::encodeGetTemperatureReadingRequest(
         0, sensorId, getTemperatureReadingRequest);
+
     if (rc != 0)
     {
-        lg2::error("Error updating Temperature Sensor: encode failed, rc={RC}",
-                   "RC", rc);
-        return;
+        lg2::error(
+            "Error updating Temperature Sensor for eid {EID} and sensor id {SID} : encode failed, rc={RC}",
+            "EID", eid, "SID", sensorId, "RC", rc);
     }
 
     mctpRequester.sendRecvMsg(
         eid, getTemperatureReadingRequest, getTemperatureReadingResponse,
         [this](int sendRecvMsgResult) { processResponse(sendRecvMsgResult); });
 }
-
-void GpuTempSensor::processQueryDeviceIdResponse(uint8_t eid,
-                                                 int sendRecvMsgResult)
-{
-    if (sendRecvMsgResult != 0)
-    {
-        lg2::error(
-            "Error processing GPU endpoint: sending message over MCTP failed, rc={RC}",
-            "RC", sendRecvMsgResult);
-        return;
-    }
-
-    ocp::accelerator_management::CompletionCode cc{};
-    uint16_t reasonCode = 0;
-    uint8_t responseDeviceType = 0;
-    uint8_t responseInstanceId = 0;
-
-    auto rc = gpu::decodeQueryDeviceIdentificationResponse(
-        queryDeviceIdentificationResponse, cc, reasonCode, responseDeviceType,
-        responseInstanceId);
-
-    if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
-    {
-        lg2::error(
-            "Error processing GPU endpoint: decode failed, rc={RC}, cc={CC}, reasonCode={RESC}",
-            "RC", rc, "CC", cc, "RESC", reasonCode);
-        return;
-    }
-
-    if (responseDeviceType ==
-        static_cast<uint8_t>(gpu::DeviceIdentification::DEVICE_GPU))
-    {
-        lg2::info(
-            "Found the GPU with EID {EID}, DeviceType {DEVTYPE}, InstanceId {IID}.",
-            "EID", eid, "DEVTYPE", responseDeviceType, "IID",
-            responseInstanceId);
-
-        this->eid = eid;
-        setInitialProperties(sensor_paths::unitDegreesC);
-        read();
-    }
-}
-
-void GpuTempSensor::processGpuEndpoint(uint8_t eid)
-{
-    auto rc = gpu::encodeQueryDeviceIdentificationRequest(
-        0, queryDeviceIdentificationRequest);
-    if (rc != 0)
-    {
-        lg2::error("Error processing GPU endpoint: encode failed, rc={RC}",
-                   "RC", rc);
-        return;
-    }
-
-    mctpRequester.sendRecvMsg(
-        eid, queryDeviceIdentificationRequest,
-        queryDeviceIdentificationResponse, [this, eid](int sendRecvMsgResult) {
-            processQueryDeviceIdResponse(eid, sendRecvMsgResult);
-        });
-}
-
-void GpuTempSensor::processEndpoint(const boost::system::error_code& ec,
-                                    const SensorBaseConfigMap& endpoint)
-{
-    if (ec)
-    {
-        lg2::error("Error processing MCTP endpoint: {ERROR}", "ERROR",
-                   ec.message());
-        return;
-    }
-
-    uint8_t eid{};
-    std::vector<uint8_t> mctpTypes{};
-
-    auto hasEid = endpoint.find("EID");
-    if (hasEid != endpoint.end())
-    {
-        const auto* eidPtr = std::get_if<uint8_t>(&hasEid->second);
-        if (eidPtr != nullptr)
-        {
-            eid = *eidPtr;
-        }
-        else
-        {
-            lg2::error(
-                "Error processing MCTP endpoint: Property EID does not have valid type.");
-            return;
-        }
-    }
-    else
-    {
-        lg2::error(
-            "Error processing MCTP endpoint: Property EID not found in the configuration.");
-        return;
-    }
-
-    auto hasMctpTypes = endpoint.find("SupportedMessageTypes");
-    if (hasMctpTypes != endpoint.end())
-    {
-        const auto* mctpTypePtr =
-            std::get_if<std::vector<uint8_t>>(&hasMctpTypes->second);
-        if (mctpTypePtr != nullptr)
-        {
-            mctpTypes = *mctpTypePtr;
-        }
-        else
-        {
-            lg2::error(
-                "Error processing MCTP endpoint: Property SupportedMessageTypes does not have valid type.");
-            return;
-        }
-    }
-    else
-    {
-        lg2::error(
-            "Error processing MCTP endpoint: Property SupportedMessageTypes not found in the configuration.");
-        return;
-    }
-
-    if (std::find(mctpTypes.begin(), mctpTypes.end(),
-                  ocp::accelerator_management::messageType) != mctpTypes.end())
-    {
-        lg2::info(
-            "GpuTempSensor::discoverGpus(): Found OCP MCTP VDM Endpoint with ID {EID}",
-            "EID", eid);
-        this->processGpuEndpoint(eid);
-    }
-}
-
-void GpuTempSensor::discoverGpus()
-{
-    std::string searchPath{"/au/com/codeconstruct/"};
-    std::vector<std::string> ifaceList{{"xyz.openbmc_project.MCTP.Endpoint"}};
-
-    conn->async_method_call(
-        [this](const boost::system::error_code& ec, const GetSubTreeType& ret) {
-            queryEndpoints(ec, ret);
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree", searchPath, 0,
-        ifaceList);
-}
-
-void processSensorConfigs(
-    boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
-    boost::container::flat_map<std::string, std::shared_ptr<GpuTempSensor>>&
-        sensors,
-    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
-    mctp::MctpRequester& mctpRequester, const ManagedObjectType& resp)
-{
-    for (const auto& [path, interfaces] : resp)
-    {
-        for (const auto& [intf, cfg] : interfaces)
-        {
-            if (intf != configInterfaceName(sensorType))
-            {
-                continue;
-            }
-
-            std::string name = loadVariant<std::string>(cfg, "Name");
-
-            uint64_t pollRate = loadVariant<uint64_t>(cfg, "PollRate");
-
-            sensors[name] = std::make_shared<GpuTempSensor>(
-                dbusConnection, io, mctpRequester, name, path, objectServer,
-                std::vector<thresholds::Threshold>{},
-                std::chrono::milliseconds{pollRate});
-
-            lg2::info(
-                "Added GPU Temperature Sensor {NAME} with chassis path: {PATH}.",
-                "NAME", name, "PATH", path);
-        }
-    }
-}
-
-void createSensors(
-    boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
-    boost::container::flat_map<std::string, std::shared_ptr<GpuTempSensor>>&
-        sensors,
-    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
-    mctp::MctpRequester& mctpRequester)
-{
-    if (!dbusConnection)
-    {
-        lg2::error("Connection not created");
-        return;
-    }
-    dbusConnection->async_method_call(
-        [&sensors, &mctpRequester, &dbusConnection, &io,
-         &objectServer](const boost::system::error_code& ec,
-                        const ManagedObjectType& resp) {
-            if (ec)
-            {
-                lg2::error("Error contacting entity manager");
-                return;
-            }
-
-            processSensorConfigs(io, objectServer, sensors, dbusConnection,
-                                 mctpRequester, resp);
-        },
-        entityManagerName, "/xyz/openbmc_project/inventory",
-        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-}
-
-void interfaceRemoved(
-    sdbusplus::message_t& message,
-    boost::container::flat_map<std::string, std::shared_ptr<GpuTempSensor>>&
-        sensors)
-{
-    if (message.is_method_error())
-    {
-        lg2::error("interfacesRemoved callback method error");
-        return;
-    }
-
-    sdbusplus::message::object_path removedPath;
-    std::vector<std::string> interfaces;
-
-    message.read(removedPath, interfaces);
-
-    // If the xyz.openbmc_project.Confguration.X interface was removed
-    // for one or more sensors, delete those sensor objects.
-    auto sensorIt = sensors.begin();
-    while (sensorIt != sensors.end())
-    {
-        if ((sensorIt->second->configurationPath == removedPath) &&
-            (std::find(interfaces.begin(), interfaces.end(),
-                       configInterfaceName(sensorType)) != interfaces.end()))
-        {
-            sensorIt = sensors.erase(sensorIt);
-        }
-        else
-        {
-            sensorIt++;
-        }
-    }
-}
