diff --git a/phosphor-power-sequencer/src/config_file_parser.hpp b/phosphor-power-sequencer/src/config_file_parser.hpp
index 3764b7c..dbd41d7 100644
--- a/phosphor-power-sequencer/src/config_file_parser.hpp
+++ b/phosphor-power-sequencer/src/config_file_parser.hpp
@@ -21,6 +21,7 @@
 
 #include <cstdint>
 #include <filesystem>
+#include <memory>
 #include <stdexcept>
 #include <string>
 #include <vector>
diff --git a/phosphor-power-sequencer/src/meson.build b/phosphor-power-sequencer/src/meson.build
index faab116..db3ac4a 100644
--- a/phosphor-power-sequencer/src/meson.build
+++ b/phosphor-power-sequencer/src/meson.build
@@ -21,6 +21,7 @@
     'power_control.cpp',
     'power_interface.cpp',
     'power_sequencer_monitor.cpp',
+    'services.cpp',
     'ucd90x_monitor.cpp',
     'ucd90160_monitor.cpp',
     'ucd90320_monitor.cpp',
diff --git a/phosphor-power-sequencer/src/services.cpp b/phosphor-power-sequencer/src/services.cpp
new file mode 100644
index 0000000..80ad464
--- /dev/null
+++ b/phosphor-power-sequencer/src/services.cpp
@@ -0,0 +1,141 @@
+/**
+ * Copyright © 2024 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "services.hpp"
+
+#include "types.hpp"
+#include "utility.hpp"
+
+#include <sys/types.h> // for getpid()
+#include <unistd.h>    // for getpid()
+
+#include <gpiod.hpp>
+
+#include <exception>
+
+namespace phosphor::power::sequencer
+{
+
+void BMCServices::logError(const std::string& message, Entry::Level severity,
+                           std::map<std::string, std::string>& additionalData)
+{
+    try
+    {
+        // Add PID to AdditionalData
+        additionalData.emplace("_PID", std::to_string(getpid()));
+
+        // If severity is critical, set error as system terminating
+        if (severity == Entry::Level::Critical)
+        {
+            additionalData.emplace("SEVERITY_DETAIL", "SYSTEM_TERM");
+        }
+
+        auto method = bus.new_method_call(
+            "xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging",
+            "xyz.openbmc_project.Logging.Create", "Create");
+        method.append(message, severity, additionalData);
+        bus.call_noreply(method);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error("Unable to log error {ERROR}: {EXCEPTION}", "ERROR", message,
+                   "EXCEPTION", e);
+    }
+}
+
+bool BMCServices::isPresent(const std::string& inventoryPath)
+{
+    // Initially assume hardware is not present
+    bool present{false};
+
+    // Get presence from D-Bus interface/property
+    try
+    {
+        util::getProperty(INVENTORY_IFACE, PRESENT_PROP, inventoryPath,
+                          INVENTORY_MGR_IFACE, bus, present);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        // If exception type is expected and indicates hardware not present
+        if (isExpectedException(e))
+        {
+            present = false;
+        }
+        else
+        {
+            // Re-throw unexpected exception
+            throw;
+        }
+    }
+
+    return present;
+}
+
+std::vector<int> BMCServices::getGPIOValues(const std::string& chipLabel)
+{
+    // Set up the chip object
+    gpiod::chip chip{chipLabel, gpiod::chip::OPEN_BY_LABEL};
+    unsigned int numLines = chip.num_lines();
+    lg2::info(
+        "Reading GPIO values from chip {NAME} with label {LABEL} and {NUM_LINES} lines",
+        "NAME", chip.name(), "LABEL", chipLabel, "NUM_LINES", numLines);
+
+    // Read GPIO values.  Work around libgpiod bulk line maximum by getting
+    // values from individual lines.
+    std::vector<int> values;
+    for (unsigned int offset = 0; offset < numLines; ++offset)
+    {
+        gpiod::line line = chip.get_line(offset);
+        line.request({"phosphor-power-control",
+                      gpiod::line_request::DIRECTION_INPUT, 0});
+        values.push_back(line.get_value());
+        line.release();
+    }
+    return values;
+}
+
+bool BMCServices::isExpectedException(const sdbusplus::exception_t& e)
+{
+    // Initially assume exception is not one of the expected types
+    bool isExpected{false};
+
+    // If the D-Bus error name is set within the exception
+    if (e.name() != nullptr)
+    {
+        // Check if the error name is one of the expected values when hardware
+        // is not present.
+        //
+        // Sometimes the object path does not exist.  Sometimes the object path
+        // exists, but it does not implement the D-Bus interface that contains
+        // the present property.  Both of these cases result in exceptions.
+        //
+        // In the case where the interface is not implemented, the systemd
+        // documentation seems to indicate that the error name should be
+        // SD_BUS_ERROR_UNKNOWN_INTERFACE.  However, in OpenBMC the
+        // SD_BUS_ERROR_UNKNOWN_PROPERTY error name can occur.
+        std::string name = e.name();
+        if ((name == SD_BUS_ERROR_UNKNOWN_OBJECT) ||
+            (name == SD_BUS_ERROR_UNKNOWN_INTERFACE) ||
+            (name == SD_BUS_ERROR_UNKNOWN_PROPERTY))
+        {
+            isExpected = true;
+        }
+    }
+
+    return isExpected;
+}
+
+} // namespace phosphor::power::sequencer
diff --git a/phosphor-power-sequencer/src/services.hpp b/phosphor-power-sequencer/src/services.hpp
new file mode 100644
index 0000000..743c034
--- /dev/null
+++ b/phosphor-power-sequencer/src/services.hpp
@@ -0,0 +1,211 @@
+/**
+ * Copyright © 2024 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "pmbus.hpp"
+#include "xyz/openbmc_project/Logging/Entry/server.hpp"
+
+#include <fmt/format.h>
+
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/exception.hpp>
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace phosphor::power::sequencer
+{
+
+using namespace sdbusplus::xyz::openbmc_project::Logging::server;
+using PMBusBase = phosphor::pmbus::PMBusBase;
+using PMBus = phosphor::pmbus::PMBus;
+
+/**
+ * @class Services
+ *
+ * Abstract base class that provides an interface to system services like error
+ * logging and the journal.
+ */
+class Services
+{
+  public:
+    // Specify which compiler-generated methods we want
+    Services() = default;
+    Services(const Services&) = delete;
+    Services(Services&&) = delete;
+    Services& operator=(const Services&) = delete;
+    Services& operator=(Services&&) = delete;
+    virtual ~Services() = default;
+
+    /**
+     * Returns the D-Bus bus object.
+     *
+     * @return D-Bus bus
+     */
+    virtual sdbusplus::bus_t& getBus() = 0;
+
+    /**
+     * Logs an error message in the system journal.
+     *
+     * @param message message to log
+     */
+    virtual void logErrorMsg(const std::string& message) = 0;
+
+    /**
+     * Logs an informational message in the system journal.
+     *
+     * @param message message to log
+     */
+    virtual void logInfoMsg(const std::string& message) = 0;
+
+    /**
+     * Logs an error.
+     *
+     * If logging fails, a message is written to the system journal but an
+     * exception is not thrown.
+     *
+     * @param message Message property of the error log entry
+     * @param severity Severity property of the error log entry
+     * @param additionalData AdditionalData property of the error log entry
+     */
+    virtual void
+        logError(const std::string& message, Entry::Level severity,
+                 std::map<std::string, std::string>& additionalData) = 0;
+
+    /**
+     * Returns whether the hardware with the specified inventory path is
+     * present.
+     *
+     * Throws an exception if an error occurs while obtaining the presence
+     * value.
+     *
+     * @param inventoryPath D-Bus inventory path of the hardware
+     * @return true if hardware is present, false otherwise
+     */
+    virtual bool isPresent(const std::string& inventoryPath) = 0;
+
+    /**
+     * Reads all the GPIO values on the chip with the specified label.
+     *
+     * Throws an exception if an error occurs while obtaining the values.
+     *
+     * @param chipLabel label identifying the chip with the GPIOs
+     * @return GPIO values
+     */
+    virtual std::vector<int> getGPIOValues(const std::string& chipLabel) = 0;
+
+    /**
+     * Creates object for communicating with a PMBus device by reading and
+     * writing sysfs files.
+     *
+     * Throws an exception if an error occurs.
+     *
+     * @param bus I2C bus
+     * @param address I2C address
+     * @param driverName Device driver name
+     * @param instance Chip instance number
+     * @return object for communicating with PMBus device
+     */
+    virtual std::unique_ptr<PMBusBase>
+        createPMBus(uint8_t bus, uint16_t address,
+                    const std::string& driverName = "",
+                    size_t instance = 0) = 0;
+};
+
+/**
+ * @class BMCServices
+ *
+ * Implementation of the Services interface using standard BMC system services.
+ */
+class BMCServices : public Services
+{
+  public:
+    // Specify which compiler-generated methods we want
+    BMCServices() = delete;
+    BMCServices(const BMCServices&) = delete;
+    BMCServices(BMCServices&&) = delete;
+    BMCServices& operator=(const BMCServices&) = delete;
+    BMCServices& operator=(BMCServices&&) = delete;
+    virtual ~BMCServices() = default;
+
+    /**
+     * Constructor.
+     *
+     * @param bus D-Bus bus object
+     */
+    explicit BMCServices(sdbusplus::bus_t& bus) : bus{bus} {}
+
+    /** @copydoc Services::getBus() */
+    virtual sdbusplus::bus_t& getBus() override
+    {
+        return bus;
+    }
+
+    /** @copydoc Services::logErrorMsg() */
+    virtual void logErrorMsg(const std::string& message) override
+    {
+        lg2::error(message.c_str());
+    }
+
+    /** @copydoc Services::logInfoMsg() */
+    virtual void logInfoMsg(const std::string& message) override
+    {
+        lg2::info(message.c_str());
+    }
+
+    /** @copydoc Services::logError() */
+    virtual void
+        logError(const std::string& message, Entry::Level severity,
+                 std::map<std::string, std::string>& additionalData) override;
+
+    /** @copydoc Services::isPresent() */
+    virtual bool isPresent(const std::string& inventoryPath) override;
+
+    /** @copydoc Services::getGPIOValues() */
+    virtual std::vector<int>
+        getGPIOValues(const std::string& chipLabel) override;
+
+    /** @copydoc Services::createPMBus() */
+    virtual std::unique_ptr<PMBusBase>
+        createPMBus(uint8_t bus, uint16_t address,
+                    const std::string& driverName = "",
+                    size_t instance = 0) override
+    {
+        std::string path = fmt::format("/sys/bus/i2c/devices/{}-{:04x}", bus,
+                                       address);
+        return std::make_unique<PMBus>(path, driverName, instance);
+    }
+
+  private:
+    /**
+     * Returns whether the specified D-Bus exception is one of the expected
+     * types that can be thrown if hardware is not present.
+     *
+     * @return true if exception type is expected, false otherwise
+     */
+    bool isExpectedException(const sdbusplus::exception_t& e);
+
+    /**
+     * D-Bus bus object.
+     */
+    sdbusplus::bus_t& bus;
+};
+
+} // namespace phosphor::power::sequencer
