diff --git a/src/Utils.hpp b/src/Utils.hpp
new file mode 100644
index 0000000..444030c
--- /dev/null
+++ b/src/Utils.hpp
@@ -0,0 +1,390 @@
+#pragma once
+
+#include "VariantVisitors.hpp"
+
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <boost/container/flat_map.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/message/types.hpp>
+
+#include <filesystem>
+#include <functional>
+#include <iostream>
+#include <memory>
+#include <optional>
+#include <regex>
+#include <span>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <variant>
+#include <vector>
+
+const constexpr char* jsonStore = "/var/configuration/flattened.json";
+const constexpr char* inventoryPath = "/xyz/openbmc_project/inventory";
+const constexpr char* entityManagerName = "xyz.openbmc_project.EntityManager";
+
+constexpr const char* cpuInventoryPath =
+    "/xyz/openbmc_project/inventory/system/chassis/motherboard";
+const std::regex illegalDbusRegex("[^A-Za-z0-9_]");
+
+using BasicVariantType =
+    std::variant<std::vector<std::string>, std::string, int64_t, uint64_t,
+                 double, int32_t, uint32_t, int16_t, uint16_t, uint8_t, bool>;
+using SensorBaseConfigMap =
+    boost::container::flat_map<std::string, BasicVariantType>;
+using SensorBaseConfiguration = std::pair<std::string, SensorBaseConfigMap>;
+using SensorData = boost::container::flat_map<std::string, SensorBaseConfigMap>;
+using ManagedObjectType =
+    boost::container::flat_map<sdbusplus::message::object_path, SensorData>;
+
+using GetSubTreeType = std::vector<
+    std::pair<std::string,
+              std::vector<std::pair<std::string, std::vector<std::string>>>>>;
+using Association = std::tuple<std::string, std::string, std::string>;
+
+inline std::string escapeName(const std::string& sensorName)
+{
+    return boost::replace_all_copy(sensorName, " ", "_");
+}
+
+enum class PowerState
+{
+    on,
+    biosPost,
+    always,
+    chassisOn
+};
+
+std::optional<std::string> openAndRead(const std::string& hwmonFile);
+std::optional<std::string>
+    getFullHwmonFilePath(const std::string& directory,
+                         const std::string& hwmonBaseName,
+                         const std::set<std::string>& permitSet);
+std::set<std::string> getPermitSet(const SensorBaseConfigMap& config);
+bool findFiles(const std::filesystem::path& dirPath,
+               std::string_view matchString,
+               std::vector<std::filesystem::path>& foundPaths,
+               int symlinkDepth = 1);
+bool isPowerOn(void);
+bool hasBiosPost(void);
+bool isChassisOn(void);
+void setupPowerMatchCallback(
+    const std::shared_ptr<sdbusplus::asio::connection>& conn,
+    std::function<void(PowerState type, bool state)>&& callback);
+void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn);
+bool getSensorConfiguration(
+    const std::string& type,
+    const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
+    ManagedObjectType& resp, bool useCache);
+
+bool getSensorConfiguration(
+    const std::string& type,
+    const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
+    ManagedObjectType& resp);
+
+void createAssociation(
+    std::shared_ptr<sdbusplus::asio::dbus_interface>& association,
+    const std::string& path);
+
+// replaces limits if MinReading and MaxReading are found.
+void findLimits(std::pair<double, double>& limits,
+                const SensorBaseConfiguration* data);
+
+bool readingStateGood(const PowerState& powerState);
+
+constexpr const char* configInterfacePrefix =
+    "xyz.openbmc_project.Configuration.";
+
+inline std::string configInterfaceName(const std::string& type)
+{
+    return std::string(configInterfacePrefix) + type;
+}
+
+namespace mapper
+{
+constexpr const char* busName = "xyz.openbmc_project.ObjectMapper";
+constexpr const char* path = "/xyz/openbmc_project/object_mapper";
+constexpr const char* interface = "xyz.openbmc_project.ObjectMapper";
+constexpr const char* subtree = "GetSubTree";
+} // namespace mapper
+
+namespace properties
+{
+constexpr const char* interface = "org.freedesktop.DBus.Properties";
+constexpr const char* get = "Get";
+constexpr const char* set = "Set";
+} // namespace properties
+
+namespace power
+{
+const static constexpr char* busname = "xyz.openbmc_project.State.Host";
+const static constexpr char* interface = "xyz.openbmc_project.State.Host";
+const static constexpr char* path = "/xyz/openbmc_project/state/host0";
+const static constexpr char* property = "CurrentHostState";
+} // namespace power
+
+namespace chassis
+{
+const static constexpr char* busname = "xyz.openbmc_project.State.Chassis";
+const static constexpr char* interface = "xyz.openbmc_project.State.Chassis";
+const static constexpr char* path = "/xyz/openbmc_project/state/chassis0";
+const static constexpr char* property = "CurrentPowerState";
+const static constexpr char* sOn = "On";
+} // namespace chassis
+
+namespace post
+{
+const static constexpr char* busname =
+    "xyz.openbmc_project.State.OperatingSystem";
+const static constexpr char* interface =
+    "xyz.openbmc_project.State.OperatingSystem.Status";
+const static constexpr char* path = "/xyz/openbmc_project/state/os";
+const static constexpr char* property = "OperatingSystemState";
+} // namespace post
+
+namespace association
+{
+const static constexpr char* interface =
+    "xyz.openbmc_project.Association.Definitions";
+} // namespace association
+
+template <typename T>
+inline T loadVariant(const SensorBaseConfigMap& data, const std::string& key)
+{
+    auto it = data.find(key);
+    if (it == data.end())
+    {
+        std::cerr << "Configuration missing " << key << "\n";
+        throw std::invalid_argument("Key Missing");
+    }
+    if constexpr (std::is_same_v<T, double>)
+    {
+        return std::visit(VariantToDoubleVisitor(), it->second);
+    }
+    else if constexpr (std::is_unsigned_v<T>)
+    {
+        return std::visit(VariantToUnsignedIntVisitor(), it->second);
+    }
+    else if constexpr (std::is_same_v<T, std::string>)
+    {
+        return std::visit(VariantToStringVisitor(), it->second);
+    }
+    else
+    {
+        static_assert(!std::is_same_v<T, T>, "Type Not Implemented");
+    }
+}
+
+inline void setReadState(const std::string& str, PowerState& val)
+{
+
+    if (str == "On")
+    {
+        val = PowerState::on;
+    }
+    else if (str == "BiosPost")
+    {
+        val = PowerState::biosPost;
+    }
+    else if (str == "Always")
+    {
+        val = PowerState::always;
+    }
+    else if (str == "ChassisOn")
+    {
+        val = PowerState::chassisOn;
+    }
+}
+
+inline PowerState getPowerState(const SensorBaseConfigMap& cfg)
+{
+    PowerState state = PowerState::always;
+    auto findPowerState = cfg.find("PowerState");
+    if (findPowerState != cfg.end())
+    {
+        std::string powerState =
+            std::visit(VariantToStringVisitor(), findPowerState->second);
+        setReadState(powerState, state);
+    }
+    return state;
+}
+
+inline float getPollRate(const SensorBaseConfigMap& cfg, float dflt)
+{
+    float pollRate = dflt;
+    auto findPollRate = cfg.find("PollRate");
+    if (findPollRate != cfg.end())
+    {
+        pollRate = std::visit(VariantToFloatVisitor(), findPollRate->second);
+        if (!std::isfinite(pollRate) || pollRate <= 0.0F)
+        {
+            pollRate = dflt; // poll time invalid, fall back to default
+        }
+    }
+    return pollRate;
+}
+
+inline void setLed(const std::shared_ptr<sdbusplus::asio::connection>& conn,
+                   const std::string& name, bool on)
+{
+    conn->async_method_call(
+        [name](const boost::system::error_code ec) {
+        if (ec)
+        {
+            std::cerr << "Failed to set LED " << name << "\n";
+        }
+        },
+        "xyz.openbmc_project.LED.GroupManager",
+        "/xyz/openbmc_project/led/groups/" + name, properties::interface,
+        properties::set, "xyz.openbmc_project.Led.Group", "Asserted",
+        std::variant<bool>(on));
+}
+
+void createInventoryAssoc(
+    const std::shared_ptr<sdbusplus::asio::connection>& conn,
+    const std::shared_ptr<sdbusplus::asio::dbus_interface>& association,
+    const std::string& path);
+
+struct GetSensorConfiguration :
+    std::enable_shared_from_this<GetSensorConfiguration>
+{
+    GetSensorConfiguration(
+        std::shared_ptr<sdbusplus::asio::connection> connection,
+        std::function<void(ManagedObjectType& resp)>&& callbackFunc) :
+        dbusConnection(std::move(connection)),
+        callback(std::move(callbackFunc))
+    {}
+
+    void getPath(const std::string& path, const std::string& interface,
+                 const std::string& owner, size_t retries = 5)
+    {
+        if (retries > 5)
+        {
+            retries = 5;
+        }
+        std::shared_ptr<GetSensorConfiguration> self = shared_from_this();
+
+        self->dbusConnection->async_method_call(
+            [self, path, interface, owner, retries](
+                const boost::system::error_code ec, SensorBaseConfigMap& data) {
+            if (ec)
+            {
+                std::cerr << "Error getting " << path << ": retries left"
+                          << retries - 1 << "\n";
+                if (retries == 0U)
+                {
+                    return;
+                }
+                auto timer = std::make_shared<boost::asio::steady_timer>(
+                    self->dbusConnection->get_io_context());
+                timer->expires_after(std::chrono::seconds(10));
+                timer->async_wait([self, timer, path, interface, owner,
+                                   retries](boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        std::cerr << "Timer error!\n";
+                        return;
+                    }
+                    self->getPath(path, interface, owner, retries - 1);
+                });
+                return;
+            }
+
+            self->respData[path][interface] = std::move(data);
+            },
+            owner, path, "org.freedesktop.DBus.Properties", "GetAll",
+            interface);
+    }
+
+    void getConfiguration(const std::vector<std::string>& types,
+                          size_t retries = 0)
+    {
+        if (retries > 5)
+        {
+            retries = 5;
+        }
+
+        std::vector<std::string> interfaces(types.size());
+        for (const auto& type : types)
+        {
+            interfaces.push_back(configInterfaceName(type));
+        }
+
+        std::shared_ptr<GetSensorConfiguration> self = shared_from_this();
+        dbusConnection->async_method_call(
+            [self, interfaces, retries](const boost::system::error_code ec,
+                                        const GetSubTreeType& ret) {
+            if (ec)
+            {
+                std::cerr << "Error calling mapper\n";
+                if (retries == 0U)
+                {
+                    return;
+                }
+                auto timer = std::make_shared<boost::asio::steady_timer>(
+                    self->dbusConnection->get_io_context());
+                timer->expires_after(std::chrono::seconds(10));
+                timer->async_wait([self, timer, interfaces,
+                                   retries](boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        std::cerr << "Timer error!\n";
+                        return;
+                    }
+                    self->getConfiguration(interfaces, retries - 1);
+                });
+
+                return;
+            }
+            for (const auto& [path, objDict] : ret)
+            {
+                if (objDict.empty())
+                {
+                    return;
+                }
+                const std::string& owner = objDict.begin()->first;
+
+                for (const std::string& interface : objDict.begin()->second)
+                {
+                    // anything that starts with a requested configuration
+                    // is good
+                    if (std::find_if(interfaces.begin(), interfaces.end(),
+                                     [interface](const std::string& possible) {
+                        return interface.starts_with(possible);
+                        }) == interfaces.end())
+                    {
+                        continue;
+                    }
+                    self->getPath(path, interface, owner);
+                }
+            }
+            },
+            mapper::busName, mapper::path, mapper::interface, mapper::subtree,
+            "/", 0, interfaces);
+    }
+
+    ~GetSensorConfiguration()
+    {
+        callback(respData);
+    }
+
+    std::shared_ptr<sdbusplus::asio::connection> dbusConnection;
+    std::function<void(ManagedObjectType& resp)> callback;
+    ManagedObjectType respData;
+};
+
+// The common scheme for sysfs files naming is: <type><number>_<item>.
+// This function returns optionally these 3 elements as a tuple.
+std::optional<std::tuple<std::string, std::string, std::string>>
+    splitFileName(const std::filesystem::path& filePath);
+std::optional<double> readFile(const std::string& thresholdFile,
+                               const double& scaleFactor);
+void setupManufacturingModeMatch(sdbusplus::asio::connection& conn);
+bool getManufacturingMode();
+std::vector<std::unique_ptr<sdbusplus::bus::match_t>>
+    setupPropertiesChangedMatches(
+        sdbusplus::asio::connection& bus, std::span<const char* const> types,
+        const std::function<void(sdbusplus::message_t&)>& handler);
