diff --git a/src/smbpbi/SmbpbiSensor.cpp b/src/smbpbi/SmbpbiSensor.cpp
new file mode 100644
index 0000000..6b3aa1a
--- /dev/null
+++ b/src/smbpbi/SmbpbiSensor.cpp
@@ -0,0 +1,546 @@
+/*
+ * SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION &
+ * AFFILIATES. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "SmbpbiSensor.hpp"
+
+#include "SensorPaths.hpp"
+#include "Thresholds.hpp"
+#include "Utils.hpp"
+#include "sensor.hpp"
+
+#include <linux/i2c.h>
+
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/post.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/bus/match.hpp>
+#include <sdbusplus/message.hpp>
+
+#include <array>
+#include <chrono>
+#include <cmath>
+#include <cstdint>
+#include <cstring>
+#include <functional>
+#include <limits>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+extern "C"
+{
+#include <linux/i2c-dev.h>
+#include <sys/ioctl.h>
+}
+
+constexpr const bool debug = false;
+
+constexpr const char* configInterface =
+    "xyz.openbmc_project.Configuration.SmbpbiVirtualEeprom";
+constexpr const char* sensorRootPath = "/xyz/openbmc_project/sensors/";
+constexpr const char* objectType = "SmbpbiVirtualEeprom";
+
+boost::container::flat_map<std::string, std::unique_ptr<SmbpbiSensor>> sensors;
+
+SmbpbiSensor::SmbpbiSensor(
+    std::shared_ptr<sdbusplus::asio::connection>& conn,
+    boost::asio::io_context& io, const std::string& sensorName,
+    const std::string& sensorConfiguration, const std::string& objType,
+    sdbusplus::asio::object_server& objectServer,
+    std::vector<thresholds::Threshold>&& thresholdData, uint8_t busId,
+    uint8_t addr, uint16_t offset, std::string& sensorUnits,
+    std::string& valueType, size_t pollTime, double minVal, double maxVal,
+    std::string& path) :
+    Sensor(escapeName(sensorName), std::move(thresholdData),
+           sensorConfiguration, objType, false, false, maxVal, minVal, conn),
+    busId(busId), addr(addr), offset(offset), sensorUnits(sensorUnits),
+    valueType(valueType), objectServer(objectServer),
+    inputDev(io, path, boost::asio::random_access_file::read_only),
+    waitTimer(io), pollRateSecond(pollTime)
+{
+    sensorType = sensor_paths::getPathForUnits(sensorUnits);
+    std::string sensorPath = sensorRootPath + sensorType + "/";
+
+    sensorInterface =
+        objectServer.add_interface(sensorPath + name, sensorValueInterface);
+
+    for (const auto& threshold : thresholds)
+    {
+        std::string interface = thresholds::getInterface(threshold.level);
+        thresholdInterfaces[static_cast<size_t>(threshold.level)] =
+            objectServer.add_interface(sensorPath + name, interface);
+    }
+    association =
+        objectServer.add_interface(sensorPath + name, association::interface);
+
+    if (sensorType == "temperature")
+    {
+        setInitialProperties(sensor_paths::unitDegreesC);
+    }
+    else if (sensorType == "power")
+    {
+        setInitialProperties(sensor_paths::unitWatts);
+    }
+    else if (sensorType == "energy")
+    {
+        setInitialProperties(sensor_paths::unitJoules);
+    }
+    else if (sensorType == "voltage")
+    {
+        setInitialProperties(sensor_paths::unitVolts);
+    }
+    else
+    {
+        lg2::error("no sensor type found");
+    }
+}
+
+SmbpbiSensor::~SmbpbiSensor()
+{
+    inputDev.close();
+    waitTimer.cancel();
+    for (const auto& iface : thresholdInterfaces)
+    {
+        objectServer.remove_interface(iface);
+    }
+    objectServer.remove_interface(sensorInterface);
+    objectServer.remove_interface(association);
+}
+
+void SmbpbiSensor::init()
+{
+    read();
+}
+
+void SmbpbiSensor::checkThresholds()
+{
+    thresholds::checkThresholds(this);
+}
+
+double SmbpbiSensor::convert2Temp(const uint8_t* raw)
+{
+    // Temp data is encoded in SMBPBI format. The 3 MSBs denote
+    // the integer portion, LSB is an encoded fraction.
+    // this automatic convert to int (two's complement integer)
+    int32_t intg = (raw[3] << 24 | raw[2] << 16 | raw[1] << 8 | raw[0]);
+    uint8_t frac = uint8_t(raw[0]);
+    // shift operation on a int keeps the sign in two's complement
+    intg >>= 8;
+
+    double temp = 0;
+    if (intg > 0)
+    {
+        temp = double(intg) + double(frac / 256.0);
+    }
+    else
+    {
+        temp = double(intg) - double(frac / 256.0);
+    }
+
+    return temp;
+}
+
+double SmbpbiSensor::convert2Power(const uint8_t* raw)
+{
+    // Power data is encoded as a 4-byte unsigned integer
+    uint32_t val = (raw[3] << 24) + (raw[2] << 16) + (raw[1] << 8) + raw[0];
+
+    // mWatts to Watts
+    double power = static_cast<double>(val) / 1000;
+
+    return power;
+}
+
+int SmbpbiSensor::i2cReadDataBytesDouble(double& reading)
+{
+    constexpr int length =
+        i2CReadLenValues[static_cast<size_t>(I2C_READ_LEN_INDEX::FLOAT64)];
+
+    static_assert(length == sizeof(reading), "Unsupported arch");
+
+    std::array<uint8_t, length> buf{};
+    int ret = i2cReadDataBytes(buf.data(), length);
+    if (ret < 0)
+    {
+        return ret;
+    }
+    // there is no value updated from HMC if reading data is all 0xff
+    // Return NaN since reading is already a double
+    if (checkInvalidReading(buf.data(), length))
+    {
+        reading = std::numeric_limits<double>::quiet_NaN();
+        return 0;
+    }
+    uint64_t tempd = 0;
+    for (int byteI = 0; byteI < length; byteI++)
+    {
+        tempd |= static_cast<uint64_t>(buf[byteI]) << (8 * byteI);
+    }
+    std::memcpy(&reading, &tempd, sizeof(reading));
+
+    return 0;
+}
+
+int SmbpbiSensor::i2cReadDataBytesUI64(uint64_t& reading)
+{
+    constexpr int length =
+        i2CReadLenValues[static_cast<size_t>(I2C_READ_LEN_INDEX::UINT64)];
+
+    static_assert(length == sizeof(reading), "Unsupported arch");
+
+    std::array<uint8_t, length> buf{};
+    int ret = i2cReadDataBytes(buf.data(), length);
+    if (ret < 0)
+    {
+        return ret;
+    }
+    reading = 0;
+    for (int byteI = 0; byteI < length; byteI++)
+    {
+        reading |= static_cast<uint64_t>(buf[byteI]) << (8 * byteI);
+    }
+    return 0;
+}
+
+// Generic i2c Command to read bytes
+int SmbpbiSensor::i2cReadDataBytes(uint8_t* reading, int length)
+{
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
+    const int fd = inputDev.native_handle();
+    if (fd < 0)
+    {
+        lg2::error(" unable to open i2c device on bus {BUS} err={FD}", "BUS",
+                   busId, "FD", fd);
+        return -1;
+    }
+
+    unsigned long funcs = 0;
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
+    if (ioctl(fd, I2C_FUNCS, &funcs) < 0)
+    {
+        lg2::error(" I2C_FUNCS not supported");
+        return -1;
+    }
+
+    int ret = 0;
+    struct i2c_rdwr_ioctl_data args = {nullptr, 0};
+    struct i2c_msg msg = {0, 0, 0, nullptr};
+    std::array<uint8_t, 8> cmd{};
+
+    msg.addr = addr;
+    args.msgs = &msg;
+    args.nmsgs = 1;
+
+    msg.flags = 0;
+    msg.buf = cmd.data();
+    // handle two bytes offset
+    if (offset > 255)
+    {
+        msg.len = 2;
+        msg.buf[0] = offset >> 8;
+        msg.buf[1] = offset & 0xFF;
+    }
+    else
+    {
+        msg.len = 1;
+        msg.buf[0] = offset & 0xFF;
+    }
+
+    // write offset
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
+    ret = ioctl(fd, I2C_RDWR, &args);
+    if (ret < 0)
+    {
+        return ret;
+    }
+
+    msg.flags = I2C_M_RD;
+    msg.len = length;
+    msg.buf = reading;
+
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
+    ret = ioctl(fd, I2C_RDWR, &args);
+    if (ret < 0)
+    {
+        return ret;
+    }
+    return 0;
+}
+
+int SmbpbiSensor::readRawEEPROMData(double& data)
+{
+    uint64_t reading = 0;
+    int ret = i2cReadDataBytesUI64(reading);
+    if (ret < 0)
+    {
+        return ret;
+    }
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+    if (checkInvalidReading(reinterpret_cast<uint8_t*>(&reading),
+                            sizeof(reading)))
+    {
+        data = std::numeric_limits<double>::quiet_NaN();
+        return 0;
+    }
+    if (debug)
+    {
+        lg2::error("offset: {OFFSET} reading: {READING}", "OFFSET", offset,
+                   "READING", reading);
+    }
+    if (sensorType == "temperature")
+    {
+        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+        data = convert2Temp(reinterpret_cast<uint8_t*>(&reading));
+    }
+    else if (sensorType == "power")
+    {
+        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+        data = convert2Power(reinterpret_cast<uint8_t*>(&reading));
+    }
+    else if (sensorType == "energy")
+    {
+        data = reading / 1000.0; // mJ to J (double)
+    }
+    else
+    {
+        data = reading; // Voltage
+    }
+    return 0;
+}
+
+int SmbpbiSensor::readFloat64EEPROMData(double& data)
+{
+    double reading = 0;
+    int ret = i2cReadDataBytesDouble(reading);
+    if (ret < 0)
+    {
+        return ret;
+    }
+    data = reading;
+    return 0;
+}
+
+void SmbpbiSensor::waitReadCallback(const boost::system::error_code& ec)
+{
+    if (ec == boost::asio::error::operation_aborted)
+    {
+        // we're being cancelled
+        return;
+    }
+    // read timer error
+    if (ec)
+    {
+        lg2::error("timer error");
+        return;
+    }
+    double temp = 0;
+
+    int ret = 0;
+    // Sensor reading value types are sensor-specific. So, read
+    // and interpret sensor data based on it's value type.
+    if (valueType == "UINT64")
+    {
+        ret = readRawEEPROMData(temp);
+    }
+    else if (valueType == "FLOAT64")
+    {
+        ret = readFloat64EEPROMData(temp);
+    }
+    else
+    {
+        return;
+    }
+
+    if (ret >= 0)
+    {
+        if constexpr (debug)
+        {
+            lg2::error("Value update to {TEMP}", "TEMP", temp);
+        }
+        updateValue(temp);
+    }
+    else
+    {
+        lg2::error("Invalid read getRegsInfo");
+        incrementError();
+    }
+    read();
+}
+
+void SmbpbiSensor::read()
+{
+    size_t pollTime = getPollRate(); // in seconds
+
+    waitTimer.expires_after(std::chrono::seconds(pollTime));
+    waitTimer.async_wait([this](const boost::system::error_code& ec) {
+        this->waitReadCallback(ec);
+    });
+}
+
+static void createSensorCallback(
+    boost::system::error_code ec, const ManagedObjectType& resp,
+    boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
+    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
+    boost::container::flat_map<std::string, std::unique_ptr<SmbpbiSensor>>&
+        sensors)
+{
+    if (ec)
+    {
+        lg2::error("Error contacting entity manager");
+        return;
+    }
+    for (const auto& pathPair : resp)
+    {
+        for (const auto& entry : pathPair.second)
+        {
+            if (entry.first != configInterface)
+            {
+                continue;
+            }
+            std::string name = loadVariant<std::string>(entry.second, "Name");
+
+            std::vector<thresholds::Threshold> sensorThresholds;
+            if (!parseThresholdsFromConfig(pathPair.second, sensorThresholds))
+            {
+                lg2::error("error populating thresholds for {NAME}", "NAME",
+                           name);
+            }
+
+            uint8_t busId = loadVariant<uint8_t>(entry.second, "Bus");
+
+            uint8_t addr = loadVariant<uint8_t>(entry.second, "Address");
+
+            uint16_t off = loadVariant<uint16_t>(entry.second, "ReadOffset");
+
+            std::string sensorUnits =
+                loadVariant<std::string>(entry.second, "Units");
+
+            std::string valueType =
+                loadVariant<std::string>(entry.second, "ValueType");
+            if (valueType != "UINT64" && valueType != "FLOAT64")
+            {
+                lg2::error("Invalid ValueType for sensor: {NAME}", "NAME",
+                           name);
+                break;
+            }
+
+            size_t rate = loadVariant<uint8_t>(entry.second, "PollRate");
+
+            double minVal = loadVariant<double>(entry.second, "MinValue");
+
+            double maxVal = loadVariant<double>(entry.second, "MaxValue");
+            if constexpr (debug)
+            {
+                lg2::info("Configuration parsed for \n\t {CONF}\nwith\n"
+                          "\tName: {NAME}\n"
+                          "\tBus: {BUS}\n"
+                          "\tAddress:{ADDR}\n"
+                          "\tOffset: {OFF}\n"
+                          "\tType : {TYPE}\n"
+                          "\tValue Type : {VALUETYPE}\n"
+                          "\tPollrate: {RATE}\n"
+                          "\tMinValue: {MIN}\n"
+                          "\tMaxValue: {MAX}\n",
+                          "CONF", entry.first, "NAME", name, "BUS",
+                          static_cast<int>(busId), "ADDR",
+                          static_cast<int>(addr), "OFF", static_cast<int>(off),
+                          "UNITS", sensorUnits, "VALUETYPE", valueType, "RATE",
+                          rate, "MIN", minVal, "MAX", maxVal);
+            }
+
+            auto& sensor = sensors[name];
+            sensor = nullptr;
+
+            std::string path = "/dev/i2c-" + std::to_string(busId);
+
+            sensor = std::make_unique<SmbpbiSensor>(
+                dbusConnection, io, name, pathPair.first, objectType,
+                objectServer, std::move(sensorThresholds), busId, addr, off,
+                sensorUnits, valueType, rate, minVal, maxVal, path);
+
+            sensor->init();
+        }
+    }
+}
+
+void createSensors(
+    boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
+    boost::container::flat_map<std::string, std::unique_ptr<SmbpbiSensor>>&
+        sensors,
+    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
+{
+    if (!dbusConnection)
+    {
+        lg2::error("Connection not created");
+        return;
+    }
+
+    dbusConnection->async_method_call(
+        [&io, &objectServer, &dbusConnection, &sensors](
+            boost::system::error_code ec, const ManagedObjectType& resp) {
+            createSensorCallback(ec, resp, io, objectServer, dbusConnection,
+                                 sensors);
+        },
+        entityManagerName, "/xyz/openbmc_project/inventory",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+}
+
+int main()
+{
+    boost::asio::io_context io;
+    auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
+    sdbusplus::asio::object_server objectServer(systemBus, true);
+    objectServer.add_manager("/xyz/openbmc_project/sensors");
+    systemBus->request_name("xyz.openbmc_project.SMBPBI");
+
+    boost::asio::post(io, [&]() {
+        createSensors(io, objectServer, sensors, systemBus);
+    });
+
+    boost::asio::steady_timer configTimer(io);
+
+    std::function<void(sdbusplus::message::message&)> eventHandler =
+        [&](sdbusplus::message::message&) {
+            configTimer.expires_after(std::chrono::seconds(1));
+            // create a timer because normally multiple properties change
+            configTimer.async_wait([&](const boost::system::error_code& ec) {
+                if (ec == boost::asio::error::operation_aborted)
+                {
+                    return; // we're being canceled
+                }
+                // config timer error
+                if (ec)
+                {
+                    lg2::error("timer error");
+                    return;
+                }
+                createSensors(io, objectServer, sensors, systemBus);
+                if (sensors.empty())
+                {
+                    lg2::info("Configuration not detected");
+                }
+            });
+        };
+
+    sdbusplus::bus::match::match configMatch(
+        static_cast<sdbusplus::bus::bus&>(*systemBus),
+        "type='signal',member='PropertiesChanged',"
+        "path_namespace='" +
+            std::string(inventoryPath) +
+            "',"
+            "arg0namespace='" +
+            configInterface + "'",
+        eventHandler);
+
+    setupManufacturingModeMatch(*systemBus);
+    io.run();
+    return 0;
+}
