diff --git a/src/PSUSensor.cpp b/src/PSUSensor.cpp
new file mode 100644
index 0000000..c71b84d
--- /dev/null
+++ b/src/PSUSensor.cpp
@@ -0,0 +1,147 @@
+/*
+// Copyright (c) 2019 Intel 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 <unistd.h>
+
+#include <PSUSensor.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <iostream>
+#include <limits>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <string>
+
+PSUSensor::PSUSensor(const std::string& path, const std::string& objectType,
+                     sdbusplus::asio::object_server& objectServer,
+                     std::shared_ptr<sdbusplus::asio::connection>& conn,
+                     boost::asio::io_service& io, const std::string& sensorName,
+                     std::vector<thresholds::Threshold>&& _thresholds,
+                     const std::string& sensorConfiguration,
+                     std::string& sensorTypeName, unsigned int factor,
+                     double max, double min) :
+    Sensor(boost::replace_all_copy(sensorName, " ", "_"), path,
+           std::move(_thresholds), sensorConfiguration, objectType, max, min),
+    objServer(objectServer), inputDev(io, open(path.c_str(), O_RDONLY)),
+    waitTimer(io), errCount(0), sensorFactor(factor)
+{
+    sensorInterface = objectServer.add_interface(
+        "/xyz/openbmc_project/sensors/" + sensorTypeName + name,
+        "xyz.openbmc_project.Sensor.Value");
+
+    if (thresholds::hasWarningInterface(thresholds))
+    {
+        thresholdInterfaceWarning = objectServer.add_interface(
+            "/xyz/openbmc_project/sensors/" + sensorTypeName + name,
+            "xyz.openbmc_project.Sensor.Threshold.Warning");
+    }
+    if (thresholds::hasCriticalInterface(thresholds))
+    {
+        thresholdInterfaceCritical = objectServer.add_interface(
+            "/xyz/openbmc_project/sensors/" + sensorTypeName + name,
+            "xyz.openbmc_project.Sensor.Threshold.Critical");
+    }
+    setInitialProperties(conn);
+    setupRead();
+}
+
+PSUSensor::~PSUSensor()
+{
+    inputDev.close();
+    waitTimer.cancel();
+    objServer.remove_interface(sensorInterface);
+    objServer.remove_interface(thresholdInterfaceWarning);
+    objServer.remove_interface(thresholdInterfaceCritical);
+}
+
+void PSUSensor::setupRead(void)
+{
+    boost::asio::async_read_until(
+        inputDev, readBuf, '\n',
+        [&](const boost::system::error_code& ec,
+            std::size_t /*bytes_transfered*/) { handleResponse(ec); });
+}
+
+void PSUSensor::handleResponse(const boost::system::error_code& err)
+{
+    if (err == boost::system::errc::bad_file_descriptor)
+    {
+        return;
+    }
+    std::istream responseStream(&readBuf);
+    if (!err)
+    {
+        std::string response;
+        try
+        {
+            std::getline(responseStream, response);
+            float nvalue = std::stof(response);
+            responseStream.clear();
+            nvalue /= sensorFactor;
+            if (overridenState)
+            {
+                nvalue = overriddenValue;
+            }
+            if (nvalue != value)
+            {
+                updateValue(nvalue);
+            }
+            errCount = 0;
+        }
+        catch (const std::invalid_argument&)
+        {
+            errCount++;
+        }
+    }
+    else
+    {
+        errCount++;
+    }
+
+    if (errCount >= warnAfterErrorCount)
+    {
+        if (errCount == warnAfterErrorCount)
+        {
+            std::cerr << "Failure to read sensor " << name << " at " << path
+                      << "\n";
+        }
+        updateValue(0);
+        errCount++;
+    }
+
+    responseStream.clear();
+    inputDev.close();
+    int fd = open(path.c_str(), O_RDONLY);
+    if (fd <= 0)
+    {
+        return;
+    }
+    inputDev.assign(fd);
+    waitTimer.expires_from_now(boost::posix_time::milliseconds(sensorPollMs));
+    waitTimer.async_wait([&](const boost::system::error_code& ec) {
+        if (ec == boost::asio::error::operation_aborted)
+        {
+            return;
+        }
+        setupRead();
+    });
+}
+
+void PSUSensor::checkThresholds(void)
+{
+    thresholds::checkThresholds(this);
+}
diff --git a/src/PSUSensorMain.cpp b/src/PSUSensorMain.cpp
new file mode 100644
index 0000000..c752cc6
--- /dev/null
+++ b/src/PSUSensorMain.cpp
@@ -0,0 +1,310 @@
+/*
+// Copyright (c) 2019 Intel 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 "filesystem.hpp"
+
+#include <PSUSensor.hpp>
+#include <Utils.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/container/flat_set.hpp>
+#include <fstream>
+#include <regex>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+static constexpr std::array<const char*, 1> sensorTypes = {
+    "xyz.openbmc_project.Configuration.pmbus"};
+
+namespace fs = std::filesystem;
+
+void createSensors(
+    boost::asio::io_service& io, sdbusplus::asio::object_server& objectServer,
+    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
+    boost::container::flat_map<std::string, std::unique_ptr<PSUSensor>>&
+        sensors,
+    boost::container::flat_map<SensorType, std::unique_ptr<PSUProperty>>&
+        sensorTable,
+    boost::container::flat_map<std::string, std::string>& labelMatch)
+{
+
+    ManagedObjectType sensorConfigs;
+    bool useCache = false;
+
+    for (const char* type : sensorTypes)
+    {
+        if (!getSensorConfiguration(type, dbusConnection, sensorConfigs,
+                                    useCache))
+        {
+            std::cerr << "error get sensor config from entity manager\n";
+            return;
+        }
+        useCache = true;
+    }
+
+    std::vector<fs::path> pmbusPaths;
+    if (!findFiles(fs::path("/sys/class/hwmon"), "name", pmbusPaths))
+    {
+        std::cerr << "No PSU sensors in system\n";
+        return;
+    }
+
+    boost::container::flat_set<std::string> directories;
+    for (const auto& pmbusPath : pmbusPaths)
+    {
+        const std::string pathStr = pmbusPath.string();
+        auto directory = pmbusPath.parent_path();
+
+        auto ret = directories.insert(directory.string());
+        if (!ret.second)
+        {
+            continue; // check if path i1 already searched
+        }
+
+        auto device = fs::path(directory / "device");
+        std::string deviceName = fs::canonical(device).stem();
+        auto findHyphen = deviceName.find("-");
+        if (findHyphen == std::string::npos)
+        {
+            std::cerr << "found bad device" << deviceName << "\n";
+            continue;
+        }
+        std::string busStr = deviceName.substr(0, findHyphen);
+        std::string addrStr = deviceName.substr(findHyphen + 1);
+
+        size_t bus = 0;
+        size_t addr = 0;
+
+        try
+        {
+            bus = std::stoi(busStr);
+            addr = std::stoi(addrStr, 0, 16);
+        }
+        catch (std::invalid_argument)
+        {
+            continue;
+        }
+
+        std::ifstream nameFile(pmbusPath);
+        if (!nameFile.good())
+        {
+            std::cerr << "Failure reading " << pmbusPath << "\n";
+            continue;
+        }
+
+        std::string pmbusName;
+        std::getline(nameFile, pmbusName);
+        nameFile.close();
+        if (pmbusName != "pmbus")
+        {
+            continue;
+        }
+
+        const std::pair<std::string, boost::container::flat_map<
+                                         std::string, BasicVariantType>>*
+            baseConfig = nullptr;
+        const SensorData* sensorData = nullptr;
+        const std::string* interfacePath = nullptr;
+        const char* sensorType = nullptr;
+
+        for (const std::pair<sdbusplus::message::object_path, SensorData>&
+                 sensor : sensorConfigs)
+        {
+            sensorData = &(sensor.second);
+            for (const char* type : sensorTypes)
+            {
+                auto sensorBase = sensorData->find(type);
+                if (sensorBase != sensorData->end())
+                {
+                    baseConfig = &(*sensorBase);
+                    sensorType = type;
+                    break;
+                }
+            }
+            if (baseConfig == nullptr)
+            {
+                std::cerr << "error finding base configuration for "
+                          << deviceName << "\n";
+                continue;
+            }
+
+            auto configBus = baseConfig->second.find("Bus");
+            auto configAddress = baseConfig->second.find("Address");
+
+            if (configBus == baseConfig->second.end() ||
+                configAddress == baseConfig->second.end())
+            {
+                std::cerr << "error finding necessary entry in configuration";
+                continue;
+            }
+
+            if (std::get<uint64_t>(configBus->second) != bus ||
+                std::get<uint64_t>(configAddress->second) != addr)
+            {
+                continue;
+            }
+
+            interfacePath = &(sensor.first.str);
+            break;
+        }
+        if (interfacePath == nullptr)
+        {
+            std::cerr << "failed to find match for " << deviceName << "\n";
+            continue;
+        }
+
+        auto findSensorName = baseConfig->second.find("Name");
+        if (findSensorName == baseConfig->second.end())
+        {
+            std::cerr << "could not determine configuration name for "
+                      << deviceName << "\n";
+            continue;
+        }
+
+        std::vector<fs::path> powerPaths;
+        if (!findFiles(fs::path(directory), R"(power\d+_input$)", powerPaths,
+                       0))
+        {
+            std::cerr << "No power sensor in PSU\n";
+            continue;
+        }
+
+        for (const auto& powerPath : powerPaths)
+        {
+            auto powerPathStr = powerPath.string();
+            auto labelPath =
+                boost::replace_all_copy(powerPathStr, "input", "label");
+            std::ifstream labelFile(labelPath);
+            if (!labelFile.good())
+            {
+                std::cerr << "Failure reading " << powerPath << "\n";
+                continue;
+            }
+            std::string label;
+            std::getline(labelFile, label);
+            labelFile.close();
+
+            auto findSensor = sensors.find(label);
+            if (findSensor != sensors.end())
+            {
+                continue;
+            }
+
+            std::vector<thresholds::Threshold> sensorThresholds;
+            std::string labelHead = label.substr(0, label.find(" "));
+            parseThresholdsFromConfig(*sensorData, sensorThresholds,
+                                      &labelHead);
+            if (sensorThresholds.empty())
+            {
+                continue;
+            }
+
+            std::string labelName;
+            auto findLabel = labelMatch.find(label);
+            if (findLabel != labelMatch.end())
+            {
+                labelName = findLabel->second;
+            }
+            else
+            {
+                labelName = label;
+            }
+            std::string sensorName =
+                std::get<std::string>(findSensorName->second) + " " + labelName;
+
+            auto findProperty = sensorTable.find(SensorType::powerSensor);
+            if (findProperty == sensorTable.end())
+            {
+                std::cerr << "Cannot find PSU sensorType " << sensorType
+                          << "\n";
+                continue;
+            }
+
+            sensors[sensorName] = std::make_unique<PSUSensor>(
+                powerPathStr, sensorType, objectServer, dbusConnection, io,
+                sensorName, std::move(sensorThresholds), *interfacePath,
+                findProperty->second->sensorTypeName,
+                findProperty->second->sensorScaleFactor,
+                findProperty->second->maxReading,
+                findProperty->second->minReading);
+        }
+    }
+    return;
+}
+
+void propertyInitialize(
+    boost::container::flat_map<SensorType, std::unique_ptr<PSUProperty>>&
+        sensorTable,
+    boost::container::flat_map<std::string, std::string>& labelMatch)
+{
+    sensorTable[SensorType::powerSensor] =
+        std::make_unique<PSUProperty>("power/", 65535, 0, 100000);
+    labelMatch["pin"] = "Input Power";
+}
+
+int main(int argc, char** argv)
+{
+    boost::asio::io_service io;
+    auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
+
+    systemBus->request_name("xyz.openbmc_project.PSUSensor");
+    sdbusplus::asio::object_server objectServer(systemBus);
+    boost::container::flat_map<std::string, std::unique_ptr<PSUSensor>> sensors;
+    boost::container::flat_map<SensorType, std::unique_ptr<PSUProperty>>
+        sensorTable;
+    std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
+    boost::container::flat_map<std::string, std::string> labelMatch;
+
+    propertyInitialize(sensorTable, labelMatch);
+
+    io.post([&]() {
+        createSensors(io, objectServer, systemBus, sensors, sensorTable,
+                      labelMatch);
+    });
+    boost::asio::deadline_timer filterTimer(io);
+    std::function<void(sdbusplus::message::message&)> eventHandler =
+        [&](sdbusplus::message::message& message) {
+            if (message.is_method_error())
+            {
+                std::cerr << "callback method error\n";
+                return;
+            }
+            filterTimer.expires_from_now(boost::posix_time::seconds(1));
+            filterTimer.async_wait([&](const boost::system::error_code& ec) {
+                if (ec == boost::asio::error::operation_aborted)
+                {
+                    return;
+                }
+                else if (ec)
+                {
+                    std::cerr << "timer error\n";
+                }
+                createSensors(io, objectServer, systemBus, sensors, sensorTable,
+                              labelMatch);
+            });
+        };
+
+    for (const char* type : sensorTypes)
+    {
+        auto match = std::make_unique<sdbusplus::bus::match::match>(
+            static_cast<sdbusplus::bus::bus&>(*systemBus),
+            "type='signal',member='PropertiesChanged',path_namespace='" +
+                std::string(inventoryPath) + "',arg0namespace='" + type + "'",
+            eventHandler);
+        matches.emplace_back(std::move(match));
+    }
+    io.run();
+}
