diff --git a/src/calculate.cpp b/src/calculate.cpp
new file mode 100644
index 0000000..ccdb723
--- /dev/null
+++ b/src/calculate.cpp
@@ -0,0 +1,81 @@
+#include "calculate.hpp"
+
+#include <algorithm>
+#include <limits>
+#include <numeric>
+
+namespace phosphor::virtual_sensor
+{
+
+double calculateModifiedMedianValue(std::vector<double>& values)
+{
+    size_t size = values.size();
+    std::sort(values.begin(), values.end());
+    switch (size)
+    {
+        case 2:
+            /* Choose biggest value */
+            return values.at(1);
+        case 0:
+            return std::numeric_limits<double>::quiet_NaN();
+        default:
+            /* Choose median value */
+            if (size % 2 == 0)
+            {
+                // Average of the two middle values
+                return (values.at(size / 2) + values.at(size / 2 - 1)) / 2;
+            }
+            else
+            {
+                return values.at((size - 1) / 2);
+            }
+    }
+}
+
+double calculateMaximumValue(std::vector<double>& values)
+{
+    auto maxIt = std::max_element(values.begin(), values.end());
+    if (maxIt == values.end())
+    {
+        return std::numeric_limits<double>::quiet_NaN();
+    }
+    return *maxIt;
+}
+
+double calculateMinimumValue(std::vector<double>& values)
+{
+    auto maxIt = std::min_element(values.begin(), values.end());
+    if (maxIt == values.end())
+    {
+        return std::numeric_limits<double>::quiet_NaN();
+    }
+    return *maxIt;
+}
+
+double calculateSumValue(std::vector<double>& values)
+{
+    if (values.empty())
+    {
+        return std::numeric_limits<double>::quiet_NaN();
+    }
+    return std::accumulate(values.begin(), values.end(), 0.0);
+}
+
+double calculateAverageValue(std::vector<double>& values)
+{
+    if (values.empty())
+    {
+        return std::numeric_limits<double>::quiet_NaN();
+    }
+    return std::accumulate(values.begin(), values.end(), 0.0) / values.size();
+}
+
+std::map<Interface, CalculationFunc> calculationIfaces{
+    {"xyz.openbmc_project.Configuration.Average", calculateAverageValue},
+    {"xyz.openbmc_project.Configuration.Maximum", calculateMaximumValue},
+    {"xyz.openbmc_project.Configuration.Minimum", calculateMinimumValue},
+    {"xyz.openbmc_project.Configuration.Sum", calculateSumValue},
+    {"xyz.openbmc_project.Configuration.ModifiedMedian",
+     calculateModifiedMedianValue}};
+
+} // namespace phosphor::virtual_sensor
diff --git a/src/calculate.hpp b/src/calculate.hpp
new file mode 100644
index 0000000..fdf200f
--- /dev/null
+++ b/src/calculate.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <functional>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace phosphor::virtual_sensor
+{
+
+using Interface = std::string;
+using CalculationFunc = std::function<double(std::vector<double>&)>;
+extern std::map<Interface, CalculationFunc> calculationIfaces;
+
+} // namespace phosphor::virtual_sensor
diff --git a/src/dbusSensor.cpp b/src/dbusSensor.cpp
new file mode 100644
index 0000000..8b6a48f
--- /dev/null
+++ b/src/dbusSensor.cpp
@@ -0,0 +1,158 @@
+#include "dbusSensor.hpp"
+
+#include "virtualSensor.hpp"
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+
+#include <cmath>
+static constexpr auto sensorIntf =
+    sdbusplus::common::xyz::openbmc_project::sensor::Value::interface;
+
+/** When the Entity Manager removes the sensor, the interfaceRemoveSignal sent
+ * uses the path /xyz/openbmc_project/sensors
+ * */
+static constexpr auto interfacesSensorPath = "/xyz/openbmc_project/sensors";
+
+namespace phosphor::virtual_sensor
+{
+
+DbusSensor::DbusSensor(sdbusplus::bus_t& bus, const std::string& path,
+                       VirtualSensor& virtualSensor) :
+    bus(bus), path(path), virtualSensor(virtualSensor),
+    signalPropChange(
+        bus, sdbusplus::bus::match::rules::propertiesChanged(path, sensorIntf),
+        [this](sdbusplus::message_t& message) {
+            handleDbusSignalPropChange(message);
+        }),
+    signalRemove(
+        bus,
+        sdbusplus::bus::match::rules::interfacesRemoved(interfacesSensorPath),
+        [this](sdbusplus::message_t& message) {
+            handleDbusSignalRemove(message);
+        })
+{
+    initSensorValue();
+}
+
+double DbusSensor::getSensorValue()
+{
+    return value;
+}
+
+void DbusSensor::initSensorValue()
+{
+    try
+    {
+        // If servName is not empty, reduce one DbusCall
+        if (servName.empty())
+        {
+            value = std::numeric_limits<double>::quiet_NaN();
+            servName = getService(bus, path, sensorIntf);
+        }
+
+        if (!servName.empty())
+        {
+            signalNameOwnerChanged.reset();
+            signalNameOwnerChanged = std::make_unique<sdbusplus::bus::match_t>(
+                bus,
+                sdbusplus::bus::match::rules::nameOwnerChanged() +
+                    sdbusplus::bus::match::rules::arg0namespace(servName),
+                [this](sdbusplus::message_t& message) {
+                    handleDbusSignalNameOwnerChanged(message);
+                });
+
+            value = getDbusProperty<double>(bus, servName, path, sensorIntf,
+                                            "Value");
+        }
+    }
+    catch (const std::exception& e)
+    {
+        value = std::numeric_limits<double>::quiet_NaN();
+    }
+
+    return;
+}
+
+void DbusSensor::handleDbusSignalNameOwnerChanged(sdbusplus::message_t& msg)
+{
+    try
+    {
+        auto [name, oldOwner,
+              newOwner] = msg.unpack<std::string, std::string, std::string>();
+
+        if (!oldOwner.empty() && !name.empty())
+        {
+            if (name == servName)
+            {
+                // Connection removed
+
+                value = std::numeric_limits<double>::quiet_NaN();
+                virtualSensor.updateVirtualSensor();
+            }
+        }
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Error in dbusSensor NameOwnerChanged: {PATH}  {ERROR}",
+                   "PATH", path, "ERROR", e);
+    }
+}
+
+void DbusSensor::handleDbusSignalPropChange(sdbusplus::message_t& msg)
+{
+    try
+    {
+        using SensorValuePropertiesVariant = sdbusplus::server::xyz::
+            openbmc_project::sensor::Value::PropertiesVariant;
+        auto [msgIfce, msgData] =
+            msg.unpack<std::string,
+                       std::map<std::string, SensorValuePropertiesVariant>>();
+
+        if (auto itr = msgData.find("Value"); itr != msgData.end())
+        {
+            double tmpValue = std::get<double>(itr->second);
+            if (!std::isfinite(tmpValue))
+            {
+                if (std::isnan(value))
+                {
+                    return;
+                }
+
+                tmpValue = std::numeric_limits<double>::quiet_NaN();
+            }
+
+            if (tmpValue != value)
+            {
+                value = tmpValue;
+                virtualSensor.updateVirtualSensor();
+            }
+        }
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Error in dbusSensor PropertyChange: {PATH}  {ERROR}",
+                   "PATH", path, "ERROR", e);
+    }
+}
+
+void DbusSensor::handleDbusSignalRemove(sdbusplus::message_t& msg)
+{
+    try
+    {
+        auto objPath = msg.unpack<sdbusplus::message::object_path>();
+
+        if (this->path == objPath)
+        {
+            value = std::numeric_limits<double>::quiet_NaN();
+            virtualSensor.updateVirtualSensor();
+        }
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Error in dbusSensor interfaceRemove: {PATH}  {ERROR}",
+                   "PATH", path, "ERROR", e);
+    }
+}
+
+} // namespace phosphor::virtual_sensor
diff --git a/src/dbusSensor.hpp b/src/dbusSensor.hpp
new file mode 100644
index 0000000..41d8c69
--- /dev/null
+++ b/src/dbusSensor.hpp
@@ -0,0 +1,66 @@
+#pragma once
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+
+namespace phosphor::virtual_sensor
+{
+
+class VirtualSensor;
+
+class DbusSensor
+{
+  public:
+    DbusSensor() = delete;
+    virtual ~DbusSensor() = default;
+
+    /** @brief Constructs DbusSensor
+     *
+     * @param[in] bus     - Handle to system dbus
+     * @param[in] path    - The Dbus path of sensor
+     */
+    DbusSensor(sdbusplus::bus_t& bus, const std::string& path,
+               VirtualSensor& virtualSensor);
+
+    /** @brief Get sensor value from local */
+    double getSensorValue();
+
+  private:
+    /** @brief sdbusplus bus client connection. */
+    sdbusplus::bus_t& bus;
+
+    /** @brief complete path for sensor */
+    std::string path{};
+
+    /** @brief service name for the sensor daemon */
+    std::string servName{};
+
+    /** @brief point to the VirtualSensor */
+    VirtualSensor& virtualSensor;
+
+    /** @brief signal for sensor value change */
+    sdbusplus::bus::match_t signalPropChange;
+
+    /** @brief signal for sensor interface remove */
+    sdbusplus::bus::match_t signalRemove;
+
+    /** @brief Match for this dbus sensor service destroy  */
+    std::unique_ptr<sdbusplus::bus::match_t> signalNameOwnerChanged;
+
+    /** @brief dbus sensor value */
+    double value = std::numeric_limits<double>::quiet_NaN();
+
+    /** @brief Get sensor value property from D-bus interface */
+    void initSensorValue();
+
+    /** @brief Handle for this dbus sensor NameOwnerChanged */
+    void handleDbusSignalNameOwnerChanged(sdbusplus::message_t& msg);
+
+    /** @brief Handle for this dbus sensor PropertyChanged */
+    void handleDbusSignalPropChange(sdbusplus::message_t& msg);
+
+    /** @brief Handle for this dbus sensor InterfaceRemove */
+    void handleDbusSignalRemove(sdbusplus::message_t& msg);
+};
+
+} // namespace phosphor::virtual_sensor
diff --git a/src/dbusUtils.cpp b/src/dbusUtils.cpp
new file mode 100644
index 0000000..1096ed0
--- /dev/null
+++ b/src/dbusUtils.cpp
@@ -0,0 +1,81 @@
+#include "dbusUtils.hpp"
+
+#include <xyz/openbmc_project/ObjectMapper/common.hpp>
+
+const char* propIntf = "org.freedesktop.DBus.Properties";
+const char* mapperBusName = "xyz.openbmc_project.ObjectMapper";
+const char* mapperPath = "/xyz/openbmc_project/object_mapper";
+const char* mapperIntf =
+    sdbusplus::common::xyz::openbmc_project::ObjectMapper::interface;
+
+const char* methodGetObject = "GetObject";
+const char* methodGet = "Get";
+const char* methodSet = "Set";
+
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+std::string getService(sdbusplus::bus_t& bus, const std::string& path,
+                       const char* intf)
+{
+    /* Get mapper object for sensor path */
+    auto mapper = bus.new_method_call(mapperBusName, mapperPath, mapperIntf,
+                                      methodGetObject);
+
+    mapper.append(path.c_str());
+    mapper.append(std::vector<std::string>({intf}));
+
+    std::unordered_map<std::string, std::vector<std::string>> resp;
+
+    try
+    {
+        auto msg = bus.call(mapper);
+        msg.read(resp);
+    }
+    catch (const sdbusplus::exception_t& ex)
+    {
+        if (ex.name() == std::string(sdbusplus::xyz::openbmc_project::Common::
+                                         Error::ResourceNotFound::errName))
+        {
+            // The service isn't on D-Bus yet.
+            return std::string{};
+        }
+        else if (ex.name() == std::string("org.freedesktop.DBus.Error.Timeout"))
+        {
+            lg2::info("Mapper timeout while looking up {PATH}", "PATH", path);
+            return std::string{};
+        }
+
+        throw;
+    }
+
+    if (resp.begin() == resp.end())
+    {
+        // Shouldn't happen, if the mapper can't find it it is handled above.
+        throw std::runtime_error("Unable to find Object: " + path);
+    }
+
+    return resp.begin()->first;
+}
+
+int setDbusProperty(sdbusplus::bus_t& bus, const std::string& service,
+                    const std::string& path, const std::string& intf,
+                    const std::string& property, const Value& value)
+{
+    try
+    {
+        auto method = bus.new_method_call(service.c_str(), path.c_str(),
+                                          propIntf, methodSet);
+        method.append(intf, property, value);
+        auto msg = bus.call(method);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error(
+            "Failed to set dbus property. service:{SERVICE} path:{PATH} intf:{INTF} Property:{PROP},{ERROR}",
+            "SERVICE", service, "PATH", path, "INTF", intf, "PROP", property,
+            "ERROR", e);
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/src/dbusUtils.hpp b/src/dbusUtils.hpp
new file mode 100644
index 0000000..4f99872
--- /dev/null
+++ b/src/dbusUtils.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+using Value = std::variant<int64_t, double, std::string, bool>;
+
+std::string getService(sdbusplus::bus_t& bus, const std::string& path,
+                       const char* intf);
+
+template <typename T>
+
+T getDbusProperty(sdbusplus::bus_t& bus, const std::string& service,
+                  const std::string& path, const std::string& intf,
+                  const std::string& property)
+{
+    Value value;
+
+    auto method = bus.new_method_call(service.c_str(), path.c_str(),
+                                      "org.freedesktop.DBus.Properties", "Get");
+
+    method.append(intf, property);
+
+    try
+    {
+        auto msg = bus.call(method);
+        msg.read(value);
+    }
+    catch (const sdbusplus::exception_t& ex)
+    {
+        return std::numeric_limits<T>::quiet_NaN();
+    }
+
+    return std::get<T>(value);
+}
+
+int setDbusProperty(sdbusplus::bus_t& bus, const std::string& service,
+                    const std::string& path, const std::string& intf,
+                    const std::string& property, const Value& value);
diff --git a/src/exprtkTools.hpp b/src/exprtkTools.hpp
new file mode 100644
index 0000000..936b134
--- /dev/null
+++ b/src/exprtkTools.hpp
@@ -0,0 +1,112 @@
+/*
+ * This define will disable the ability for expressions to have comments.
+ * Expressions that have comments when parsed with a build that has this
+ * option, will result in a compilation failure.
+ */
+// #define exprtk_disable_comments
+/*
+ * This define will disable the loop-wise 'break' and 'continue'
+ * capabilities. Any expression that contains those keywords will result
+ * in a compilation failure.
+ */
+#define exprtk_disable_break_continue
+/*
+ * This define will disable the short-circuit '&' (and) and '|' (or)
+ * operators
+ */
+#define exprtk_disable_sc_andor
+/*
+ * This define will disable all enhanced features such as strength
+ * reduction and special function optimisations and expression specific
+ * type instantiations. This feature will reduce compilation times and
+ * binary sizes but will also result in massive performance degradation
+ * of expression evaluations.
+ */
+#define exprtk_disable_enhanced_features
+/*
+ * This define will disable all string processing capabilities. Any
+ * expression that contains a string or string related syntax will result
+ * in a compilation failure.
+ */
+#define exprtk_disable_string_capabilities
+
+#define exprtk_disable_rtl_io_file
+#define exprtk_disable_return_statement
+#define exprtk_disable_rtl_io
+#define exprtk_disable_superscalar_unroll
+
+/* include main exprtk header library */
+#include <exprtk.hpp>
+
+#include <cmath>
+#include <limits>
+#include <numeric>
+
+/* For floating types. (float, double, long double et al) */
+template <typename T>
+struct FuncMaxIgnoreNaN : public exprtk::ivararg_function<T>
+{
+    FuncMaxIgnoreNaN()
+    {
+        exprtk::set_min_num_args(*this, 2);
+        exprtk::set_max_num_args(*this, 255);
+    }
+
+    inline T operator()(const std::vector<T>& argList)
+    {
+        return std::reduce(std::begin(argList), std::end(argList),
+                           std::numeric_limits<double>::quiet_NaN(),
+                           [](auto a, auto b) {
+                               if (std::isnan(b))
+                               {
+                                   return a;
+                               }
+                               if (std::isnan(a))
+                               {
+                                   return b;
+                               }
+                               return std::max(a, b);
+                           });
+    }
+};
+
+template <typename T>
+struct FuncSumIgnoreNaN : public exprtk::ivararg_function<T>
+{
+    inline T operator()(const std::vector<T>& argList)
+    {
+        return std::reduce(std::begin(argList), std::end(argList),
+                           std::numeric_limits<double>::quiet_NaN(),
+                           [](auto a, auto b) {
+                               if (std::isnan(b))
+                               {
+                                   return a;
+                               }
+                               if (std::isnan(a))
+                               {
+                                   return b;
+                               }
+                               return a + b;
+                           });
+    }
+};
+
+template <typename T>
+struct FuncIfNan : public exprtk::ifunction<T>
+{
+    using exprtk::ifunction<T>::operator();
+
+    FuncIfNan() : exprtk::ifunction<T>(2) {}
+
+    inline T operator()(const T& arg1, const T& arg2)
+    {
+        if (std::isnan(arg1))
+        {
+            return arg2;
+        }
+        else
+        {
+            return arg1;
+        }
+    }
+};
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..177a0e0
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,24 @@
+#include "virtualSensor.hpp"
+
+#include <sdbusplus/server.hpp>
+
+int main()
+{
+    // Get a handle to system dbus
+    auto bus = sdbusplus::bus::new_default();
+
+    // Add the ObjectManager interface
+    sdbusplus::server::manager_t objManager(bus,
+                                            "/xyz/openbmc_project/sensors");
+
+    // Create an virtual sensors object
+    phosphor::virtual_sensor::VirtualSensors virtualSensors(bus);
+
+    // Request service bus name
+    bus.request_name("xyz.openbmc_project.VirtualSensor");
+
+    // Run the dbus loop.
+    bus.process_loop();
+
+    return 0;
+}
diff --git a/src/meson.build b/src/meson.build
new file mode 100644
index 0000000..43f7f96
--- /dev/null
+++ b/src/meson.build
@@ -0,0 +1,19 @@
+executable(
+    'virtual-sensor',
+    [
+        'calculate.cpp',
+        'dbusSensor.cpp',
+        'dbusUtils.cpp',
+        'main.cpp',
+        'virtualSensor.cpp',
+    ],
+    dependencies: [
+        dependency('nlohmann_json', include_type: 'system'),
+        dependency('phosphor-dbus-interfaces'),
+        dependency('phosphor-logging'),
+        dependency('sdbusplus'),
+        exprtk,
+    ],
+    install: true,
+    install_dir: get_option('libexecdir') / meson.project_name(),
+)
diff --git a/src/thresholds.hpp b/src/thresholds.hpp
new file mode 100644
index 0000000..1aa8e37
--- /dev/null
+++ b/src/thresholds.hpp
@@ -0,0 +1,614 @@
+#pragma once
+
+#include "dbusUtils.hpp"
+
+#include <phosphor-logging/commit.hpp>
+#include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
+#include <xyz/openbmc_project/Sensor/Threshold/HardShutdown/server.hpp>
+#include <xyz/openbmc_project/Sensor/Threshold/PerformanceLoss/server.hpp>
+#include <xyz/openbmc_project/Sensor/Threshold/SoftShutdown/server.hpp>
+#include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>
+#include <xyz/openbmc_project/Sensor/Threshold/event.hpp>
+#include <xyz/openbmc_project/Sensor/Value/server.hpp>
+
+const constexpr char* entityManagerBusName =
+    "xyz.openbmc_project.EntityManager";
+namespace phosphor::virtual_sensor
+{
+
+template <typename... T>
+using ServerObject = typename sdbusplus::server::object_t<T...>;
+
+namespace threshold_ns =
+    sdbusplus::xyz::openbmc_project::Sensor::Threshold::server;
+using Unit = sdbusplus::xyz::openbmc_project::Sensor::server::Value::Unit;
+using CriticalObject = ServerObject<threshold_ns::Critical>;
+using WarningObject = ServerObject<threshold_ns::Warning>;
+using SoftShutdownObject = ServerObject<threshold_ns::SoftShutdown>;
+using HardShutdownObject = ServerObject<threshold_ns::HardShutdown>;
+using PerformanceLossObject = ServerObject<threshold_ns::PerformanceLoss>;
+
+template <typename T>
+struct Threshold;
+
+struct Hysteresis
+{
+    double highHysteresis;
+    double lowHysteresis;
+    auto getHighHysteresis()
+    {
+        return this->highHysteresis;
+    }
+
+    auto getLowHysteresis()
+    {
+        return this->lowHysteresis;
+    }
+
+    auto setHighHysteresis(double value)
+    {
+        this->highHysteresis = value;
+    }
+
+    auto setLowHysteresis(double value)
+    {
+        this->lowHysteresis = value;
+    }
+};
+
+template <typename error>
+auto tryCommit(const std::string& objPath, double value, Unit unit,
+               double thresholdValue)
+    -> std::optional<sdbusplus::message::object_path>
+{
+    try
+    {
+        return lg2::commit(
+            error("SENSOR_NAME", objPath, "READING_VALUE", value, "UNITS", unit,
+                  "THRESHOLD_VALUE", thresholdValue));
+    }
+    catch (std::exception&)
+    {
+        lg2::error(
+            "Failed creating a threshold log entry for {SENSOR} with value {VALUE}",
+            "SENSOR", objPath, "VALUE", value);
+        return std::nullopt;
+    }
+}
+
+static inline void tryResolve(
+    std::optional<sdbusplus::message::object_path>& log)
+{
+    if (log)
+    {
+        try
+        {
+            lg2::resolve(*log);
+        }
+        catch (std::exception&)
+        {
+            lg2::error("Failed to resolve: {LOG}", "LOG", *log);
+        }
+        log.reset();
+    }
+}
+
+template <>
+struct Threshold<WarningObject> : public WarningObject, public Hysteresis
+{
+    static constexpr auto name = "Warning";
+    using WarningObject::WarningObject;
+    using ReadingAboveUpperWarningThreshold = sdbusplus::error::xyz::
+        openbmc_project::sensor::Threshold::ReadingAboveUpperWarningThreshold;
+    using ReadingBelowLowerWarningThreshold = sdbusplus::error::xyz::
+        openbmc_project::sensor::Threshold::ReadingBelowLowerWarningThreshold;
+    /** @brief sdbusplus bus client connection. */
+    sdbusplus::bus_t& bus;
+    std::string objPath;
+    Unit units;
+
+    /** @brief Virtual sensor path/interface in entityManagerDbus.
+     * This 3 value is used to set thresholds
+     */
+    std::string entityPath;
+    std::string entityInterfaceHigh;
+    std::string entityInterfaceLow;
+    std::optional<sdbusplus::message::object_path> assertedHighLog;
+    std::optional<sdbusplus::message::object_path> assertedLowLog;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] path - Path to attach at.
+     *  @param[in] units - units
+     */
+    Threshold(sdbusplus::bus_t& bus, const char* path, Unit units) :
+        WarningObject(bus, path), bus(bus), objPath(std::string(path)),
+        units(units)
+    {}
+
+    auto high()
+    {
+        return WarningObject::warningHigh();
+    }
+    auto low()
+    {
+        return WarningObject::warningLow();
+    }
+
+    template <typename... Args>
+    auto alarmHigh(Args... args)
+    {
+        return warningAlarmHigh(std::forward<Args>(args)...);
+    }
+
+    template <typename... Args>
+    auto alarmLow(Args... args)
+    {
+        return warningAlarmLow(std::forward<Args>(args)...);
+    }
+
+    template <typename V>
+    auto alarmHighSignalAsserted(V value)
+    {
+        assertedHighLog = tryCommit<ReadingAboveUpperWarningThreshold>(
+            objPath, value, units, high());
+        return warningHighAlarmAsserted(value);
+    }
+
+    template <typename... Args>
+    auto alarmHighSignalDeasserted(Args... args)
+    {
+        tryResolve(assertedHighLog);
+        return warningHighAlarmDeasserted(std::forward<Args>(args)...);
+    }
+
+    template <typename V>
+    auto alarmLowSignalAsserted(V value)
+    {
+        assertedLowLog = tryCommit<ReadingBelowLowerWarningThreshold>(
+            objPath, value, units, low());
+        return warningLowAlarmAsserted(value);
+    }
+
+    template <typename... Args>
+    auto alarmLowSignalDeasserted(Args... args)
+    {
+        tryResolve(assertedLowLog);
+        return warningLowAlarmDeasserted(std::forward<Args>(args)...);
+    }
+
+    /** @brief Set value of WarningHigh */
+    virtual double warningHigh(double value)
+    {
+        if (!entityPath.empty() && !entityInterfaceHigh.empty())
+        {
+            // persistThreshold
+            setDbusProperty(bus, entityManagerBusName, entityPath,
+                            entityInterfaceHigh, "Value", value);
+        }
+        return WarningObject::warningHigh(value);
+    }
+
+    /** @brief Set value of WarningLow */
+    virtual double warningLow(double value)
+    {
+        if (!entityPath.empty() && !entityInterfaceLow.empty())
+        {
+            // persistThreshold
+            setDbusProperty(bus, entityManagerBusName, entityPath,
+                            entityInterfaceLow, "Value", value);
+        }
+        return WarningObject::warningLow(value);
+    }
+
+    /** @brief Set the entitymanager interface corresponding to virtualsensor
+     * warningLow
+     */
+    void setEntityInterfaceLow(const std::string& interfaceLow)
+    {
+        entityInterfaceLow = interfaceLow;
+    }
+
+    /** @brief Set the entitymanager interface corresponding to virtualsensor
+     * warningHigh
+     */
+    void setEntityInterfaceHigh(const std::string& interfaceHigh)
+    {
+        entityInterfaceHigh = interfaceHigh;
+    }
+
+    /** @brief Set the entitymanager path corresponding to virtualsensor warning
+     */
+    void setEntityPath(const std::string& path)
+    {
+        entityPath = path;
+    }
+};
+
+template <>
+struct Threshold<CriticalObject> : public CriticalObject, public Hysteresis
+{
+    static constexpr auto name = "Critical";
+
+    /** @brief sdbusplus bus client connection. */
+    sdbusplus::bus_t& bus;
+    std::string objPath;
+    Unit units;
+
+    /** @brief Virtual sensor path/interface in entityManagerDbus.
+     * This 3 value is used to set thresholds
+     */
+    std::string entityPath;
+    std::string entityInterfaceHigh;
+    std::string entityInterfaceLow;
+    std::optional<sdbusplus::message::object_path> assertedHighLog;
+    std::optional<sdbusplus::message::object_path> assertedLowLog;
+
+    using CriticalObject::CriticalObject;
+    using ReadingAboveUpperCriticalThreshold = sdbusplus::error::xyz::
+        openbmc_project::sensor::Threshold::ReadingAboveUpperCriticalThreshold;
+    using ReadingBelowLowerCriticalThreshold = sdbusplus::error::xyz::
+        openbmc_project::sensor::Threshold::ReadingBelowLowerCriticalThreshold;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] path - Path to attach at.
+     *  @param[in] units - units
+     */
+    Threshold(sdbusplus::bus_t& bus, const char* path, Unit units) :
+        CriticalObject(bus, path), bus(bus), objPath(std::string(path)),
+        units(units)
+    {}
+
+    auto high()
+    {
+        return CriticalObject::criticalHigh();
+    }
+    auto low()
+    {
+        return CriticalObject::criticalLow();
+    }
+
+    template <typename... Args>
+    auto alarmHigh(Args... args)
+    {
+        return criticalAlarmHigh(std::forward<Args>(args)...);
+    }
+
+    template <typename... Args>
+    auto alarmLow(Args... args)
+    {
+        return criticalAlarmLow(std::forward<Args>(args)...);
+    }
+
+    template <typename V>
+    auto alarmHighSignalAsserted(V value)
+    {
+        assertedHighLog = tryCommit<ReadingAboveUpperCriticalThreshold>(
+            objPath, value, units, high());
+        return criticalHighAlarmAsserted(value);
+    }
+
+    template <typename... Args>
+    auto alarmHighSignalDeasserted(Args... args)
+    {
+        tryResolve(assertedHighLog);
+        return criticalHighAlarmDeasserted(std::forward<Args>(args)...);
+    }
+
+    template <typename V>
+    auto alarmLowSignalAsserted(V value)
+    {
+        assertedLowLog = tryCommit<ReadingBelowLowerCriticalThreshold>(
+            objPath, value, units, low());
+        return criticalLowAlarmAsserted(value);
+    }
+
+    template <typename... Args>
+    auto alarmLowSignalDeasserted(Args... args)
+    {
+        tryResolve(assertedLowLog);
+        return criticalLowAlarmDeasserted(std::forward<Args>(args)...);
+    }
+
+    /** @brief Set value of CriticalHigh */
+    virtual double criticalHigh(double value)
+    {
+        // persistThreshold
+        if (!entityPath.empty() && !entityInterfaceHigh.empty())
+        {
+            setDbusProperty(bus, entityManagerBusName, entityPath,
+                            entityInterfaceHigh, "Value", value);
+        }
+        return CriticalObject::criticalHigh(value);
+    }
+
+    /** @brief Set value of CriticalLow */
+    virtual double criticalLow(double value)
+    {
+        if (!entityPath.empty() && !entityInterfaceLow.empty())
+        {
+            setDbusProperty(bus, entityManagerBusName, entityPath,
+                            entityInterfaceLow, "Value", value);
+        }
+        return CriticalObject::criticalLow(value);
+    }
+
+    /** @brief Set the entitymanager interface corresponding to virtualsensor
+     * criticalLow
+     */
+    void setEntityInterfaceLow(const std::string& interfaceLow)
+    {
+        entityInterfaceLow = interfaceLow;
+    }
+
+    /** @brief Set the entitymanager interface corresponding to virtualsensor
+     * criticalLow
+     */
+    void setEntityInterfaceHigh(const std::string& interfaceHigh)
+    {
+        entityInterfaceHigh = interfaceHigh;
+    }
+
+    /** @brief Set the entitymanager path corresponding to virtualsensor warning
+     */
+    void setEntityPath(const std::string& path)
+    {
+        entityPath = path;
+    }
+};
+
+template <>
+struct Threshold<SoftShutdownObject> :
+    public SoftShutdownObject,
+    public Hysteresis
+{
+    static constexpr auto name = "SoftShutdown";
+
+    /** @brief sdbusplus bus client connection. */
+    sdbusplus::bus_t& bus;
+    std::string objPath;
+    Unit units;
+
+    using SoftShutdownObject::SoftShutdownObject;
+    using ReadingAboveUpperSoftShutdownThreshold =
+        sdbusplus::error::xyz::openbmc_project::sensor::Threshold::
+            ReadingAboveUpperSoftShutdownThreshold;
+    using ReadingBelowLowerSoftShutdownThreshold =
+        sdbusplus::error::xyz::openbmc_project::sensor::Threshold::
+            ReadingBelowLowerSoftShutdownThreshold;
+    std::optional<sdbusplus::message::object_path> assertedHighLog;
+    std::optional<sdbusplus::message::object_path> assertedLowLog;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] path - Path to attach at.
+     *  @param[in] units - units
+     */
+    Threshold(sdbusplus::bus_t& bus, const char* path, Unit units) :
+        SoftShutdownObject(bus, path), bus(bus), objPath(std::string(path)),
+        units(units)
+    {}
+
+    auto high()
+    {
+        return softShutdownHigh();
+    }
+    auto low()
+    {
+        return softShutdownLow();
+    }
+
+    template <typename... Args>
+    auto alarmHigh(Args... args)
+    {
+        return softShutdownAlarmHigh(std::forward<Args>(args)...);
+    }
+
+    template <typename... Args>
+    auto alarmLow(Args... args)
+    {
+        return softShutdownAlarmLow(std::forward<Args>(args)...);
+    }
+
+    template <typename V>
+    auto alarmHighSignalAsserted(V value)
+    {
+        assertedHighLog = tryCommit<ReadingAboveUpperSoftShutdownThreshold>(
+            objPath, value, units, high());
+        return softShutdownHighAlarmAsserted(value);
+    }
+
+    template <typename... Args>
+    auto alarmHighSignalDeasserted(Args... args)
+    {
+        tryResolve(assertedHighLog);
+        return softShutdownHighAlarmDeasserted(std::forward<Args>(args)...);
+    }
+
+    template <typename V>
+    auto alarmLowSignalAsserted(V value)
+    {
+        assertedLowLog = tryCommit<ReadingBelowLowerSoftShutdownThreshold>(
+            objPath, value, units, low());
+        return softShutdownLowAlarmAsserted(value);
+    }
+
+    template <typename... Args>
+    auto alarmLowSignalDeasserted(Args... args)
+    {
+        tryResolve(assertedLowLog);
+        return softShutdownLowAlarmDeasserted(std::forward<Args>(args)...);
+    }
+};
+
+template <>
+struct Threshold<HardShutdownObject> :
+    public HardShutdownObject,
+    public Hysteresis
+{
+    static constexpr auto name = "HardShutdown";
+
+    /** @brief sdbusplus bus client connection. */
+    sdbusplus::bus_t& bus;
+    std::string objPath;
+    Unit units;
+
+    using HardShutdownObject::HardShutdownObject;
+    using ReadingAboveUpperHardShutdownThreshold =
+        sdbusplus::error::xyz::openbmc_project::sensor::Threshold::
+            ReadingAboveUpperHardShutdownThreshold;
+    using ReadingBelowLowerHardShutdownThreshold =
+        sdbusplus::error::xyz::openbmc_project::sensor::Threshold::
+            ReadingBelowLowerHardShutdownThreshold;
+    std::optional<sdbusplus::message::object_path> assertedHighLog;
+    std::optional<sdbusplus::message::object_path> assertedLowLog;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] path - Path to attach at.
+     *  @param[in] units - units
+     */
+    Threshold(sdbusplus::bus_t& bus, const char* path, Unit units) :
+        HardShutdownObject(bus, path), bus(bus), objPath(std::string(path)),
+        units(units)
+    {}
+
+    auto high()
+    {
+        return hardShutdownHigh();
+    }
+    auto low()
+    {
+        return hardShutdownLow();
+    }
+
+    template <typename... Args>
+    auto alarmHigh(Args... args)
+    {
+        return hardShutdownAlarmHigh(std::forward<Args>(args)...);
+    }
+
+    template <typename... Args>
+    auto alarmLow(Args... args)
+    {
+        return hardShutdownAlarmLow(std::forward<Args>(args)...);
+    }
+
+    template <typename V>
+    auto alarmHighSignalAsserted(V value)
+    {
+        assertedHighLog = tryCommit<ReadingAboveUpperHardShutdownThreshold>(
+            objPath, value, units, high());
+        return hardShutdownHighAlarmAsserted(value);
+    }
+
+    template <typename... Args>
+    auto alarmHighSignalDeasserted(Args... args)
+    {
+        tryResolve(assertedHighLog);
+        return hardShutdownHighAlarmDeasserted(std::forward<Args>(args)...);
+    }
+
+    template <typename V>
+    auto alarmLowSignalAsserted(V value)
+    {
+        assertedLowLog = tryCommit<ReadingBelowLowerHardShutdownThreshold>(
+            objPath, value, units, low());
+        return hardShutdownLowAlarmAsserted(value);
+    }
+
+    template <typename... Args>
+    auto alarmLowSignalDeasserted(Args... args)
+    {
+        tryResolve(assertedLowLog);
+        return hardShutdownLowAlarmDeasserted(std::forward<Args>(args)...);
+    }
+};
+
+template <>
+struct Threshold<PerformanceLossObject> :
+    public PerformanceLossObject,
+    public Hysteresis
+{
+    static constexpr auto name = "PerformanceLoss";
+    /** @brief sdbusplus bus client connection. */
+    sdbusplus::bus_t& bus;
+    std::string objPath;
+    Unit units;
+
+    using PerformanceLossObject::PerformanceLossObject;
+    using ReadingAboveUpperPerformanceLossThreshold =
+        sdbusplus::error::xyz::openbmc_project::sensor::Threshold::
+            ReadingAboveUpperPerformanceLossThreshold;
+    using ReadingBelowLowerPerformanceLossThreshold =
+        sdbusplus::error::xyz::openbmc_project::sensor::Threshold::
+            ReadingBelowLowerPerformanceLossThreshold;
+    double performanceLossHighHysteresis;
+    double performanceLossLowHysteresis;
+    std::optional<sdbusplus::message::object_path> assertedHighLog;
+    std::optional<sdbusplus::message::object_path> assertedLowLog;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] path - Path to attach at.
+     *  @param[in] units - units
+     */
+    Threshold(sdbusplus::bus_t& bus, const char* path, Unit units) :
+        PerformanceLossObject(bus, path), bus(bus), objPath(std::string(path)),
+        units(units)
+    {}
+
+    auto high()
+    {
+        return performanceLossHigh();
+    }
+    auto low()
+    {
+        return performanceLossLow();
+    }
+
+    template <typename... Args>
+    auto alarmHigh(Args... args)
+    {
+        return performanceLossAlarmHigh(std::forward<Args>(args)...);
+    }
+
+    template <typename... Args>
+    auto alarmLow(Args... args)
+    {
+        return performanceLossAlarmLow(std::forward<Args>(args)...);
+    }
+
+    template <typename V>
+    auto alarmHighSignalAsserted(V value)
+    {
+        assertedHighLog = tryCommit<ReadingAboveUpperPerformanceLossThreshold>(
+            objPath, value, units, high());
+        return performanceLossHighAlarmAsserted(value);
+    }
+
+    template <typename... Args>
+    auto alarmHighSignalDeasserted(Args... args)
+    {
+        tryResolve(assertedHighLog);
+        return performanceLossHighAlarmDeasserted(std::forward<Args>(args)...);
+    }
+
+    template <typename V>
+    auto alarmLowSignalAsserted(V value)
+    {
+        assertedLowLog = tryCommit<ReadingBelowLowerPerformanceLossThreshold>(
+            objPath, value, units, low());
+        return performanceLossLowAlarmAsserted(value);
+    }
+
+    template <typename... Args>
+    auto alarmLowSignalDeasserted(Args... args)
+    {
+        tryResolve(assertedLowLog);
+        return performanceLossLowAlarmDeasserted(std::forward<Args>(args)...);
+    }
+};
+
+} // namespace phosphor::virtual_sensor
diff --git a/src/virtualSensor.cpp b/src/virtualSensor.cpp
new file mode 100644
index 0000000..c6bc6da
--- /dev/null
+++ b/src/virtualSensor.cpp
@@ -0,0 +1,941 @@
+#include "virtualSensor.hpp"
+
+#include "calculate.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+#include <fstream>
+
+static constexpr auto sensorDbusPath = "/xyz/openbmc_project/sensors/";
+static constexpr auto vsThresholdsIfaceSuffix = ".Thresholds";
+static constexpr auto defaultHysteresis = 0;
+
+PHOSPHOR_LOG2_USING_WITH_FLAGS;
+
+namespace phosphor::virtual_sensor
+{
+
+FuncMaxIgnoreNaN<double> VirtualSensor::funcMaxIgnoreNaN;
+FuncSumIgnoreNaN<double> VirtualSensor::funcSumIgnoreNaN;
+FuncIfNan<double> VirtualSensor::funcIfNan;
+
+std::map<std::string, ValueIface::Unit> unitMap = {
+    {"temperature", ValueIface::Unit::DegreesC},
+    {"fan_tach", ValueIface::Unit::RPMS},
+    {"fan_pwm", ValueIface::Unit::Percent},
+    {"voltage", ValueIface::Unit::Volts},
+    {"altitude", ValueIface::Unit::Meters},
+    {"current", ValueIface::Unit::Amperes},
+    {"power", ValueIface::Unit::Watts},
+    {"energy", ValueIface::Unit::Joules},
+    {"utilization", ValueIface::Unit::Percent},
+    {"airflow", ValueIface::Unit::CFM},
+    {"pressure", ValueIface::Unit::Pascals}};
+
+void printParams(const VirtualSensor::ParamMap& paramMap)
+{
+    for (const auto& p : paramMap)
+    {
+        const auto& p1 = p.first;
+        const auto& p2 = p.second;
+        auto val = p2->getParamValue();
+        debug("Parameter: {PARAM} = {VALUE}", "PARAM", p1, "VALUE", val);
+    }
+}
+
+double SensorParam::getParamValue()
+{
+    switch (paramType)
+    {
+        case constParam:
+            return value;
+            break;
+        case dbusParam:
+            return dbusSensor->getSensorValue();
+            break;
+        default:
+            throw std::invalid_argument("param type not supported");
+    }
+}
+
+using AssociationList =
+    std::vector<std::tuple<std::string, std::string, std::string>>;
+
+AssociationList getAssociationsFromJson(const Json& j)
+{
+    AssociationList assocs{};
+    try
+    {
+        j.get_to(assocs);
+    }
+    catch (const std::exception& ex)
+    {
+        error("Failed to parse association: {ERROR}", "ERROR", ex);
+    }
+    return assocs;
+}
+
+template <typename U>
+struct VariantToNumber
+{
+    template <typename T>
+    U operator()(const T& t) const
+    {
+        if constexpr (std::is_convertible<T, U>::value)
+        {
+            return static_cast<U>(t);
+        }
+        throw std::invalid_argument("Invalid number type in config\n");
+    }
+};
+
+template <typename U>
+U getNumberFromConfig(const PropertyMap& map, const std::string& name,
+                      bool required,
+                      U defaultValue = std::numeric_limits<U>::quiet_NaN())
+{
+    if (auto itr = map.find(name); itr != map.end())
+    {
+        return std::visit(VariantToNumber<U>(), itr->second);
+    }
+    else if (required)
+    {
+        error("Required field {NAME} missing in config", "NAME", name);
+        throw std::invalid_argument("Required field missing in config");
+    }
+    return defaultValue;
+}
+
+const std::string getThresholdType(const std::string& direction,
+                                   const std::string& severity)
+{
+    std::string suffix;
+
+    if (direction == "less than")
+    {
+        suffix = "Low";
+    }
+    else if (direction == "greater than")
+    {
+        suffix = "High";
+    }
+    else
+    {
+        throw std::invalid_argument(
+            "Invalid threshold direction specified in entity manager");
+    }
+    return severity + suffix;
+}
+
+std::string getSeverityField(const PropertyMap& propertyMap)
+{
+    static const std::array thresholdTypes{
+        "Warning", "Critical", "PerformanceLoss", "SoftShutdown",
+        "HardShutdown"};
+
+    std::string severity;
+    if (auto itr = propertyMap.find("Severity"); itr != propertyMap.end())
+    {
+        /* Severity should be a string, but can be an unsigned int */
+        if (std::holds_alternative<std::string>(itr->second))
+        {
+            severity = std::get<std::string>(itr->second);
+            if (0 == std::ranges::count(thresholdTypes, severity))
+            {
+                throw std::invalid_argument(
+                    "Invalid threshold severity specified in entity manager");
+            }
+        }
+        else
+        {
+            auto sev =
+                getNumberFromConfig<uint64_t>(propertyMap, "Severity", true);
+            /* Checking bounds ourselves so we throw invalid argument on
+             * invalid user input */
+            if (sev >= thresholdTypes.size())
+            {
+                throw std::invalid_argument(
+                    "Invalid threshold severity specified in entity manager");
+            }
+            severity = thresholdTypes.at(sev);
+        }
+    }
+    return severity;
+}
+
+void parseThresholds(Json& thresholds, const PropertyMap& propertyMap,
+                     const std::string& entityInterface = "")
+{
+    std::string direction;
+
+    auto value = getNumberFromConfig<double>(propertyMap, "Value", true);
+
+    auto severity = getSeverityField(propertyMap);
+
+    if (auto itr = propertyMap.find("Direction"); itr != propertyMap.end())
+    {
+        direction = std::get<std::string>(itr->second);
+    }
+
+    auto threshold = getThresholdType(direction, severity);
+    thresholds[threshold] = value;
+
+    auto hysteresis =
+        getNumberFromConfig<double>(propertyMap, "Hysteresis", false);
+    if (hysteresis != std::numeric_limits<double>::quiet_NaN())
+    {
+        thresholds[threshold + "Hysteresis"] = hysteresis;
+    }
+
+    if (!entityInterface.empty())
+    {
+        thresholds[threshold + "Direction"] = entityInterface;
+    }
+}
+
+void VirtualSensor::parseConfigInterface(const PropertyMap& propertyMap,
+                                         const std::string& sensorType,
+                                         const std::string& interface)
+{
+    /* Parse sensors / DBus params */
+    if (auto itr = propertyMap.find("Sensors"); itr != propertyMap.end())
+    {
+        auto sensors = std::get<std::vector<std::string>>(itr->second);
+        for (auto sensor : sensors)
+        {
+            std::replace(sensor.begin(), sensor.end(), ' ', '_');
+            auto sensorObjPath = sensorDbusPath + sensorType + "/" + sensor;
+
+            auto paramPtr =
+                std::make_unique<SensorParam>(bus, sensorObjPath, *this);
+            symbols.create_variable(sensor);
+            paramMap.emplace(std::move(sensor), std::move(paramPtr));
+        }
+    }
+    /* Get expression string */
+    if (!calculationIfaces.contains(interface))
+    {
+        throw std::invalid_argument("Invalid expression in interface");
+    }
+    exprStr = interface;
+
+    /* Get optional min and max input and output values */
+    ValueIface::maxValue(
+        getNumberFromConfig<double>(propertyMap, "MaxValue", false));
+    ValueIface::minValue(
+        getNumberFromConfig<double>(propertyMap, "MinValue", false));
+    maxValidInput =
+        getNumberFromConfig<double>(propertyMap, "MaxValidInput", false,
+                                    std::numeric_limits<double>::infinity());
+    minValidInput =
+        getNumberFromConfig<double>(propertyMap, "MinValidInput", false,
+                                    -std::numeric_limits<double>::infinity());
+}
+
+void VirtualSensor::initVirtualSensor(const Json& sensorConfig,
+                                      const std::string& objPath,
+                                      const std::string& type)
+{
+    static const Json empty{};
+
+    units = unitMap.at(type);
+
+    /* Get threshold values if defined in config */
+    auto threshold = sensorConfig.value("Threshold", empty);
+
+    createThresholds(threshold, objPath, units);
+
+    /* Get MaxValue, MinValue setting if defined in config */
+    auto confDesc = sensorConfig.value("Desc", empty);
+    if (auto maxConf = confDesc.find("MaxValue");
+        maxConf != confDesc.end() && maxConf->is_number())
+    {
+        ValueIface::maxValue(maxConf->get<double>());
+    }
+    if (auto minConf = confDesc.find("MinValue");
+        minConf != confDesc.end() && minConf->is_number())
+    {
+        ValueIface::minValue(minConf->get<double>());
+    }
+
+    /* Get optional association */
+    auto assocJson = sensorConfig.value("Associations", empty);
+    if (!assocJson.empty())
+    {
+        auto assocs = getAssociationsFromJson(assocJson);
+        if (!assocs.empty())
+        {
+            associationIface =
+                std::make_unique<AssociationObject>(bus, objPath.c_str());
+            associationIface->associations(assocs);
+        }
+    }
+
+    /* Get expression string */
+    static constexpr auto exprKey = "Expression";
+    if (sensorConfig.contains(exprKey))
+    {
+        auto& ref = sensorConfig.at(exprKey);
+        if (ref.is_array())
+        {
+            exprStr = std::string{};
+            for (auto& s : ref)
+            {
+                exprStr += s;
+            }
+        }
+        else if (ref.is_string())
+        {
+            exprStr = std::string{ref};
+        }
+    }
+
+    /* Get all the parameter listed in configuration */
+    auto params = sensorConfig.value("Params", empty);
+
+    /* Check for constant parameter */
+    const auto& consParams = params.value("ConstParam", empty);
+    if (!consParams.empty())
+    {
+        for (auto& j : consParams)
+        {
+            if (j.find("ParamName") != j.end())
+            {
+                auto paramPtr = std::make_unique<SensorParam>(j["Value"]);
+                std::string name = j["ParamName"];
+                symbols.create_variable(name);
+                paramMap.emplace(std::move(name), std::move(paramPtr));
+            }
+            else
+            {
+                /* Invalid configuration */
+                throw std::invalid_argument(
+                    "ParamName not found in configuration");
+            }
+        }
+    }
+
+    /* Check for dbus parameter */
+    auto dbusParams = params.value("DbusParam", empty);
+    if (!dbusParams.empty())
+    {
+        for (auto& j : dbusParams)
+        {
+            /* Get parameter dbus sensor descriptor */
+            auto desc = j.value("Desc", empty);
+            if ((!desc.empty()) && (j.find("ParamName") != j.end()))
+            {
+                std::string sensorType = desc.value("SensorType", "");
+                std::string name = desc.value("Name", "");
+
+                if (!sensorType.empty() && !name.empty())
+                {
+                    auto path = sensorDbusPath + sensorType + "/" + name;
+                    auto paramPtr =
+                        std::make_unique<SensorParam>(bus, path, *this);
+                    std::string paramName = j["ParamName"];
+                    symbols.create_variable(paramName);
+                    paramMap.emplace(std::move(paramName), std::move(paramPtr));
+                }
+            }
+        }
+    }
+
+    symbols.add_constants();
+    symbols.add_package(vecopsPackage);
+    symbols.add_function("maxIgnoreNaN", funcMaxIgnoreNaN);
+    symbols.add_function("sumIgnoreNaN", funcSumIgnoreNaN);
+    symbols.add_function("ifNan", funcIfNan);
+
+    expression.register_symbol_table(symbols);
+
+    /* parser from exprtk */
+    exprtk::parser<double> parser{};
+    if (!parser.compile(exprStr, expression))
+    {
+        error("Expression compilation failed");
+
+        for (std::size_t i = 0; i < parser.error_count(); ++i)
+        {
+            auto err = parser.get_error(i);
+            error("Error parsing token at {POSITION}: {ERROR}", "POSITION",
+                  err.token.position, "TYPE",
+                  exprtk::parser_error::to_str(err.mode), "ERROR",
+                  err.diagnostic);
+        }
+        throw std::runtime_error("Expression compilation failed");
+    }
+
+    /* Print all parameters for debug purpose only */
+    printParams(paramMap);
+}
+
+void VirtualSensor::createAssociation(const std::string& objPath,
+                                      const std::string& entityPath)
+{
+    if (objPath.empty() || entityPath.empty())
+    {
+        return;
+    }
+
+    std::filesystem::path p(entityPath);
+    auto assocsDbus =
+        AssociationList{{"chassis", "all_sensors", p.parent_path().string()}};
+    associationIface =
+        std::make_unique<AssociationObject>(bus, objPath.c_str());
+    associationIface->associations(assocsDbus);
+}
+
+void VirtualSensor::initVirtualSensor(
+    const InterfaceMap& interfaceMap, const std::string& objPath,
+    const std::string& sensorType, const std::string& calculationIface)
+{
+    Json thresholds;
+    const std::string vsThresholdsIntf =
+        calculationIface + vsThresholdsIfaceSuffix;
+
+    units = unitMap.at(sensorType);
+
+    for (const auto& [interface, propertyMap] : interfaceMap)
+    {
+        /* Each threshold is on it's own interface with a number as a suffix
+         * eg xyz.openbmc_project.Configuration.ModifiedMedian.Thresholds1 */
+        if (interface.find(vsThresholdsIntf) != std::string::npos)
+        {
+            parseThresholds(thresholds, propertyMap, interface);
+        }
+        else if (interface == calculationIface)
+        {
+            parseConfigInterface(propertyMap, sensorType, interface);
+        }
+    }
+
+    createThresholds(thresholds, objPath, units);
+    symbols.add_constants();
+    symbols.add_package(vecopsPackage);
+    expression.register_symbol_table(symbols);
+
+    createAssociation(objPath, entityPath);
+    /* Print all parameters for debug purpose only */
+    printParams(paramMap);
+}
+
+void VirtualSensor::setSensorValue(double value)
+{
+    value = std::clamp(value, ValueIface::minValue(), ValueIface::maxValue());
+    ValueIface::value(value);
+}
+
+double VirtualSensor::calculateValue(const std::string& calculation,
+                                     const VirtualSensor::ParamMap& paramMap)
+{
+    auto iter = calculationIfaces.find(calculation);
+    if (iter == calculationIfaces.end())
+    {
+        return std::numeric_limits<double>::quiet_NaN();
+    }
+
+    std::vector<double> values;
+    for (auto& param : paramMap)
+    {
+        auto& name = param.first;
+        if (auto var = symbols.get_variable(name))
+        {
+            if (!sensorInRange(var->ref()))
+            {
+                continue;
+            }
+            values.push_back(var->ref());
+        }
+    }
+
+    return iter->second(values);
+}
+
+bool VirtualSensor::sensorInRange(double value)
+{
+    if (value <= this->maxValidInput && value >= this->minValidInput)
+    {
+        return true;
+    }
+    return false;
+}
+
+void VirtualSensor::updateVirtualSensor()
+{
+    for (auto& param : paramMap)
+    {
+        auto& name = param.first;
+        auto& data = param.second;
+        if (auto var = symbols.get_variable(name))
+        {
+            var->ref() = data->getParamValue();
+        }
+        else
+        {
+            /* Invalid parameter */
+            throw std::invalid_argument("ParamName not found in symbols");
+        }
+    }
+    auto val = (!calculationIfaces.contains(exprStr))
+                   ? expression.value()
+                   : calculateValue(exprStr, paramMap);
+
+    /* Set sensor value to dbus interface */
+    setSensorValue(val);
+    debug("Sensor {NAME} = {VALUE}", "NAME", this->name, "VALUE", val);
+
+    /* Check sensor thresholds and log required message */
+    auto changed = false;
+    auto normal = checkThresholds(val, perfLossIface, changed);
+    normal &= checkThresholds(val, warningIface, changed);
+    normal &= checkThresholds(val, criticalIface, changed);
+    normal &= checkThresholds(val, softShutdownIface, changed);
+    normal &= checkThresholds(val, hardShutdownIface, changed);
+    if (changed && normal)
+    {
+        namespace Events =
+            sdbusplus::event::xyz::openbmc_project::sensor::Threshold;
+
+        try
+        {
+            lg2::commit(Events::SensorReadingNormalRange(
+                "SENSOR_NAME", objPath, "READING_VALUE", val, "UNITS", units));
+        }
+        catch (std::exception&)
+        {
+            lg2::debug("Failed to create normal range event {NAME}", "NAME",
+                       objPath);
+        }
+    }
+}
+
+void VirtualSensor::createThresholds(
+    const Json& threshold, const std::string& objPath, ValueIface::Unit units)
+{
+    if (threshold.empty())
+    {
+        return;
+    }
+    // Only create the threshold interfaces if
+    // at least one of their values is present.
+    if (threshold.contains("CriticalHigh") || threshold.contains("CriticalLow"))
+    {
+        criticalIface = std::make_unique<Threshold<CriticalObject>>(
+            bus, objPath.c_str(), units);
+
+        if (threshold.contains("CriticalHigh"))
+        {
+            criticalIface->setEntityInterfaceHigh(
+                threshold.value("CriticalHighDirection", ""));
+            debug("Sensor Threshold:{NAME} = intf:{INTF}", "NAME", objPath,
+                  "INTF", threshold.value("CriticalHighDirection", ""));
+        }
+        if (threshold.contains("CriticalLow"))
+        {
+            criticalIface->setEntityInterfaceLow(
+                threshold.value("CriticalLowDirection", ""));
+            debug("Sensor Threshold:{NAME} = intf:{INTF}", "NAME", objPath,
+                  "INTF", threshold.value("CriticalLowDirection", ""));
+        }
+
+        criticalIface->setEntityPath(entityPath);
+        debug("Sensor Threshold:{NAME} = path:{PATH}", "NAME", objPath, "PATH",
+              entityPath);
+
+        criticalIface->criticalHigh(threshold.value(
+            "CriticalHigh", std::numeric_limits<double>::quiet_NaN()));
+        criticalIface->criticalLow(threshold.value(
+            "CriticalLow", std::numeric_limits<double>::quiet_NaN()));
+        criticalIface->setHighHysteresis(
+            threshold.value("CriticalHighHysteresis", defaultHysteresis));
+        criticalIface->setLowHysteresis(
+            threshold.value("CriticalLowHysteresis", defaultHysteresis));
+    }
+
+    if (threshold.contains("WarningHigh") || threshold.contains("WarningLow"))
+    {
+        warningIface = std::make_unique<Threshold<WarningObject>>(
+            bus, objPath.c_str(), units);
+
+        if (threshold.contains("WarningHigh"))
+        {
+            warningIface->setEntityInterfaceHigh(
+                threshold.value("WarningHighDirection", ""));
+            debug("Sensor Threshold:{NAME} = intf:{INTF}", "NAME", objPath,
+                  "INTF", threshold.value("WarningHighDirection", ""));
+        }
+        if (threshold.contains("WarningLow"))
+        {
+            warningIface->setEntityInterfaceLow(
+                threshold.value("WarningLowDirection", ""));
+            debug("Sensor Threshold:{NAME} = intf:{INTF}", "NAME", objPath,
+                  "INTF", threshold.value("WarningLowDirection", ""));
+        }
+
+        warningIface->setEntityPath(entityPath);
+        debug("Sensor Threshold:{NAME} = path:{PATH}", "NAME", objPath, "PATH",
+              entityPath);
+
+        warningIface->warningHigh(threshold.value(
+            "WarningHigh", std::numeric_limits<double>::quiet_NaN()));
+        warningIface->warningLow(threshold.value(
+            "WarningLow", std::numeric_limits<double>::quiet_NaN()));
+        warningIface->setHighHysteresis(
+            threshold.value("WarningHighHysteresis", defaultHysteresis));
+        warningIface->setLowHysteresis(
+            threshold.value("WarningLowHysteresis", defaultHysteresis));
+    }
+
+    if (threshold.contains("HardShutdownHigh") ||
+        threshold.contains("HardShutdownLow"))
+    {
+        hardShutdownIface = std::make_unique<Threshold<HardShutdownObject>>(
+            bus, objPath.c_str(), units);
+
+        hardShutdownIface->hardShutdownHigh(threshold.value(
+            "HardShutdownHigh", std::numeric_limits<double>::quiet_NaN()));
+        hardShutdownIface->hardShutdownLow(threshold.value(
+            "HardShutdownLow", std::numeric_limits<double>::quiet_NaN()));
+        hardShutdownIface->setHighHysteresis(
+            threshold.value("HardShutdownHighHysteresis", defaultHysteresis));
+        hardShutdownIface->setLowHysteresis(
+            threshold.value("HardShutdownLowHysteresis", defaultHysteresis));
+    }
+
+    if (threshold.contains("SoftShutdownHigh") ||
+        threshold.contains("SoftShutdownLow"))
+    {
+        softShutdownIface = std::make_unique<Threshold<SoftShutdownObject>>(
+            bus, objPath.c_str(), units);
+
+        softShutdownIface->softShutdownHigh(threshold.value(
+            "SoftShutdownHigh", std::numeric_limits<double>::quiet_NaN()));
+        softShutdownIface->softShutdownLow(threshold.value(
+            "SoftShutdownLow", std::numeric_limits<double>::quiet_NaN()));
+        softShutdownIface->setHighHysteresis(
+            threshold.value("SoftShutdownHighHysteresis", defaultHysteresis));
+        softShutdownIface->setLowHysteresis(
+            threshold.value("SoftShutdownLowHysteresis", defaultHysteresis));
+    }
+
+    if (threshold.contains("PerformanceLossHigh") ||
+        threshold.contains("PerformanceLossLow"))
+    {
+        perfLossIface = std::make_unique<Threshold<PerformanceLossObject>>(
+            bus, objPath.c_str(), units);
+
+        perfLossIface->performanceLossHigh(threshold.value(
+            "PerformanceLossHigh", std::numeric_limits<double>::quiet_NaN()));
+        perfLossIface->performanceLossLow(threshold.value(
+            "PerformanceLossLow", std::numeric_limits<double>::quiet_NaN()));
+        perfLossIface->setHighHysteresis(threshold.value(
+            "PerformanceLossHighHysteresis", defaultHysteresis));
+        perfLossIface->setLowHysteresis(
+            threshold.value("PerformanceLossLowHysteresis", defaultHysteresis));
+    }
+}
+
+ManagedObjectType VirtualSensors::getObjectsFromDBus()
+{
+    ManagedObjectType objects;
+
+    try
+    {
+        auto method = bus.new_method_call(
+            "xyz.openbmc_project.EntityManager",
+            "/xyz/openbmc_project/inventory",
+            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+        auto reply = bus.call(method);
+        reply.read(objects);
+    }
+    catch (const sdbusplus::exception_t& ex)
+    {
+        // If entity manager isn't running yet, keep going.
+        if (std::string("org.freedesktop.DBus.Error.ServiceUnknown") !=
+            ex.name())
+        {
+            error("Could not reach entity-manager: {ERROR}", "ERROR", ex);
+            throw;
+        }
+    }
+
+    return objects;
+}
+
+void VirtualSensors::propertiesChanged(sdbusplus::message_t& msg)
+{
+    std::string interface;
+    PropertyMap properties;
+
+    msg.read(interface, properties);
+
+    /* We get multiple callbacks for one sensor. 'Type' is a required field and
+     * is a unique label so use to to only proceed once per sensor */
+    if (properties.contains("Type"))
+    {
+        if (calculationIfaces.contains(interface))
+        {
+            createVirtualSensorsFromDBus(interface);
+        }
+    }
+}
+
+/** @brief Parsing Virtual Sensor config JSON file  */
+Json VirtualSensors::parseConfigFile()
+{
+    using path = std::filesystem::path;
+    auto configFile = []() -> path {
+        static constexpr auto name = "virtual_sensor_config.json";
+
+        for (auto pathSeg : {std::filesystem::current_path(),
+                             path{"/var/lib/phosphor-virtual-sensor"},
+                             path{"/usr/share/phosphor-virtual-sensor"}})
+        {
+            auto file = pathSeg / name;
+            if (std::filesystem::exists(file))
+            {
+                return file;
+            }
+        }
+        return name;
+    }();
+
+    std::ifstream jsonFile(configFile);
+    if (!jsonFile.is_open())
+    {
+        error("config JSON file {FILENAME} not found", "FILENAME", configFile);
+        return {};
+    }
+
+    auto data = Json::parse(jsonFile, nullptr, false);
+    if (data.is_discarded())
+    {
+        error("config readings JSON parser failure with {FILENAME}", "FILENAME",
+              configFile);
+        throw std::exception{};
+    }
+
+    return data;
+}
+
+const std::string getSensorTypeFromUnit(const std::string& unit)
+{
+    std::string unitPrefix = "xyz.openbmc_project.Sensor.Value.Unit.";
+    for (auto [type, unitObj] : unitMap)
+    {
+        auto unitPath = ValueIface::convertUnitToString(unitObj);
+        if (unitPath == (unitPrefix + unit))
+        {
+            return type;
+        }
+    }
+    return "";
+}
+
+void VirtualSensors::setupMatches()
+{
+    /* Already setup */
+    if (!this->matches.empty())
+    {
+        return;
+    }
+
+    /* Setup matches */
+    auto eventHandler = [this](sdbusplus::message_t& message) {
+        if (message.is_method_error())
+        {
+            error("Callback method error");
+            return;
+        }
+        this->propertiesChanged(message);
+    };
+
+    for (const auto& [iface, _] : calculationIfaces)
+    {
+        auto match = std::make_unique<sdbusplus::bus::match_t>(
+            bus,
+            sdbusplus::bus::match::rules::propertiesChangedNamespace(
+                "/xyz/openbmc_project/inventory", iface),
+            eventHandler);
+        this->matches.emplace_back(std::move(match));
+    }
+}
+
+void VirtualSensors::createVirtualSensorsFromDBus(
+    const std::string& calculationIface)
+{
+    if (calculationIface.empty())
+    {
+        error("No calculation type supplied");
+        return;
+    }
+    auto objects = getObjectsFromDBus();
+
+    /* Get virtual sensors config data */
+    for (const auto& [path, interfaceMap] : objects)
+    {
+        /* Find Virtual Sensor interfaces */
+        auto intfIter = interfaceMap.find(calculationIface);
+        if (intfIter == interfaceMap.end())
+        {
+            continue;
+        }
+
+        std::string name = path.filename();
+        if (name.empty())
+        {
+            error("Virtual Sensor name not found in entity manager config");
+            continue;
+        }
+        if (virtualSensorsMap.contains(name))
+        {
+            error("A virtual sensor named {NAME} already exists", "NAME", name);
+            continue;
+        }
+
+        /* Extract the virtual sensor type as we need this to initialize the
+         * sensor */
+        std::string sensorType, sensorUnit;
+        auto propertyMap = intfIter->second;
+        auto proIter = propertyMap.find("Units");
+        if (proIter != propertyMap.end())
+        {
+            sensorUnit = std::get<std::string>(proIter->second);
+        }
+        sensorType = getSensorTypeFromUnit(sensorUnit);
+        if (sensorType.empty())
+        {
+            error("Sensor unit type {TYPE} is not supported", "TYPE",
+                  sensorUnit);
+            continue;
+        }
+
+        try
+        {
+            auto objpath = static_cast<std::string>(path);
+            auto virtObjPath = sensorDbusPath + sensorType + "/" + name;
+
+            auto virtualSensorPtr = std::make_unique<VirtualSensor>(
+                bus, virtObjPath.c_str(), interfaceMap, name, sensorType,
+                calculationIface, objpath);
+            info("Added a new virtual sensor: {NAME} {TYPE}", "NAME", name,
+                 "TYPE", sensorType);
+            virtualSensorPtr->updateVirtualSensor();
+
+            /* Initialize unit value for virtual sensor */
+            virtualSensorPtr->ValueIface::unit(unitMap[sensorType]);
+            virtualSensorPtr->emit_object_added();
+
+            virtualSensorsMap.emplace(name, std::move(virtualSensorPtr));
+
+            /* Setup match for interfaces removed */
+            auto intfRemoved = [this, objpath,
+                                name](sdbusplus::message_t& message) {
+                if (!virtualSensorsMap.contains(name))
+                {
+                    return;
+                }
+                sdbusplus::message::object_path path;
+                message.read(path);
+                if (static_cast<const std::string&>(path) == objpath)
+                {
+                    info("Removed a virtual sensor: {NAME}", "NAME", name);
+                    virtualSensorsMap.erase(name);
+                }
+            };
+            auto matchOnRemove = std::make_unique<sdbusplus::bus::match_t>(
+                bus,
+                sdbusplus::bus::match::rules::interfacesRemoved() +
+                    sdbusplus::bus::match::rules::argNpath(0, objpath),
+                intfRemoved);
+            /* TODO: slight race condition here. Check that the config still
+             * exists */
+            this->matches.emplace_back(std::move(matchOnRemove));
+        }
+        catch (const std::invalid_argument& ia)
+        {
+            error("Failed to set up virtual sensor: {ERROR}", "ERROR", ia);
+        }
+    }
+}
+
+void VirtualSensors::createVirtualSensors()
+{
+    static const Json empty{};
+
+    auto data = parseConfigFile();
+
+    // print values
+    debug("JSON: {JSON}", "JSON", data.dump());
+
+    /* Get virtual sensors  config data */
+    for (const auto& j : data)
+    {
+        auto desc = j.value("Desc", empty);
+        if (!desc.empty())
+        {
+            if (desc.value("Config", "") == "D-Bus")
+            {
+                /* Look on D-Bus for a virtual sensor config. Set up matches
+                 * first because the configs may not be on D-Bus yet and we
+                 * don't want to miss them */
+                setupMatches();
+
+                for (const auto& intf : std::views::keys(calculationIfaces))
+                {
+                    createVirtualSensorsFromDBus(intf);
+                }
+                continue;
+            }
+
+            std::string sensorType = desc.value("SensorType", "");
+            std::string name = desc.value("Name", "");
+            std::replace(name.begin(), name.end(), ' ', '_');
+
+            if (!name.empty() && !sensorType.empty())
+            {
+                if (unitMap.find(sensorType) == unitMap.end())
+                {
+                    error("Sensor type {TYPE} is not supported", "TYPE",
+                          sensorType);
+                }
+                else
+                {
+                    if (virtualSensorsMap.find(name) != virtualSensorsMap.end())
+                    {
+                        error("A virtual sensor named {NAME} already exists",
+                              "NAME", name);
+                        continue;
+                    }
+                    auto objPath = sensorDbusPath + sensorType + "/" + name;
+
+                    auto virtualSensorPtr = std::make_unique<VirtualSensor>(
+                        bus, objPath.c_str(), j, name, sensorType);
+
+                    info("Added a new virtual sensor: {NAME}", "NAME", name);
+                    virtualSensorPtr->updateVirtualSensor();
+
+                    /* Initialize unit value for virtual sensor */
+                    virtualSensorPtr->ValueIface::unit(unitMap[sensorType]);
+                    virtualSensorPtr->emit_object_added();
+
+                    virtualSensorsMap.emplace(std::move(name),
+                                              std::move(virtualSensorPtr));
+                }
+            }
+            else
+            {
+                error(
+                    "Sensor type ({TYPE}) or name ({NAME}) not found in config file",
+                    "NAME", name, "TYPE", sensorType);
+            }
+        }
+        else
+        {
+            error("Descriptor for new virtual sensor not found in config file");
+        }
+    }
+}
+
+} // namespace phosphor::virtual_sensor
diff --git a/src/virtualSensor.hpp b/src/virtualSensor.hpp
new file mode 100644
index 0000000..1b3683f
--- /dev/null
+++ b/src/virtualSensor.hpp
@@ -0,0 +1,319 @@
+#pragma once
+
+#include "dbusSensor.hpp"
+#include "exprtkTools.hpp"
+#include "thresholds.hpp"
+
+#include <nlohmann/json.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/bus.hpp>
+#include <xyz/openbmc_project/Association/Definitions/server.hpp>
+#include <xyz/openbmc_project/Sensor/Value/server.hpp>
+
+#include <map>
+#include <string>
+
+namespace phosphor::virtual_sensor
+{
+
+PHOSPHOR_LOG2_USING_WITH_FLAGS;
+
+using BasicVariantType =
+    std::variant<std::string, int64_t, uint64_t, double, int32_t, uint32_t,
+                 int16_t, uint16_t, uint8_t, bool, std::vector<std::string>>;
+
+using PropertyMap = std::map<std::string, BasicVariantType>;
+
+using InterfaceMap = std::map<std::string, PropertyMap>;
+
+using ManagedObjectType =
+    std::map<sdbusplus::message::object_path, InterfaceMap>;
+
+using Json = nlohmann::json;
+
+template <typename... T>
+using ServerObject = typename sdbusplus::server::object_t<T...>;
+
+using ValueIface = sdbusplus::xyz::openbmc_project::Sensor::server::Value;
+using ValueObject = ServerObject<ValueIface>;
+
+using AssociationIface =
+    sdbusplus::xyz::openbmc_project::Association::server::Definitions;
+using AssociationObject = ServerObject<AssociationIface>;
+
+class SensorParam
+{
+  public:
+    SensorParam() = delete;
+    virtual ~SensorParam() = default;
+
+    enum ParamType
+    {
+        constParam,
+        dbusParam
+    };
+
+    /** @brief Constructs SensorParam (type = constParam)
+     *
+     * @param[in] value - Value of constant parameter
+     */
+    explicit SensorParam(double value) : value(value), paramType(constParam) {}
+
+    /** @brief Constructs SensorParam (type = dbusParam)
+     *
+     * @param[in] bus     - Handle to system dbus
+     * @param[in] path    - The Dbus path of sensor
+     * @param[in] ctx     - sensor context for update
+     */
+    SensorParam(sdbusplus::bus_t& bus, const std::string& path,
+                VirtualSensor& ctx) :
+        dbusSensor(std::make_unique<DbusSensor>(bus, path, ctx)),
+        paramType(dbusParam)
+    {}
+
+    /** @brief Get sensor value property from D-bus interface */
+    double getParamValue();
+
+  private:
+    std::unique_ptr<DbusSensor> dbusSensor = nullptr;
+
+    /** @brief virtual sensor value */
+    double value = std::numeric_limits<double>::quiet_NaN();
+    ParamType paramType;
+};
+
+class VirtualSensor : public ValueObject
+{
+  public:
+    VirtualSensor() = delete;
+    virtual ~VirtualSensor() = default;
+
+    /** @brief Constructs VirtualSensor
+     *
+     * @param[in] bus          - Handle to system dbus
+     * @param[in] objPath      - The Dbus path of sensor
+     * @param[in] sensorConfig - Json object for sensor config
+     * @param[in] name         - Sensor name
+     * @param[in] type         - sensor type/unit
+     */
+    VirtualSensor(sdbusplus::bus_t& bus, const char* objPath,
+                  const Json& sensorConfig, const std::string& name,
+                  const std::string& type) :
+        ValueObject(bus, objPath, action::defer_emit), bus(bus), name(name),
+        objPath(objPath)
+    {
+        initVirtualSensor(sensorConfig, objPath, type);
+    }
+
+    /** @brief Constructs VirtualSensor
+     *
+     * @param[in] bus          - Handle to system dbus
+     * @param[in] objPath      - The Dbus path of sensor
+     * @param[in] ifacemap     - All the sensor information
+     * @param[in] name         - Virtual sensor name
+     * @param[in] type         - Virtual sensor type/unit
+     * @param[in] calcType     - Calculation used to calculate sensor value
+     * @param[in] entityPath   - Virtual sensor path in entityManager Dbus
+     *
+     */
+    VirtualSensor(sdbusplus::bus_t& bus, const char* objPath,
+                  const InterfaceMap& ifacemap, const std::string& name,
+                  const std::string& type, const std::string& calculationType,
+                  const std::string& entityPath) :
+        ValueObject(bus, objPath, action::defer_emit), bus(bus), name(name),
+        objPath(objPath), entityPath(entityPath)
+    {
+        initVirtualSensor(ifacemap, objPath, type, calculationType);
+    }
+
+    /** @brief Set sensor value */
+    void setSensorValue(double value);
+
+    /** @brief Update sensor at regular intrval */
+    void updateVirtualSensor();
+
+    /** @brief Check if sensor value is in valid range */
+    bool sensorInRange(double value);
+
+    /** @brief Map of list of parameters */
+    using ParamMap =
+        std::unordered_map<std::string, std::unique_ptr<SensorParam>>;
+    ParamMap paramMap;
+
+  private:
+    /** @brief sdbusplus bus client connection. */
+    sdbusplus::bus_t& bus;
+    /** @brief name of sensor */
+    std::string name;
+    /** @brief unit of sensor */
+    ValueIface::Unit units;
+    /** @brief object path of this sensor */
+    std::string objPath;
+
+    /** @brief Virtual sensor path in entityManager Dbus.
+     * This value is used to set thresholds/create association
+     */
+    std::string entityPath;
+    /** @brief Expression string for virtual sensor value calculations */
+    std::string exprStr;
+    /** @brief symbol table from exprtk */
+    exprtk::symbol_table<double> symbols{};
+    /** @brief expression from exprtk to calculate sensor value */
+    exprtk::expression<double> expression{};
+    /** @brief The vecops package so the expression can use vectors */
+    exprtk::rtl::vecops::package<double> vecopsPackage;
+    /** @brief The maximum valid value for an input sensor **/
+    double maxValidInput = std::numeric_limits<double>::infinity();
+    /** @brief The minimum valid value for an input sensor **/
+    double minValidInput = -std::numeric_limits<double>::infinity();
+
+    /** @brief The critical threshold interface object */
+    std::unique_ptr<Threshold<CriticalObject>> criticalIface;
+    /** @brief The warning threshold interface object */
+    std::unique_ptr<Threshold<WarningObject>> warningIface;
+    /** @brief The soft shutdown threshold interface object */
+    std::unique_ptr<Threshold<SoftShutdownObject>> softShutdownIface;
+    /** @brief The hard shutdown threshold interface object */
+    std::unique_ptr<Threshold<HardShutdownObject>> hardShutdownIface;
+    /** @brief The performance loss threshold interface object */
+    std::unique_ptr<Threshold<PerformanceLossObject>> perfLossIface;
+
+    /** @brief The association interface object */
+    std::unique_ptr<AssociationObject> associationIface;
+
+    static FuncMaxIgnoreNaN<double> funcMaxIgnoreNaN;
+    static FuncSumIgnoreNaN<double> funcSumIgnoreNaN;
+    static FuncIfNan<double> funcIfNan;
+
+    /** @brief Read config from json object and initialize sensor data
+     * for each virtual sensor
+     */
+    void initVirtualSensor(const Json& sensorConfig, const std::string& objPath,
+                           const std::string& type);
+
+    /** @brief Read config from interface map and initialize sensor data
+     * for each virtual sensor
+     */
+    void initVirtualSensor(const InterfaceMap& interfaceMap,
+                           const std::string& objPath,
+                           const std::string& sensorType,
+                           const std::string& calculationType);
+
+    /** @brief Returns which calculation function or expression to use */
+    double calculateValue(const std::string& sensortype,
+                          const VirtualSensor::ParamMap& paramMap);
+    /** @brief create threshold objects from json config */
+    void createThresholds(const Json& threshold, const std::string& objPath,
+                          ValueIface::Unit units);
+    /** @brief parse config from entity manager **/
+    void parseConfigInterface(const PropertyMap& propertyMap,
+                              const std::string& sensorType,
+                              const std::string& interface);
+
+    /** @brief Check Sensor threshold and update alarm and log. Returns
+     * true if the threshold range has no alarms set. change will be
+     * set if a change to the alarms were detected, else will be left
+     * unchanged */
+    template <typename V, typename T>
+    bool checkThresholds(V value, T& threshold, bool& change)
+    {
+        if (!threshold)
+            return true;
+
+        static constexpr auto tname = T::element_type::name;
+
+        auto alarmHigh = threshold->alarmHigh();
+        auto highHysteresis = threshold->getHighHysteresis();
+        if ((!alarmHigh && value >= threshold->high()) ||
+            (alarmHigh && value < (threshold->high() - highHysteresis)))
+        {
+            change = true;
+            if (!alarmHigh)
+            {
+                error("ASSERT: sensor {SENSOR} is above the upper threshold "
+                      "{THRESHOLD}.",
+                      "SENSOR", name, "THRESHOLD", tname);
+                threshold->alarmHighSignalAsserted(value);
+            }
+            else
+            {
+                info("DEASSERT: sensor {SENSOR} is under the upper threshold "
+                     "{THRESHOLD}.",
+                     "SENSOR", name, "THRESHOLD", tname);
+                threshold->alarmHighSignalDeasserted(value);
+            }
+            alarmHigh = !alarmHigh;
+            threshold->alarmHigh(alarmHigh);
+        }
+
+        auto alarmLow = threshold->alarmLow();
+        auto lowHysteresis = threshold->getLowHysteresis();
+        if ((!alarmLow && value <= threshold->low()) ||
+            (alarmLow && value > (threshold->low() + lowHysteresis)))
+        {
+            change = true;
+            if (!alarmLow)
+            {
+                error("ASSERT: sensor {SENSOR} is below the lower threshold "
+                      "{THRESHOLD}.",
+                      "SENSOR", name, "THRESHOLD", tname);
+                threshold->alarmLowSignalAsserted(value);
+            }
+            else
+            {
+                info("DEASSERT: sensor {SENSOR} is above the lower threshold "
+                     "{THRESHOLD}.",
+                     "SENSOR", name, "THRESHOLD", tname);
+                threshold->alarmLowSignalDeasserted(value);
+            }
+            alarmLow = !alarmLow;
+            threshold->alarmLow(alarmLow);
+        }
+        return !alarmHigh && !alarmLow;
+    }
+
+    /** @brief Create Association from entityPath*/
+    void createAssociation(const std::string& objPath,
+                           const std::string& entityPath);
+};
+
+class VirtualSensors
+{
+  public:
+    VirtualSensors() = delete;
+    virtual ~VirtualSensors() = default;
+
+    /** @brief Constructs VirtualSensors
+     *
+     * @param[in] bus     - Handle to system dbus
+     */
+    explicit VirtualSensors(sdbusplus::bus_t& bus) : bus(bus)
+    {
+        createVirtualSensors();
+    }
+    /** @brief Calls createVirtualSensor when interface added */
+    void propertiesChanged(sdbusplus::message_t& msg);
+
+  private:
+    /** @brief sdbusplus bus client connection. */
+    sdbusplus::bus_t& bus;
+    /** @brief Get virtual sensor config from DBus**/
+    ManagedObjectType getObjectsFromDBus();
+    /** @brief Parsing virtual sensor config JSON file  */
+    Json parseConfigFile();
+
+    /** @brief Matches for virtual sensors */
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches;
+    /** @brief Map of the object VirtualSensor */
+    std::unordered_map<std::string, std::unique_ptr<VirtualSensor>>
+        virtualSensorsMap;
+
+    /** @brief Create list of virtual sensors from JSON config*/
+    void createVirtualSensors();
+    /** @brief Create list of virtual sensors from DBus config */
+    void createVirtualSensorsFromDBus(const std::string& calculationType);
+    /** @brief Setup matches for virtual sensors */
+    void setupMatches();
+};
+
+} // namespace phosphor::virtual_sensor
