diff --git a/argument.hpp b/argument.hpp
index 9d0ab06..41113ec 100644
--- a/argument.hpp
+++ b/argument.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <getopt.h>
+
 #include <map>
 #include <string>
 
@@ -18,28 +19,28 @@
  */
 class ArgumentParser
 {
-    public:
-        ArgumentParser(int argc, char** argv);
-        ArgumentParser() = delete;
-        ArgumentParser(const ArgumentParser&) = delete;
-        ArgumentParser(ArgumentParser&&) = default;
-        ArgumentParser& operator=(const ArgumentParser&) = delete;
-        ArgumentParser& operator=(ArgumentParser&&) = default;
-        ~ArgumentParser() = default;
-        const std::string& operator[](const std::string& opt);
+  public:
+    ArgumentParser(int argc, char** argv);
+    ArgumentParser() = delete;
+    ArgumentParser(const ArgumentParser&) = delete;
+    ArgumentParser(ArgumentParser&&) = default;
+    ArgumentParser& operator=(const ArgumentParser&) = delete;
+    ArgumentParser& operator=(ArgumentParser&&) = default;
+    ~ArgumentParser() = default;
+    const std::string& operator[](const std::string& opt);
 
-        static void usage(char** argv);
+    static void usage(char** argv);
 
-        static const std::string true_string;
-        static const std::string empty_string;
+    static const std::string true_string;
+    static const std::string empty_string;
 
-    private:
-        std::map<const std::string, std::string> arguments;
+  private:
+    std::map<const std::string, std::string> arguments;
 
-        static const option options[];
-        static const char* optionstr;
+    static const option options[];
+    static const char* optionstr;
 };
 
-}
-}
-}
+} // namespace util
+} // namespace fan
+} // namespace phosphor
diff --git a/sdbusplus.hpp b/sdbusplus.hpp
index 3286fbd..9c3d08d 100644
--- a/sdbusplus.hpp
+++ b/sdbusplus.hpp
@@ -1,11 +1,11 @@
 #pragma once
 
-#include <sdbusplus/bus.hpp>
-#include <sdbusplus/message.hpp>
-#include <sdbusplus/bus/match.hpp>
-#include <phosphor-logging/log.hpp>
-#include <phosphor-logging/elog.hpp>
 #include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/message.hpp>
 #include <xyz/openbmc_project/Common/error.hpp>
 
 namespace phosphor
@@ -31,11 +31,9 @@
  */
 class DBusError : public std::runtime_error
 {
-    public:
-        DBusError(const char* msg) :
-            std::runtime_error(msg)
-        {
-        }
+  public:
+    DBusError(const char* msg) : std::runtime_error(msg)
+    {}
 };
 
 /**
@@ -45,24 +43,17 @@
  */
 class DBusMethodError : public DBusError
 {
-    public:
-        DBusMethodError(
-                const std::string& busName,
-                const std::string& path,
-                const std::string& interface,
-                const std::string& method) :
-            DBusError("DBus method call failed"),
-            busName(busName),
-            path(path),
-            interface(interface),
-            method(method)
-            {
-            }
+  public:
+    DBusMethodError(const std::string& busName, const std::string& path,
+                    const std::string& interface, const std::string& method) :
+        DBusError("DBus method call failed"),
+        busName(busName), path(path), interface(interface), method(method)
+    {}
 
-        const std::string busName;
-        const std::string path;
-        const std::string interface;
-        const std::string method;
+    const std::string busName;
+    const std::string path;
+    const std::string interface;
+    const std::string method;
 };
 
 /**
@@ -73,18 +64,14 @@
  */
 class DBusServiceError : public DBusError
 {
-    public:
-        DBusServiceError(
-                const std::string& path,
-                const std::string& interface) :
-            DBusError("DBus service lookup failed"),
-            path(path),
-            interface(interface)
-            {
-            }
+  public:
+    DBusServiceError(const std::string& path, const std::string& interface) :
+        DBusError("DBus service lookup failed"), path(path),
+        interface(interface)
+    {}
 
-        const std::string path;
-        const std::string interface;
+    const std::string path;
+    const std::string interface;
 };
 
 /**
@@ -94,29 +81,22 @@
  */
 class DBusPropertyError : public DBusError
 {
-    public:
-        DBusPropertyError(
-                const char* msg,
-                const std::string& busName,
-                const std::string& path,
-                const std::string& interface,
-                const std::string& property) :
-            DBusError(msg),
-            busName(busName),
-            path(path),
-            interface(interface),
-            property(property)
-            {
-            }
+  public:
+    DBusPropertyError(const char* msg, const std::string& busName,
+                      const std::string& path, const std::string& interface,
+                      const std::string& property) :
+        DBusError(msg),
+        busName(busName), path(path), interface(interface), property(property)
+    {}
 
-        const std::string busName;
-        const std::string path;
-        const std::string interface;
-        const std::string property;
+    const std::string busName;
+    const std::string path;
+    const std::string interface;
+    const std::string property;
 };
 
 /** @brief Alias for PropertiesChanged signal callbacks. */
-template <typename ...T>
+template <typename... T>
 using Properties = std::map<std::string, std::variant<T...>>;
 
 /** @class SDBusPlus
@@ -125,583 +105,400 @@
 class SDBusPlus
 {
 
-    public:
-        /** @brief Get the bus connection. */
-        static auto& getBus() __attribute__((pure))
-        {
-            static auto bus = sdbusplus::bus::new_default();
-            return bus;
-        }
+  public:
+    /** @brief Get the bus connection. */
+    static auto& getBus() __attribute__((pure))
+    {
+        static auto bus = sdbusplus::bus::new_default();
+        return bus;
+    }
 
-        /** @brief Invoke a method. */
-        template <typename ...Args>
-        static auto callMethod(
-            sdbusplus::bus::bus& bus,
-            const std::string& busName,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& method,
-            Args&& ... args)
+    /** @brief Invoke a method. */
+    template <typename... Args>
+    static auto callMethod(sdbusplus::bus::bus& bus, const std::string& busName,
+                           const std::string& path,
+                           const std::string& interface,
+                           const std::string& method, Args&&... args)
+    {
+        auto reqMsg = bus.new_method_call(busName.c_str(), path.c_str(),
+                                          interface.c_str(), method.c_str());
+        reqMsg.append(std::forward<Args>(args)...);
+        try
         {
-            auto reqMsg = bus.new_method_call(
-                    busName.c_str(),
-                    path.c_str(),
-                    interface.c_str(),
-                    method.c_str());
-            reqMsg.append(std::forward<Args>(args)...);
-            try
-            {
-                auto respMsg = bus.call(reqMsg);
-                if (respMsg.is_method_error())
-                {
-                    throw DBusMethodError{busName, path, interface, method};
-                }
-                return respMsg;
-            }
-            catch (const sdbusplus::exception::SdBusError&)
+            auto respMsg = bus.call(reqMsg);
+            if (respMsg.is_method_error())
             {
                 throw DBusMethodError{busName, path, interface, method};
             }
-        }
-
-        /** @brief Invoke a method. */
-        template <typename ...Args>
-        static auto callMethod(
-            const std::string& busName,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& method,
-            Args&& ... args)
-        {
-            return callMethod(
-                    getBus(),
-                    busName,
-                    path,
-                    interface,
-                    method,
-                    std::forward<Args>(args)...);
-        }
-
-        /** @brief Invoke a method and read the response. */
-        template <typename Ret, typename ...Args>
-        static auto callMethodAndRead(
-            sdbusplus::bus::bus& bus,
-            const std::string& busName,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& method,
-            Args&& ... args)
-        {
-            sdbusplus::message::message respMsg =
-                    callMethod<Args...>(
-                            bus,
-                            busName,
-                            path,
-                            interface,
-                            method,
-                            std::forward<Args>(args)...);
-            Ret resp;
-            respMsg.read(resp);
-            return resp;
-        }
-
-        /** @brief Invoke a method and read the response. */
-        template <typename Ret, typename ...Args>
-        static auto callMethodAndRead(
-            const std::string& busName,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& method,
-            Args&& ... args)
-        {
-            return callMethodAndRead<Ret>(
-                    getBus(),
-                    busName,
-                    path,
-                    interface,
-                    method,
-                    std::forward<Args>(args)...);
-        }
-
-        /** @brief Get subtree from the mapper without checking response. */
-        static auto getSubTreeRaw(
-            sdbusplus::bus::bus& bus,
-            const std::string& path,
-            const std::string& interface,
-            int32_t depth)
-        {
-            using namespace std::literals::string_literals;
-
-            using Path = std::string;
-            using Intf = std::string;
-            using Serv = std::string;
-            using Intfs = std::vector<Intf>;
-            using Objects = std::map<Path, std::map<Serv, Intfs>>;
-            Intfs intfs = {interface};
-
-            return callMethodAndRead<Objects>(
-                    bus,
-                    "xyz.openbmc_project.ObjectMapper"s,
-                    "/xyz/openbmc_project/object_mapper"s,
-                    "xyz.openbmc_project.ObjectMapper"s,
-                    "GetSubTree"s,
-                    path,
-                    depth,
-                    intfs);
-        }
-
-        /** @brief Get subtree from the mapper. */
-        static auto getSubTree(
-            sdbusplus::bus::bus& bus,
-            const std::string& path,
-            const std::string& interface,
-            int32_t depth)
-        {
-            auto mapperResp = getSubTreeRaw(bus, path, interface, depth);
-            if (mapperResp.empty())
-            {
-                phosphor::logging::log<phosphor::logging::level::ERR>(
-                        "Empty response from mapper GetSubTree",
-                        phosphor::logging::entry("SUBTREE=%s", path.c_str()),
-                        phosphor::logging::entry(
-                                "INTERFACE=%s", interface.c_str()),
-                        phosphor::logging::entry("DEPTH=%u", depth));
-                phosphor::logging::elog<detail::errors::InternalFailure>();
-            }
-            return mapperResp;
-        }
-
-        /** @brief Get service from the mapper. */
-        static auto getService(
-            sdbusplus::bus::bus& bus,
-            const std::string& path,
-            const std::string& interface)
-        {
-            using namespace std::literals::string_literals;
-            using GetObject = std::map<std::string, std::vector<std::string>>;
-
-            try
-            {
-                auto mapperResp = callMethodAndRead<GetObject>(
-                        bus,
-                        "xyz.openbmc_project.ObjectMapper"s,
-                        "/xyz/openbmc_project/object_mapper"s,
-                        "xyz.openbmc_project.ObjectMapper"s,
-                        "GetObject"s,
-                        path,
-                        GetObject::mapped_type{interface});
-
-                if (mapperResp.empty())
-                {
-                    //Should never happen.  A missing object would fail
-                    //in callMethodAndRead()
-                    phosphor::logging::log<phosphor::logging::level::ERR>(
-                            "Empty mapper response on service lookup");
-                    throw DBusServiceError{path, interface};
-                }
-                return mapperResp.begin()->first;
-            }
-            catch (DBusMethodError& e)
-            {
-                throw DBusServiceError{path, interface};
-            }
-        }
-
-        /** @brief Get service from the mapper. */
-        static auto getService(
-            const std::string& path,
-            const std::string& interface)
-        {
-            return getService(
-                    getBus(),
-                    path,
-                    interface);
-        }
-
-        /** @brief Get a property with mapper lookup. */
-        template <typename Property>
-        static auto getProperty(
-            sdbusplus::bus::bus& bus,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& property)
-        {
-            using namespace std::literals::string_literals;
-
-            auto service = getService(bus, path, interface);
-            auto msg = callMethod(
-                    bus,
-                    service,
-                    path,
-                    "org.freedesktop.DBus.Properties"s,
-                    "Get"s,
-                    interface,
-                    property);
-            if (msg.is_method_error())
-            {
-                throw DBusPropertyError{
-                        "DBus get property failed",
-                        service,
-                        path,
-                        interface,
-                        property};
-            }
-            std::variant<Property> value;
-            msg.read(value);
-            return std::get<Property>(value);
-        }
-
-        /** @brief Get a property with mapper lookup. */
-        template <typename Property>
-        static auto getProperty(
-            const std::string& path,
-            const std::string& interface,
-            const std::string& property)
-        {
-            return getProperty<Property>(
-                    getBus(),
-                    path,
-                    interface,
-                    property);
-        }
-
-        /** @brief Get a property variant with mapper lookup. */
-        template <typename Variant>
-        static auto getPropertyVariant(
-            sdbusplus::bus::bus& bus,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& property)
-        {
-            using namespace std::literals::string_literals;
-
-            auto service = getService(bus, path, interface);
-            auto msg = callMethod(
-                    bus,
-                    service,
-                    path,
-                    "org.freedesktop.DBus.Properties"s,
-                    "Get"s,
-                    interface,
-                    property);
-            if (msg.is_method_error())
-            {
-                throw DBusPropertyError{
-                        "DBus get property variant failed",
-                        service,
-                        path,
-                        interface,
-                        property};
-            }
-            Variant value;
-            msg.read(value);
-            return value;
-        }
-
-        /** @brief Get a property variant with mapper lookup. */
-        template <typename Variant>
-        static auto getPropertyVariant(
-            const std::string& path,
-            const std::string& interface,
-            const std::string& property)
-        {
-            return getPropertyVariant<Variant>(
-                    getBus(),
-                    path,
-                    interface,
-                    property);
-        }
-
-        /** @brief Get a property without mapper lookup. */
-        template <typename Property>
-        static auto getProperty(
-            sdbusplus::bus::bus& bus,
-            const std::string& service,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& property)
-        {
-            using namespace std::literals::string_literals;
-
-            auto msg = callMethodAndReturn(
-                    bus,
-                    service,
-                    path,
-                    "org.freedesktop.DBus.Properties"s,
-                    "Get"s,
-                    interface,
-                    property);
-            if (msg.is_method_error())
-            {
-                throw DBusPropertyError{
-                        "DBus get property failed",
-                        service,
-                        path,
-                        interface,
-                        property};
-            }
-            std::variant<Property> value;
-            msg.read(value);
-            return std::get<Property>(value);
-        }
-
-        /** @brief Get a property without mapper lookup. */
-        template <typename Property>
-        static auto getProperty(
-            const std::string& service,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& property)
-        {
-            return getProperty<Property>(
-                    getBus(),
-                    service,
-                    path,
-                    interface,
-                    property);
-        }
-
-        /** @brief Get a property variant without mapper lookup. */
-        template <typename Variant>
-        static auto getPropertyVariant(
-            sdbusplus::bus::bus& bus,
-            const std::string& service,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& property)
-        {
-            using namespace std::literals::string_literals;
-
-            auto msg = callMethodAndReturn(
-                    bus,
-                    service,
-                    path,
-                    "org.freedesktop.DBus.Properties"s,
-                    "Get"s,
-                    interface,
-                    property);
-            if (msg.is_method_error())
-            {
-                throw DBusPropertyError{
-                        "DBus get property variant failed",
-                        service,
-                        path,
-                        interface,
-                        property};
-            }
-            Variant value;
-            msg.read(value);
-            return value;
-        }
-
-        /** @brief Get a property variant without mapper lookup. */
-        template <typename Variant>
-        static auto getPropertyVariant(
-            const std::string& service,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& property)
-        {
-            return getPropertyVariant<Variant>(
-                    getBus(),
-                    service,
-                    path,
-                    interface,
-                    property);
-        }
-
-        /** @brief Set a property with mapper lookup. */
-        template <typename Property>
-        static void setProperty(
-            sdbusplus::bus::bus& bus,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& property,
-            Property&& value)
-        {
-            using namespace std::literals::string_literals;
-
-            std::variant<Property> varValue(
-                    std::forward<Property>(value));
-
-            auto service = getService(bus, path, interface);
-            auto msg = callMethodAndReturn(
-                    bus,
-                    service,
-                    path,
-                    "org.freedesktop.DBus.Properties"s,
-                    "Set"s,
-                    interface,
-                    property,
-                    varValue);
-            if (msg.is_method_error())
-            {
-                throw DBusPropertyError{
-                        "DBus set property failed",
-                        service,
-                        path,
-                        interface,
-                        property};
-            }
-        }
-
-        /** @brief Set a property with mapper lookup. */
-        template <typename Property>
-        static void setProperty(
-            const std::string& path,
-            const std::string& interface,
-            const std::string& property,
-            Property&& value)
-        {
-            return setProperty(
-                    getBus(),
-                    path,
-                    interface,
-                    property,
-                    std::forward<Property>(value));
-        }
-
-        /** @brief Set a property without mapper lookup. */
-        template <typename Property>
-        static void setProperty(
-            sdbusplus::bus::bus& bus,
-            const std::string& service,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& property,
-            Property&& value)
-        {
-            using namespace std::literals::string_literals;
-
-            std::variant<Property> varValue(
-                    std::forward<Property>(value));
-
-            auto msg = callMethodAndReturn(
-                    bus,
-                    service,
-                    path,
-                    "org.freedesktop.DBus.Properties"s,
-                    "Set"s,
-                    interface,
-                    property,
-                    varValue);
-            if (msg.is_method_error())
-            {
-                throw DBusPropertyError{
-                        "DBus set property failed",
-                        service,
-                        path,
-                        interface,
-                        property};
-            }
-        }
-
-        /** @brief Set a property without mapper lookup. */
-        template <typename Property>
-        static void setProperty(
-            const std::string& service,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& property,
-            Property&& value)
-        {
-            return setProperty(
-                    getBus(),
-                    service,
-                    path,
-                    interface,
-                    property,
-                    std::forward<Property>(value));
-        }
-
-        /** @brief Invoke method with mapper lookup. */
-        template <typename ...Args>
-        static auto lookupAndCallMethod(
-            sdbusplus::bus::bus& bus,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& method,
-            Args&& ... args)
-        {
-            return callMethod(
-                    bus,
-                    getService(bus, path, interface),
-                    path,
-                    interface,
-                    method,
-                    std::forward<Args>(args)...);
-        }
-
-        /** @brief Invoke method with mapper lookup. */
-        template <typename ...Args>
-        static auto lookupAndCallMethod(
-            const std::string& path,
-            const std::string& interface,
-            const std::string& method,
-            Args&& ... args)
-        {
-            return lookupAndCallMethod(
-                    getBus(),
-                    path,
-                    interface,
-                    method,
-                    std::forward<Args>(args)...);
-        }
-
-        /** @brief Invoke method and read with mapper lookup. */
-        template <typename Ret, typename ...Args>
-        static auto lookupCallMethodAndRead(
-            sdbusplus::bus::bus& bus,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& method,
-            Args&& ... args)
-        {
-            return callMethodAndRead(
-                    bus,
-                    getService(bus, path, interface),
-                    path,
-                    interface,
-                    method,
-                    std::forward<Args>(args)...);
-        }
-
-        /** @brief Invoke method and read with mapper lookup. */
-        template <typename Ret, typename ...Args>
-        static auto lookupCallMethodAndRead(
-            const std::string& path,
-            const std::string& interface,
-            const std::string& method,
-            Args&& ... args)
-        {
-            return lookupCallMethodAndRead<Ret>(
-                    getBus(),
-                    path,
-                    interface,
-                    method,
-                    std::forward<Args>(args)...);
-        }
-
-        /** @brief Invoke a method and return without checking for error. */
-        template <typename ...Args>
-        static auto callMethodAndReturn(
-            sdbusplus::bus::bus& bus,
-            const std::string& busName,
-            const std::string& path,
-            const std::string& interface,
-            const std::string& method,
-            Args&& ... args)
-        {
-            auto reqMsg = bus.new_method_call(
-                    busName.c_str(),
-                    path.c_str(),
-                    interface.c_str(),
-                    method.c_str());
-            reqMsg.append(std::forward<Args>(args)...);
-            auto respMsg = bus.call(reqMsg);
-
             return respMsg;
         }
+        catch (const sdbusplus::exception::SdBusError&)
+        {
+            throw DBusMethodError{busName, path, interface, method};
+        }
+    }
+
+    /** @brief Invoke a method. */
+    template <typename... Args>
+    static auto callMethod(const std::string& busName, const std::string& path,
+                           const std::string& interface,
+                           const std::string& method, Args&&... args)
+    {
+        return callMethod(getBus(), busName, path, interface, method,
+                          std::forward<Args>(args)...);
+    }
+
+    /** @brief Invoke a method and read the response. */
+    template <typename Ret, typename... Args>
+    static auto
+        callMethodAndRead(sdbusplus::bus::bus& bus, const std::string& busName,
+                          const std::string& path, const std::string& interface,
+                          const std::string& method, Args&&... args)
+    {
+        sdbusplus::message::message respMsg = callMethod<Args...>(
+            bus, busName, path, interface, method, std::forward<Args>(args)...);
+        Ret resp;
+        respMsg.read(resp);
+        return resp;
+    }
+
+    /** @brief Invoke a method and read the response. */
+    template <typename Ret, typename... Args>
+    static auto callMethodAndRead(const std::string& busName,
+                                  const std::string& path,
+                                  const std::string& interface,
+                                  const std::string& method, Args&&... args)
+    {
+        return callMethodAndRead<Ret>(getBus(), busName, path, interface,
+                                      method, std::forward<Args>(args)...);
+    }
+
+    /** @brief Get subtree from the mapper without checking response. */
+    static auto getSubTreeRaw(sdbusplus::bus::bus& bus, const std::string& path,
+                              const std::string& interface, int32_t depth)
+    {
+        using namespace std::literals::string_literals;
+
+        using Path = std::string;
+        using Intf = std::string;
+        using Serv = std::string;
+        using Intfs = std::vector<Intf>;
+        using Objects = std::map<Path, std::map<Serv, Intfs>>;
+        Intfs intfs = {interface};
+
+        return callMethodAndRead<Objects>(bus,
+                                          "xyz.openbmc_project.ObjectMapper"s,
+                                          "/xyz/openbmc_project/object_mapper"s,
+                                          "xyz.openbmc_project.ObjectMapper"s,
+                                          "GetSubTree"s, path, depth, intfs);
+    }
+
+    /** @brief Get subtree from the mapper. */
+    static auto getSubTree(sdbusplus::bus::bus& bus, const std::string& path,
+                           const std::string& interface, int32_t depth)
+    {
+        auto mapperResp = getSubTreeRaw(bus, path, interface, depth);
+        if (mapperResp.empty())
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Empty response from mapper GetSubTree",
+                phosphor::logging::entry("SUBTREE=%s", path.c_str()),
+                phosphor::logging::entry("INTERFACE=%s", interface.c_str()),
+                phosphor::logging::entry("DEPTH=%u", depth));
+            phosphor::logging::elog<detail::errors::InternalFailure>();
+        }
+        return mapperResp;
+    }
+
+    /** @brief Get service from the mapper. */
+    static auto getService(sdbusplus::bus::bus& bus, const std::string& path,
+                           const std::string& interface)
+    {
+        using namespace std::literals::string_literals;
+        using GetObject = std::map<std::string, std::vector<std::string>>;
+
+        try
+        {
+            auto mapperResp = callMethodAndRead<GetObject>(
+                bus, "xyz.openbmc_project.ObjectMapper"s,
+                "/xyz/openbmc_project/object_mapper"s,
+                "xyz.openbmc_project.ObjectMapper"s, "GetObject"s, path,
+                GetObject::mapped_type{interface});
+
+            if (mapperResp.empty())
+            {
+                // Should never happen.  A missing object would fail
+                // in callMethodAndRead()
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "Empty mapper response on service lookup");
+                throw DBusServiceError{path, interface};
+            }
+            return mapperResp.begin()->first;
+        }
+        catch (DBusMethodError& e)
+        {
+            throw DBusServiceError{path, interface};
+        }
+    }
+
+    /** @brief Get service from the mapper. */
+    static auto getService(const std::string& path,
+                           const std::string& interface)
+    {
+        return getService(getBus(), path, interface);
+    }
+
+    /** @brief Get a property with mapper lookup. */
+    template <typename Property>
+    static auto getProperty(sdbusplus::bus::bus& bus, const std::string& path,
+                            const std::string& interface,
+                            const std::string& property)
+    {
+        using namespace std::literals::string_literals;
+
+        auto service = getService(bus, path, interface);
+        auto msg =
+            callMethod(bus, service, path, "org.freedesktop.DBus.Properties"s,
+                       "Get"s, interface, property);
+        if (msg.is_method_error())
+        {
+            throw DBusPropertyError{"DBus get property failed", service, path,
+                                    interface, property};
+        }
+        std::variant<Property> value;
+        msg.read(value);
+        return std::get<Property>(value);
+    }
+
+    /** @brief Get a property with mapper lookup. */
+    template <typename Property>
+    static auto getProperty(const std::string& path,
+                            const std::string& interface,
+                            const std::string& property)
+    {
+        return getProperty<Property>(getBus(), path, interface, property);
+    }
+
+    /** @brief Get a property variant with mapper lookup. */
+    template <typename Variant>
+    static auto getPropertyVariant(sdbusplus::bus::bus& bus,
+                                   const std::string& path,
+                                   const std::string& interface,
+                                   const std::string& property)
+    {
+        using namespace std::literals::string_literals;
+
+        auto service = getService(bus, path, interface);
+        auto msg =
+            callMethod(bus, service, path, "org.freedesktop.DBus.Properties"s,
+                       "Get"s, interface, property);
+        if (msg.is_method_error())
+        {
+            throw DBusPropertyError{"DBus get property variant failed", service,
+                                    path, interface, property};
+        }
+        Variant value;
+        msg.read(value);
+        return value;
+    }
+
+    /** @brief Get a property variant with mapper lookup. */
+    template <typename Variant>
+    static auto getPropertyVariant(const std::string& path,
+                                   const std::string& interface,
+                                   const std::string& property)
+    {
+        return getPropertyVariant<Variant>(getBus(), path, interface, property);
+    }
+
+    /** @brief Get a property without mapper lookup. */
+    template <typename Property>
+    static auto getProperty(sdbusplus::bus::bus& bus,
+                            const std::string& service, const std::string& path,
+                            const std::string& interface,
+                            const std::string& property)
+    {
+        using namespace std::literals::string_literals;
+
+        auto msg = callMethodAndReturn(bus, service, path,
+                                       "org.freedesktop.DBus.Properties"s,
+                                       "Get"s, interface, property);
+        if (msg.is_method_error())
+        {
+            throw DBusPropertyError{"DBus get property failed", service, path,
+                                    interface, property};
+        }
+        std::variant<Property> value;
+        msg.read(value);
+        return std::get<Property>(value);
+    }
+
+    /** @brief Get a property without mapper lookup. */
+    template <typename Property>
+    static auto getProperty(const std::string& service, const std::string& path,
+                            const std::string& interface,
+                            const std::string& property)
+    {
+        return getProperty<Property>(getBus(), service, path, interface,
+                                     property);
+    }
+
+    /** @brief Get a property variant without mapper lookup. */
+    template <typename Variant>
+    static auto getPropertyVariant(sdbusplus::bus::bus& bus,
+                                   const std::string& service,
+                                   const std::string& path,
+                                   const std::string& interface,
+                                   const std::string& property)
+    {
+        using namespace std::literals::string_literals;
+
+        auto msg = callMethodAndReturn(bus, service, path,
+                                       "org.freedesktop.DBus.Properties"s,
+                                       "Get"s, interface, property);
+        if (msg.is_method_error())
+        {
+            throw DBusPropertyError{"DBus get property variant failed", service,
+                                    path, interface, property};
+        }
+        Variant value;
+        msg.read(value);
+        return value;
+    }
+
+    /** @brief Get a property variant without mapper lookup. */
+    template <typename Variant>
+    static auto getPropertyVariant(const std::string& service,
+                                   const std::string& path,
+                                   const std::string& interface,
+                                   const std::string& property)
+    {
+        return getPropertyVariant<Variant>(getBus(), service, path, interface,
+                                           property);
+    }
+
+    /** @brief Set a property with mapper lookup. */
+    template <typename Property>
+    static void setProperty(sdbusplus::bus::bus& bus, const std::string& path,
+                            const std::string& interface,
+                            const std::string& property, Property&& value)
+    {
+        using namespace std::literals::string_literals;
+
+        std::variant<Property> varValue(std::forward<Property>(value));
+
+        auto service = getService(bus, path, interface);
+        auto msg = callMethodAndReturn(bus, service, path,
+                                       "org.freedesktop.DBus.Properties"s,
+                                       "Set"s, interface, property, varValue);
+        if (msg.is_method_error())
+        {
+            throw DBusPropertyError{"DBus set property failed", service, path,
+                                    interface, property};
+        }
+    }
+
+    /** @brief Set a property with mapper lookup. */
+    template <typename Property>
+    static void setProperty(const std::string& path,
+                            const std::string& interface,
+                            const std::string& property, Property&& value)
+    {
+        return setProperty(getBus(), path, interface, property,
+                           std::forward<Property>(value));
+    }
+
+    /** @brief Set a property without mapper lookup. */
+    template <typename Property>
+    static void setProperty(sdbusplus::bus::bus& bus,
+                            const std::string& service, const std::string& path,
+                            const std::string& interface,
+                            const std::string& property, Property&& value)
+    {
+        using namespace std::literals::string_literals;
+
+        std::variant<Property> varValue(std::forward<Property>(value));
+
+        auto msg = callMethodAndReturn(bus, service, path,
+                                       "org.freedesktop.DBus.Properties"s,
+                                       "Set"s, interface, property, varValue);
+        if (msg.is_method_error())
+        {
+            throw DBusPropertyError{"DBus set property failed", service, path,
+                                    interface, property};
+        }
+    }
+
+    /** @brief Set a property without mapper lookup. */
+    template <typename Property>
+    static void setProperty(const std::string& service, const std::string& path,
+                            const std::string& interface,
+                            const std::string& property, Property&& value)
+    {
+        return setProperty(getBus(), service, path, interface, property,
+                           std::forward<Property>(value));
+    }
+
+    /** @brief Invoke method with mapper lookup. */
+    template <typename... Args>
+    static auto lookupAndCallMethod(sdbusplus::bus::bus& bus,
+                                    const std::string& path,
+                                    const std::string& interface,
+                                    const std::string& method, Args&&... args)
+    {
+        return callMethod(bus, getService(bus, path, interface), path,
+                          interface, method, std::forward<Args>(args)...);
+    }
+
+    /** @brief Invoke method with mapper lookup. */
+    template <typename... Args>
+    static auto lookupAndCallMethod(const std::string& path,
+                                    const std::string& interface,
+                                    const std::string& method, Args&&... args)
+    {
+        return lookupAndCallMethod(getBus(), path, interface, method,
+                                   std::forward<Args>(args)...);
+    }
+
+    /** @brief Invoke method and read with mapper lookup. */
+    template <typename Ret, typename... Args>
+    static auto lookupCallMethodAndRead(sdbusplus::bus::bus& bus,
+                                        const std::string& path,
+                                        const std::string& interface,
+                                        const std::string& method,
+                                        Args&&... args)
+    {
+        return callMethodAndRead(bus, getService(bus, path, interface), path,
+                                 interface, method,
+                                 std::forward<Args>(args)...);
+    }
+
+    /** @brief Invoke method and read with mapper lookup. */
+    template <typename Ret, typename... Args>
+    static auto lookupCallMethodAndRead(const std::string& path,
+                                        const std::string& interface,
+                                        const std::string& method,
+                                        Args&&... args)
+    {
+        return lookupCallMethodAndRead<Ret>(getBus(), path, interface, method,
+                                            std::forward<Args>(args)...);
+    }
+
+    /** @brief Invoke a method and return without checking for error. */
+    template <typename... Args>
+    static auto callMethodAndReturn(sdbusplus::bus::bus& bus,
+                                    const std::string& busName,
+                                    const std::string& path,
+                                    const std::string& interface,
+                                    const std::string& method, Args&&... args)
+    {
+        auto reqMsg = bus.new_method_call(busName.c_str(), path.c_str(),
+                                          interface.c_str(), method.c_str());
+        reqMsg.append(std::forward<Args>(args)...);
+        auto respMsg = bus.call(reqMsg);
+
+        return respMsg;
+    }
 };
 
 } // namespace util
diff --git a/utility.hpp b/utility.hpp
index 168bd57..7db9047 100644
--- a/utility.hpp
+++ b/utility.hpp
@@ -1,17 +1,17 @@
 #pragma once
 
-#include <sdbusplus/bus.hpp>
-#include <unistd.h>
 #include <fcntl.h>
-#include <phosphor-logging/log.hpp>
-#include <phosphor-logging/elog.hpp>
+#include <unistd.h>
+
 #include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
 #include <xyz/openbmc_project/Common/error.hpp>
 
-
 using namespace phosphor::logging;
-using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
-                            Error::InternalFailure;
+using InternalFailure =
+    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
 
 namespace phosphor
 {
@@ -33,50 +33,47 @@
 
 class FileDescriptor
 {
-    public:
-        FileDescriptor() = delete;
-        FileDescriptor(const FileDescriptor&) = delete;
-        FileDescriptor(FileDescriptor&&) = default;
-        FileDescriptor& operator=(const FileDescriptor&) = delete;
-        FileDescriptor& operator=(FileDescriptor&&) = default;
+  public:
+    FileDescriptor() = delete;
+    FileDescriptor(const FileDescriptor&) = delete;
+    FileDescriptor(FileDescriptor&&) = default;
+    FileDescriptor& operator=(const FileDescriptor&) = delete;
+    FileDescriptor& operator=(FileDescriptor&&) = default;
 
-        FileDescriptor(int fd) : fd(fd)
+    FileDescriptor(int fd) : fd(fd)
+    {}
+
+    ~FileDescriptor()
+    {
+        if (fd != -1)
         {
+            close(fd);
         }
+    }
 
-        ~FileDescriptor()
+    int operator()()
+    {
+        return fd;
+    }
+
+    void open(const std::string& pathname, int flags)
+    {
+        fd = ::open(pathname.c_str(), flags);
+        if (-1 == fd)
         {
-            if (fd != -1)
-            {
-                close(fd);
-            }
+            log<level::ERR>("Failed to open file device: ",
+                            entry("PATHNAME=%s", pathname.c_str()));
+            elog<InternalFailure>();
         }
+    }
 
-        int operator()()
-        {
-            return fd;
-        }
+    bool is_open()
+    {
+        return fd != -1;
+    }
 
-        void open(const std::string& pathname, int flags)
-        {
-            fd = ::open(pathname.c_str(), flags);
-            if (-1 == fd)
-            {
-                log<level::ERR>(
-                     "Failed to open file device: ",
-                     entry("PATHNAME=%s", pathname.c_str()));
-                elog<InternalFailure>();
-            }
-        }
-
-        bool is_open()
-        {
-            return fd != -1;
-        }
-
-    private:
-        int fd = -1;
-
+  private:
+    int fd = -1;
 };
 
 /**
@@ -90,10 +87,8 @@
  * @return - The full object path containing the property value
  */
 template <typename T>
-auto getObjMap(const std::string& path,
-               const std::string& intf,
-               const std::string& prop,
-               const T& value)
+auto getObjMap(const std::string& path, const std::string& intf,
+               const std::string& prop, const T& value)
 {
     using Property = std::string;
     using Value = std::variant<T>;
@@ -116,6 +111,6 @@
     return objectMap;
 }
 
-}
-}
-}
+} // namespace util
+} // namespace fan
+} // namespace phosphor
