diff --git a/src/fan/FanMain.cpp b/src/fan/FanMain.cpp
new file mode 100644
index 0000000..736d07d
--- /dev/null
+++ b/src/fan/FanMain.cpp
@@ -0,0 +1,679 @@
+/*
+// Copyright (c) 2017 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 "PresenceGpio.hpp"
+#include "PwmSensor.hpp"
+#include "TachSensor.hpp"
+#include "Thresholds.hpp"
+#include "Utils.hpp"
+#include "VariantVisitors.hpp"
+
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/post.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/message.hpp>
+
+#include <array>
+#include <chrono>
+#include <cstddef>
+#include <cstdint>
+#include <filesystem>
+#include <fstream>
+#include <functional>
+#include <ios>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <optional>
+#include <regex>
+#include <string>
+#include <system_error>
+#include <utility>
+#include <variant>
+#include <vector>
+
+namespace fs = std::filesystem;
+
+// The following two structures need to be consistent
+static auto sensorTypes{std::to_array<const char*>(
+    {"AspeedFan", "I2CFan", "NuvotonFan", "HPEFan"})};
+
+enum FanTypes
+{
+    aspeed = 0,
+    i2c,
+    nuvoton,
+    hpe,
+    max,
+};
+
+static_assert(std::tuple_size<decltype(sensorTypes)>::value == FanTypes::max,
+              "sensorTypes element number is not equal to FanTypes number");
+
+constexpr const char* redundancyConfiguration =
+    "xyz.openbmc_project.Configuration.FanRedundancy";
+static std::regex inputRegex(R"(fan(\d+)_input)");
+
+// todo: power supply fan redundancy
+std::optional<RedundancySensor> systemRedundancy;
+
+static const std::map<std::string, FanTypes> compatibleFanTypes = {
+    {"aspeed,ast2400-pwm-tacho", FanTypes::aspeed},
+    {"aspeed,ast2500-pwm-tacho", FanTypes::aspeed},
+    {"aspeed,ast2600-pwm-tach", FanTypes::aspeed},
+    {"nuvoton,npcm750-pwm-fan", FanTypes::nuvoton},
+    {"nuvoton,npcm845-pwm-fan", FanTypes::nuvoton},
+    {"hpe,gxp-fan-ctrl", FanTypes::hpe}
+    // add compatible string here for new fan type
+};
+
+FanTypes getFanType(const fs::path& parentPath)
+{
+    fs::path linkPath = parentPath / "of_node";
+    if (!fs::exists(linkPath))
+    {
+        return FanTypes::i2c;
+    }
+
+    std::string canonical = fs::canonical(linkPath);
+    std::string compatiblePath = canonical + "/compatible";
+    std::ifstream compatibleStream(compatiblePath);
+
+    if (!compatibleStream)
+    {
+        std::cerr << "Error opening " << compatiblePath << "\n";
+        return FanTypes::i2c;
+    }
+
+    std::string compatibleString;
+    while (std::getline(compatibleStream, compatibleString))
+    {
+        compatibleString.pop_back(); // trim EOL before comparisons
+
+        std::map<std::string, FanTypes>::const_iterator compatibleIterator =
+            compatibleFanTypes.find(compatibleString);
+
+        if (compatibleIterator != compatibleFanTypes.end())
+        {
+            return compatibleIterator->second;
+        }
+    }
+
+    return FanTypes::i2c;
+}
+void enablePwm(const fs::path& filePath)
+{
+    std::fstream enableFile(filePath, std::ios::in | std::ios::out);
+    if (!enableFile.good())
+    {
+        std::cerr << "Error read/write " << filePath << "\n";
+        return;
+    }
+
+    std::string regulateMode;
+    std::getline(enableFile, regulateMode);
+    if (regulateMode == "0")
+    {
+        enableFile << 1;
+    }
+}
+bool findPwmfanPath(unsigned int configPwmfanIndex, fs::path& pwmPath)
+{
+    /* Search PWM since pwm-fan had separated
+     * PWM from tach directory and 1 channel only*/
+    std::vector<fs::path> pwmfanPaths;
+    std::string pwnfanDevName("pwm-fan");
+
+    pwnfanDevName += std::to_string(configPwmfanIndex);
+
+    if (!findFiles(fs::path("/sys/class/hwmon"), R"(pwm\d+)", pwmfanPaths))
+    {
+        std::cerr << "No PWMs are found!\n";
+        return false;
+    }
+    for (const auto& path : pwmfanPaths)
+    {
+        std::error_code ec;
+        fs::path link = fs::read_symlink(path.parent_path() / "device", ec);
+
+        if (ec)
+        {
+            std::cerr << "read_symlink() failed: " << ec.message() << " ("
+                      << ec.value() << ")\n";
+            continue;
+        }
+
+        if (link.filename().string() == pwnfanDevName)
+        {
+            pwmPath = path;
+            return true;
+        }
+    }
+    return false;
+}
+bool findPwmPath(const fs::path& directory, unsigned int pwm, fs::path& pwmPath)
+{
+    std::error_code ec;
+
+    /* Assuming PWM file is appeared in the same directory as fanX_input */
+    auto path = directory / ("pwm" + std::to_string(pwm + 1));
+    bool exists = fs::exists(path, ec);
+
+    if (ec || !exists)
+    {
+        /* PWM file not exist or error happened */
+        if (ec)
+        {
+            std::cerr << "exists() failed: " << ec.message() << " ("
+                      << ec.value() << ")\n";
+        }
+        /* try search form pwm-fanX directory */
+        return findPwmfanPath(pwm, pwmPath);
+    }
+
+    pwmPath = path;
+    return true;
+}
+
+// The argument to this function should be the fanN_input file that we want to
+// enable. The function will locate the corresponding fanN_enable file if it
+// exists. Note that some drivers don't provide this file if the sensors are
+// always enabled.
+void enableFanInput(const fs::path& fanInputPath)
+{
+    std::error_code ec;
+    std::string path(fanInputPath.string());
+    boost::replace_last(path, "input", "enable");
+
+    bool exists = fs::exists(path, ec);
+    if (ec || !exists)
+    {
+        return;
+    }
+
+    std::fstream enableFile(path, std::ios::out);
+    if (!enableFile.good())
+    {
+        return;
+    }
+    enableFile << 1;
+}
+
+void createRedundancySensor(
+    const boost::container::flat_map<std::string, std::shared_ptr<TachSensor>>&
+        sensors,
+    const std::shared_ptr<sdbusplus::asio::connection>& conn,
+    sdbusplus::asio::object_server& objectServer)
+{
+    conn->async_method_call(
+        [&objectServer, &sensors](boost::system::error_code& ec,
+                                  const ManagedObjectType& managedObj) {
+            if (ec)
+            {
+                std::cerr << "Error calling entity manager \n";
+                return;
+            }
+            for (const auto& [path, interfaces] : managedObj)
+            {
+                for (const auto& [intf, cfg] : interfaces)
+                {
+                    if (intf == redundancyConfiguration)
+                    {
+                        // currently only support one
+                        auto findCount = cfg.find("AllowedFailures");
+                        if (findCount == cfg.end())
+                        {
+                            std::cerr << "Malformed redundancy record \n";
+                            return;
+                        }
+                        std::vector<std::string> sensorList;
+
+                        for (const auto& [name, sensor] : sensors)
+                        {
+                            sensorList.push_back(
+                                "/xyz/openbmc_project/sensors/fan_tach/" +
+                                sensor->name);
+                        }
+                        systemRedundancy.reset();
+                        systemRedundancy.emplace(RedundancySensor(
+                            std::get<uint64_t>(findCount->second), sensorList,
+                            objectServer, path));
+
+                        return;
+                    }
+                }
+            }
+        },
+        "xyz.openbmc_project.EntityManager", "/xyz/openbmc_project/inventory",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+}
+
+void createSensors(
+    boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
+    boost::container::flat_map<std::string, std::shared_ptr<TachSensor>>&
+        tachSensors,
+    boost::container::flat_map<std::string, std::unique_ptr<PwmSensor>>&
+        pwmSensors,
+    boost::container::flat_map<std::string, std::weak_ptr<PresenceGpio>>&
+        presenceGpios,
+    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
+    const std::shared_ptr<boost::container::flat_set<std::string>>&
+        sensorsChanged,
+    size_t retries = 0)
+{
+    auto getter = std::make_shared<GetSensorConfiguration>(
+        dbusConnection,
+        [&io, &objectServer, &tachSensors, &pwmSensors, &presenceGpios,
+         &dbusConnection,
+         sensorsChanged](const ManagedObjectType& sensorConfigurations) {
+            bool firstScan = sensorsChanged == nullptr;
+            std::vector<fs::path> paths;
+            if (!findFiles(fs::path("/sys/class/hwmon"), R"(fan\d+_input)",
+                           paths))
+            {
+                std::cerr << "No fan sensors in system\n";
+                return;
+            }
+
+            // iterate through all found fan sensors, and try to match them with
+            // configuration
+            for (const auto& path : paths)
+            {
+                std::smatch match;
+                std::string pathStr = path.string();
+
+                std::regex_search(pathStr, match, inputRegex);
+                std::string indexStr = *(match.begin() + 1);
+
+                fs::path directory = path.parent_path();
+                FanTypes fanType = getFanType(directory);
+                std::string cfgIntf = configInterfaceName(sensorTypes[fanType]);
+
+                // convert to 0 based
+                size_t index = std::stoul(indexStr) - 1;
+
+                const char* baseType = nullptr;
+                const SensorData* sensorData = nullptr;
+                const std::string* interfacePath = nullptr;
+                const SensorBaseConfiguration* baseConfiguration = nullptr;
+                for (const auto& [path, cfgData] : sensorConfigurations)
+                {
+                    // find the base of the configuration to see if indexes
+                    // match
+                    auto sensorBaseFind = cfgData.find(cfgIntf);
+                    if (sensorBaseFind == cfgData.end())
+                    {
+                        continue;
+                    }
+
+                    baseConfiguration = &(*sensorBaseFind);
+                    interfacePath = &path.str;
+                    baseType = sensorTypes[fanType];
+
+                    auto findIndex = baseConfiguration->second.find("Index");
+                    if (findIndex == baseConfiguration->second.end())
+                    {
+                        std::cerr
+                            << baseConfiguration->first << " missing index\n";
+                        continue;
+                    }
+                    unsigned int configIndex = std::visit(
+                        VariantToUnsignedIntVisitor(), findIndex->second);
+                    if (configIndex != index)
+                    {
+                        continue;
+                    }
+                    if (fanType == FanTypes::aspeed ||
+                        fanType == FanTypes::nuvoton ||
+                        fanType == FanTypes::hpe)
+                    {
+                        // there will be only 1 aspeed or nuvoton or hpe sensor
+                        // object in sysfs, we found the fan
+                        sensorData = &cfgData;
+                        break;
+                    }
+                    if (fanType == FanTypes::i2c)
+                    {
+                        std::string deviceName =
+                            fs::read_symlink(directory / "device").filename();
+
+                        size_t bus = 0;
+                        size_t addr = 0;
+                        if (!getDeviceBusAddr(deviceName, bus, addr))
+                        {
+                            continue;
+                        }
+
+                        auto findBus = baseConfiguration->second.find("Bus");
+                        auto findAddress =
+                            baseConfiguration->second.find("Address");
+                        if (findBus == baseConfiguration->second.end() ||
+                            findAddress == baseConfiguration->second.end())
+                        {
+                            std::cerr << baseConfiguration->first
+                                      << " missing bus or address\n";
+                            continue;
+                        }
+                        unsigned int configBus = std::visit(
+                            VariantToUnsignedIntVisitor(), findBus->second);
+                        unsigned int configAddress = std::visit(
+                            VariantToUnsignedIntVisitor(), findAddress->second);
+
+                        if (configBus == bus && configAddress == addr)
+                        {
+                            sensorData = &cfgData;
+                            break;
+                        }
+                    }
+                }
+                if (sensorData == nullptr)
+                {
+                    std::cerr
+                        << "failed to find match for " << path.string() << "\n";
+                    continue;
+                }
+
+                auto findSensorName = baseConfiguration->second.find("Name");
+
+                if (findSensorName == baseConfiguration->second.end())
+                {
+                    std::cerr << "could not determine configuration name for "
+                              << path.string() << "\n";
+                    continue;
+                }
+                std::string sensorName =
+                    std::get<std::string>(findSensorName->second);
+
+                // on rescans, only update sensors we were signaled by
+                auto findSensor = tachSensors.find(sensorName);
+                if (!firstScan && findSensor != tachSensors.end())
+                {
+                    bool found = false;
+                    for (auto it = sensorsChanged->begin();
+                         it != sensorsChanged->end(); it++)
+                    {
+                        if (it->ends_with(findSensor->second->name))
+                        {
+                            sensorsChanged->erase(it);
+                            findSensor->second = nullptr;
+                            found = true;
+                            break;
+                        }
+                    }
+                    if (!found)
+                    {
+                        continue;
+                    }
+                }
+                std::vector<thresholds::Threshold> sensorThresholds;
+                if (!parseThresholdsFromConfig(*sensorData, sensorThresholds))
+                {
+                    std::cerr << "error populating thresholds for "
+                              << sensorName << "\n";
+                }
+
+                auto presenceConfig =
+                    sensorData->find(cfgIntf + std::string(".Presence"));
+
+                std::shared_ptr<PresenceGpio> presenceGpio(nullptr);
+
+                // presence sensors are optional
+                if (presenceConfig != sensorData->end())
+                {
+                    auto findPolarity = presenceConfig->second.find("Polarity");
+                    auto findPinName = presenceConfig->second.find("PinName");
+
+                    if (findPinName == presenceConfig->second.end() ||
+                        findPolarity == presenceConfig->second.end())
+                    {
+                        std::cerr << "Malformed Presence Configuration\n";
+                    }
+                    else
+                    {
+                        bool inverted = std::get<std::string>(
+                                            findPolarity->second) == "Low";
+                        const auto* pinName =
+                            std::get_if<std::string>(&findPinName->second);
+
+                        if (pinName != nullptr)
+                        {
+                            auto findPresenceGpio =
+                                presenceGpios.find(*pinName);
+                            if (findPresenceGpio != presenceGpios.end())
+                            {
+                                auto p = findPresenceGpio->second.lock();
+                                if (p)
+                                {
+                                    presenceGpio = p;
+                                }
+                            }
+                            if (!presenceGpio)
+                            {
+                                presenceGpio =
+                                    std::make_shared<EventPresenceGpio>(
+                                        "Fan", sensorName, *pinName, inverted,
+                                        io);
+                                presenceGpios[*pinName] = presenceGpio;
+                            }
+                        }
+                        else
+                        {
+                            std::cerr
+                                << "Malformed Presence pinName for sensor "
+                                << sensorName << " \n";
+                        }
+                    }
+                }
+                std::optional<RedundancySensor>* redundancy = nullptr;
+                if (fanType == FanTypes::aspeed)
+                {
+                    redundancy = &systemRedundancy;
+                }
+
+                PowerState powerState =
+                    getPowerState(baseConfiguration->second);
+
+                constexpr double defaultMaxReading = 25000;
+                constexpr double defaultMinReading = 0;
+                std::pair<double, double> limits =
+                    std::make_pair(defaultMinReading, defaultMaxReading);
+
+                auto connector =
+                    sensorData->find(cfgIntf + std::string(".Connector"));
+
+                std::optional<std::string> led;
+                std::string pwmName;
+                fs::path pwmPath;
+
+                // The Mutable parameter is optional, defaulting to false
+                bool isValueMutable = false;
+                if (connector != sensorData->end())
+                {
+                    auto findPwm = connector->second.find("Pwm");
+                    if (findPwm != connector->second.end())
+                    {
+                        size_t pwm = std::visit(VariantToUnsignedIntVisitor(),
+                                                findPwm->second);
+                        if (!findPwmPath(directory, pwm, pwmPath))
+                        {
+                            std::cerr << "Connector for " << sensorName
+                                      << " no pwm channel found!\n";
+                            continue;
+                        }
+
+                        fs::path pwmEnableFile =
+                            "pwm" + std::to_string(pwm + 1) + "_enable";
+                        fs::path enablePath =
+                            pwmPath.parent_path() / pwmEnableFile;
+                        enablePwm(enablePath);
+
+                        /* use pwm name override if found in configuration else
+                         * use default */
+                        auto findOverride = connector->second.find("PwmName");
+                        if (findOverride != connector->second.end())
+                        {
+                            pwmName = std::visit(VariantToStringVisitor(),
+                                                 findOverride->second);
+                        }
+                        else
+                        {
+                            pwmName = "Pwm_" + std::to_string(pwm + 1);
+                        }
+
+                        // Check PWM sensor mutability
+                        auto findMutable = connector->second.find("Mutable");
+                        if (findMutable != connector->second.end())
+                        {
+                            const auto* ptrMutable =
+                                std::get_if<bool>(&(findMutable->second));
+                            if (ptrMutable != nullptr)
+                            {
+                                isValueMutable = *ptrMutable;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        std::cerr << "Connector for " << sensorName
+                                  << " missing pwm!\n";
+                    }
+
+                    auto findLED = connector->second.find("LED");
+                    if (findLED != connector->second.end())
+                    {
+                        const auto* ledName =
+                            std::get_if<std::string>(&(findLED->second));
+                        if (ledName == nullptr)
+                        {
+                            std::cerr << "Wrong format for LED of "
+                                      << sensorName << "\n";
+                        }
+                        else
+                        {
+                            led = *ledName;
+                        }
+                    }
+                }
+
+                findLimits(limits, baseConfiguration);
+
+                enableFanInput(path);
+
+                auto& tachSensor = tachSensors[sensorName];
+                tachSensor = nullptr;
+                tachSensor = std::make_shared<TachSensor>(
+                    path.string(), baseType, objectServer, dbusConnection,
+                    presenceGpio, redundancy, io, sensorName,
+                    std::move(sensorThresholds), *interfacePath, limits,
+                    powerState, led);
+                tachSensor->setupRead();
+
+                if (!pwmPath.empty() && fs::exists(pwmPath) &&
+                    (pwmSensors.count(pwmPath) == 0U))
+                {
+                    pwmSensors[pwmPath] = std::make_unique<PwmSensor>(
+                        pwmName, pwmPath, dbusConnection, objectServer,
+                        *interfacePath, "Fan", isValueMutable);
+                }
+            }
+
+            createRedundancySensor(tachSensors, dbusConnection, objectServer);
+        });
+    getter->getConfiguration(
+        std::vector<std::string>{sensorTypes.begin(), sensorTypes.end()},
+        retries);
+}
+
+int main()
+{
+    boost::asio::io_context io;
+    auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
+    sdbusplus::asio::object_server objectServer(systemBus, true);
+
+    objectServer.add_manager("/xyz/openbmc_project/sensors");
+    objectServer.add_manager("/xyz/openbmc_project/control");
+    objectServer.add_manager("/xyz/openbmc_project/inventory");
+    systemBus->request_name("xyz.openbmc_project.FanSensor");
+    boost::container::flat_map<std::string, std::shared_ptr<TachSensor>>
+        tachSensors;
+    boost::container::flat_map<std::string, std::unique_ptr<PwmSensor>>
+        pwmSensors;
+    boost::container::flat_map<std::string, std::weak_ptr<PresenceGpio>>
+        presenceGpios;
+    auto sensorsChanged =
+        std::make_shared<boost::container::flat_set<std::string>>();
+
+    boost::asio::post(io, [&]() {
+        createSensors(io, objectServer, tachSensors, pwmSensors, presenceGpios,
+                      systemBus, nullptr);
+    });
+
+    boost::asio::steady_timer filterTimer(io);
+    std::function<void(sdbusplus::message_t&)> eventHandler =
+        [&](sdbusplus::message_t& message) {
+            if (message.is_method_error())
+            {
+                std::cerr << "callback method error\n";
+                return;
+            }
+            sensorsChanged->insert(message.get_path());
+            // this implicitly cancels the timer
+            filterTimer.expires_after(std::chrono::seconds(1));
+
+            filterTimer.async_wait([&](const boost::system::error_code& ec) {
+                if (ec == boost::asio::error::operation_aborted)
+                {
+                    /* we were canceled*/
+                    return;
+                }
+                if (ec)
+                {
+                    std::cerr << "timer error\n";
+                    return;
+                }
+                createSensors(io, objectServer, tachSensors, pwmSensors,
+                              presenceGpios, systemBus, sensorsChanged, 5);
+            });
+        };
+
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(*systemBus, sensorTypes, eventHandler);
+
+    // redundancy sensor
+    std::function<void(sdbusplus::message_t&)> redundancyHandler =
+        [&tachSensors, &systemBus, &objectServer](sdbusplus::message_t&) {
+            createRedundancySensor(tachSensors, systemBus, objectServer);
+        };
+    auto match = std::make_unique<sdbusplus::bus::match_t>(
+        static_cast<sdbusplus::bus_t&>(*systemBus),
+        "type='signal',member='PropertiesChanged',path_namespace='" +
+            std::string(inventoryPath) + "',arg0namespace='" +
+            redundancyConfiguration + "'",
+        std::move(redundancyHandler));
+    matches.emplace_back(std::move(match));
+
+    setupManufacturingModeMatch(*systemBus);
+    io.run();
+    return 0;
+}
diff --git a/src/fan/PresenceGpio.cpp b/src/fan/PresenceGpio.cpp
new file mode 100644
index 0000000..6c528d7
--- /dev/null
+++ b/src/fan/PresenceGpio.cpp
@@ -0,0 +1,118 @@
+/*
+// Copyright (c) 2018 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 "PresenceGpio.hpp"
+
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/posix/stream_descriptor.hpp>
+#include <gpiod.hpp>
+
+#include <iostream>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <system_error>
+
+PresenceGpio::~PresenceGpio()
+{
+    gpioLine.release();
+}
+
+void PresenceGpio::updateAndTracePresence()
+{
+    status = (gpioLine.get_value() != 0);
+    if (status)
+    {
+        logPresent(deviceName);
+    }
+    else
+    {
+        logRemoved(deviceName);
+    }
+}
+
+EventPresenceGpio::EventPresenceGpio(
+    const std::string& iDeviceType, const std::string& iDeviceName,
+    const std::string& gpioName, bool inverted, boost::asio::io_context& io) :
+    PresenceGpio(iDeviceType, iDeviceName), gpioFd(io)
+{
+    gpioLine = gpiod::find_line(gpioName);
+    if (!gpioLine)
+    {
+        std::cerr << "Error requesting gpio: " << gpioName << "\n";
+        return;
+    }
+
+    try
+    {
+        gpioLine.request(
+            {deviceType + "Sensor", gpiod::line_request::EVENT_BOTH_EDGES,
+             inverted ? gpiod::line_request::FLAG_ACTIVE_LOW : 0});
+        updateAndTracePresence();
+
+        int gpioLineFd = gpioLine.event_get_fd();
+        if (gpioLineFd < 0)
+        {
+            std::cerr << "Failed to get " << gpioName << " fd\n";
+            throw std::runtime_error("Failed to get GPIO fd " + gpioName);
+        }
+
+        gpioFd.assign(gpioLineFd);
+    }
+    catch (const std::system_error& e)
+    {
+        std::cerr << "Error reading gpio " << gpioName << ": " << e.what()
+                  << "\n";
+        return;
+    }
+
+    monitorPresence();
+}
+
+void EventPresenceGpio::monitorPresence()
+{
+    std::weak_ptr<EventPresenceGpio> weakRef = weak_from_this();
+    gpioFd.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [weakRef](const boost::system::error_code& ec) {
+            std::shared_ptr<EventPresenceGpio> self = weakRef.lock();
+            if (!self)
+            {
+                std::cerr << "Failed to get lock for eventPresenceGpio: "
+                          << ec.message() << "\n";
+                return;
+            }
+            if (ec)
+            {
+                if (ec != boost::system::errc::bad_file_descriptor)
+                {
+                    std::cerr
+                        << "Error on event presence device " << self->deviceName
+                        << ": " << ec.message() << "\n";
+                }
+                return;
+            }
+            self->read();
+            self->monitorPresence();
+        });
+}
+
+void EventPresenceGpio::read()
+{
+    // Read is invoked when an edge event is detected by monitorPresence
+    gpioLine.event_read();
+    updateAndTracePresence();
+}
diff --git a/src/fan/PresenceGpio.hpp b/src/fan/PresenceGpio.hpp
new file mode 100644
index 0000000..54805cf
--- /dev/null
+++ b/src/fan/PresenceGpio.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+#include "sensor.hpp"
+
+#include <gpiod.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+class PresenceGpio
+{
+  public:
+    PresenceGpio(const std::string& type, const std::string& name) :
+        deviceType(type), deviceName(name) {};
+    PresenceGpio(const PresenceGpio&) = delete;
+    PresenceGpio& operator=(const PresenceGpio&) = delete;
+    virtual ~PresenceGpio() = 0;
+
+    bool isPresent() const
+    {
+        return status;
+    }
+
+  protected:
+    gpiod::line gpioLine;
+    bool status = false;
+    std::string deviceType;
+    std::string deviceName;
+
+    virtual void monitorPresence() = 0;
+
+    void logPresent(const std::string& device)
+    {
+        std::string summary = deviceType + " " + deviceName + " Inserted";
+        std::string msg = "OpenBMC.0.1." + deviceType + "Inserted";
+        lg2::info(summary.c_str(), "REDFISH_MESSAGE_ID", msg.c_str(),
+                  "REDFISH_MESSAGE_ARGS", device);
+    }
+
+    void logRemoved(const std::string& device)
+    {
+        std::string summary = deviceType + " " + deviceName + " Removed";
+        std::string msg = "OpenBMC.0.1." + deviceType + "Removed";
+        lg2::error(summary.c_str(), "REDFISH_MESSAGE_ID", msg.c_str(),
+                   "REDFISH_MESSAGE_ARGS", device);
+    }
+
+    void updateAndTracePresence();
+};
+
+class EventPresenceGpio :
+    public PresenceGpio,
+    public std::enable_shared_from_this<EventPresenceGpio>
+{
+  public:
+    EventPresenceGpio(const std::string& iDeviceType,
+                      const std::string& iDeviceName,
+                      const std::string& gpioName, bool inverted,
+                      boost::asio::io_context& io);
+
+  private:
+    boost::asio::posix::stream_descriptor gpioFd;
+
+    void monitorPresence() override;
+    void read();
+};
diff --git a/src/fan/TachSensor.cpp b/src/fan/TachSensor.cpp
new file mode 100644
index 0000000..7908488
--- /dev/null
+++ b/src/fan/TachSensor.cpp
@@ -0,0 +1,274 @@
+/*
+// Copyright (c) 2018 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 "TachSensor.hpp"
+
+#include "PresenceGpio.hpp"
+#include "SensorPaths.hpp"
+#include "Thresholds.hpp"
+#include "Utils.hpp"
+#include "sensor.hpp"
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/random_access_file.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <charconv>
+#include <chrono>
+#include <cstddef>
+#include <cstdint>
+#include <iostream>
+#include <memory>
+#include <optional>
+#include <string>
+#include <system_error>
+#include <utility>
+#include <vector>
+
+static constexpr unsigned int pwmPollMs = 500;
+
+TachSensor::TachSensor(
+    const std::string& path, const std::string& objectType,
+    sdbusplus::asio::object_server& objectServer,
+    std::shared_ptr<sdbusplus::asio::connection>& conn,
+    std::shared_ptr<PresenceGpio>& presenceGpio,
+    std::optional<RedundancySensor>* redundancy, boost::asio::io_context& io,
+    const std::string& fanName,
+    std::vector<thresholds::Threshold>&& thresholdsIn,
+    const std::string& sensorConfiguration,
+    const std::pair<double, double>& limits, const PowerState& powerState,
+    const std::optional<std::string>& ledIn) :
+    Sensor(escapeName(fanName), std::move(thresholdsIn), sensorConfiguration,
+           objectType, false, false, limits.second, limits.first, conn,
+           powerState),
+    objServer(objectServer), redundancy(redundancy), presence(presenceGpio),
+    inputDev(io, path, boost::asio::random_access_file::read_only),
+    waitTimer(io), path(path), led(ledIn)
+{
+    sensorInterface = objectServer.add_interface(
+        "/xyz/openbmc_project/sensors/fan_tach/" + name,
+        "xyz.openbmc_project.Sensor.Value");
+
+    for (const auto& threshold : thresholds)
+    {
+        std::string interface = thresholds::getInterface(threshold.level);
+        thresholdInterfaces[static_cast<size_t>(threshold.level)] =
+            objectServer.add_interface(
+                "/xyz/openbmc_project/sensors/fan_tach/" + name, interface);
+    }
+    association = objectServer.add_interface(
+        "/xyz/openbmc_project/sensors/fan_tach/" + name,
+        association::interface);
+
+    if (presence)
+    {
+        itemIface =
+            objectServer.add_interface("/xyz/openbmc_project/inventory/" + name,
+                                       "xyz.openbmc_project.Inventory.Item");
+        itemIface->register_property("PrettyName",
+                                     std::string()); // unused property
+        itemIface->register_property("Present", true);
+        itemIface->initialize();
+        itemAssoc = objectServer.add_interface(
+            "/xyz/openbmc_project/inventory/" + name, association::interface);
+        itemAssoc->register_property(
+            "Associations",
+            std::vector<Association>{
+                {"sensors", "inventory",
+                 "/xyz/openbmc_project/sensors/fan_tach/" + name}});
+        itemAssoc->initialize();
+    }
+    setInitialProperties(sensor_paths::unitRPMs);
+}
+
+TachSensor::~TachSensor()
+{
+    // close the input dev to cancel async operations
+    inputDev.close();
+    waitTimer.cancel();
+    for (const auto& iface : thresholdInterfaces)
+    {
+        objServer.remove_interface(iface);
+    }
+    objServer.remove_interface(sensorInterface);
+    objServer.remove_interface(association);
+    objServer.remove_interface(itemIface);
+    objServer.remove_interface(itemAssoc);
+}
+
+void TachSensor::setupRead()
+{
+    std::weak_ptr<TachSensor> weakRef = weak_from_this();
+    inputDev.async_read_some_at(
+        0, boost::asio::buffer(readBuf),
+        [weakRef](const boost::system::error_code& ec, std::size_t bytesRead) {
+            std::shared_ptr<TachSensor> self = weakRef.lock();
+            if (self)
+            {
+                self->handleResponse(ec, bytesRead);
+            }
+        });
+}
+
+void TachSensor::restartRead(size_t pollTime)
+{
+    std::weak_ptr<TachSensor> weakRef = weak_from_this();
+    waitTimer.expires_after(std::chrono::milliseconds(pollTime));
+    waitTimer.async_wait([weakRef](const boost::system::error_code& ec) {
+        if (ec == boost::asio::error::operation_aborted)
+        {
+            return; // we're being canceled
+        }
+        std::shared_ptr<TachSensor> self = weakRef.lock();
+        if (!self)
+        {
+            return;
+        }
+        self->setupRead();
+    });
+}
+
+void TachSensor::handleResponse(const boost::system::error_code& err,
+                                size_t bytesRead)
+{
+    if ((err == boost::system::errc::bad_file_descriptor) ||
+        (err == boost::asio::error::misc_errors::not_found))
+    {
+        std::cerr << "TachSensor " << name << " removed " << path << "\n";
+        return; // we're being destroyed
+    }
+    bool missing = false;
+    size_t pollTime = pwmPollMs;
+    if (presence)
+    {
+        if (!presence->isPresent())
+        {
+            markAvailable(false);
+            missing = true;
+            pollTime = sensorFailedPollTimeMs;
+        }
+        itemIface->set_property("Present", !missing);
+    }
+
+    if (!missing)
+    {
+        if (!err)
+        {
+            const char* bufEnd = readBuf.data() + bytesRead;
+            int nvalue = 0;
+            std::from_chars_result ret =
+                std::from_chars(readBuf.data(), bufEnd, nvalue);
+            if (ret.ec != std::errc())
+            {
+                incrementError();
+                pollTime = sensorFailedPollTimeMs;
+            }
+            else
+            {
+                updateValue(nvalue);
+            }
+        }
+        else
+        {
+            incrementError();
+            pollTime = sensorFailedPollTimeMs;
+        }
+    }
+
+    restartRead(pollTime);
+}
+
+void TachSensor::checkThresholds()
+{
+    bool status = thresholds::checkThresholds(this);
+
+    if ((redundancy != nullptr) && *redundancy)
+    {
+        (*redundancy)
+            ->update("/xyz/openbmc_project/sensors/fan_tach/" + name, !status);
+    }
+
+    bool curLed = !status;
+    if (led && ledState != curLed)
+    {
+        ledState = curLed;
+        setLed(dbusConnection, *led, curLed);
+    }
+}
+
+RedundancySensor::RedundancySensor(size_t count,
+                                   const std::vector<std::string>& children,
+                                   sdbusplus::asio::object_server& objectServer,
+                                   const std::string& sensorConfiguration) :
+    count(count),
+    iface(objectServer.add_interface(
+        "/xyz/openbmc_project/control/FanRedundancy/Tach",
+        "xyz.openbmc_project.Control.FanRedundancy")),
+    association(objectServer.add_interface(
+        "/xyz/openbmc_project/control/FanRedundancy/Tach",
+        association::interface)),
+    objectServer(objectServer)
+{
+    createAssociation(association, sensorConfiguration);
+    iface->register_property("Collection", children);
+    iface->register_property("Status", std::string("Full"));
+    iface->register_property("AllowedFailures", static_cast<uint8_t>(count));
+    iface->initialize();
+}
+RedundancySensor::~RedundancySensor()
+{
+    objectServer.remove_interface(association);
+    objectServer.remove_interface(iface);
+}
+void RedundancySensor::update(const std::string& name, bool failed)
+{
+    statuses[name] = failed;
+    size_t failedCount = 0;
+
+    std::string newState = redundancy::full;
+    for (const auto& [name, status] : statuses)
+    {
+        if (status)
+        {
+            failedCount++;
+        }
+        if (failedCount > count)
+        {
+            newState = redundancy::failed;
+            break;
+        }
+        if (failedCount != 0U)
+        {
+            newState = redundancy::degraded;
+        }
+    }
+    if (state != newState)
+    {
+        if (state == redundancy::full)
+        {
+            logFanRedundancyLost();
+        }
+        else if (newState == redundancy::full)
+        {
+            logFanRedundancyRestored();
+        }
+        state = newState;
+        iface->set_property("Status", state);
+    }
+}
diff --git a/src/fan/TachSensor.hpp b/src/fan/TachSensor.hpp
new file mode 100644
index 0000000..d2ca101
--- /dev/null
+++ b/src/fan/TachSensor.hpp
@@ -0,0 +1,95 @@
+#pragma once
+
+#include "PresenceGpio.hpp"
+#include "Thresholds.hpp"
+#include "sensor.hpp"
+
+#include <boost/asio/random_access_file.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <gpiod.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <memory>
+#include <optional>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace redundancy
+{
+constexpr const char* full = "Full";
+constexpr const char* degraded = "Degraded";
+constexpr const char* failed = "Failed";
+} // namespace redundancy
+
+class RedundancySensor
+{
+  public:
+    RedundancySensor(size_t count, const std::vector<std::string>& children,
+                     sdbusplus::asio::object_server& objectServer,
+                     const std::string& sensorConfiguration);
+    ~RedundancySensor();
+
+    void update(const std::string& name, bool failed);
+
+  private:
+    size_t count;
+    std::string state = redundancy::full;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> iface;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> association;
+    sdbusplus::asio::object_server& objectServer;
+    boost::container::flat_map<std::string, bool> statuses;
+
+    static void logFanRedundancyLost()
+    {
+        const auto* msg = "OpenBMC.0.1.FanRedundancyLost";
+        lg2::error("Fan Inserted", "REDFISH_MESSAGE_ID", msg);
+    }
+
+    static void logFanRedundancyRestored()
+    {
+        const auto* msg = "OpenBMC.0.1.FanRedundancyRegained";
+        lg2::error("Fan Removed", "REDFISH_MESSAGE_ID", msg);
+    }
+};
+
+class TachSensor :
+    public Sensor,
+    public std::enable_shared_from_this<TachSensor>
+{
+  public:
+    TachSensor(const std::string& path, const std::string& objectType,
+               sdbusplus::asio::object_server& objectServer,
+               std::shared_ptr<sdbusplus::asio::connection>& conn,
+               std::shared_ptr<PresenceGpio>& presence,
+               std::optional<RedundancySensor>* redundancy,
+               boost::asio::io_context& io, const std::string& fanName,
+               std::vector<thresholds::Threshold>&& thresholds,
+               const std::string& sensorConfiguration,
+               const std::pair<double, double>& limits,
+               const PowerState& powerState,
+               const std::optional<std::string>& led);
+    ~TachSensor() override;
+    void setupRead();
+
+  private:
+    // Ordering is important here; readBuf is first so that it's not destroyed
+    // while async operations from other member fields might still be using it.
+    std::array<char, 128> readBuf{};
+    sdbusplus::asio::object_server& objServer;
+    std::optional<RedundancySensor>* redundancy;
+    std::shared_ptr<PresenceGpio> presence;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> itemIface;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> itemAssoc;
+    boost::asio::random_access_file inputDev;
+    boost::asio::steady_timer waitTimer;
+    std::string path;
+    std::optional<std::string> led;
+    bool ledState = false;
+
+    void handleResponse(const boost::system::error_code& err, size_t bytesRead);
+    void restartRead(size_t pollTime);
+    void checkThresholds() override;
+};
diff --git a/src/fan/meson.build b/src/fan/meson.build
new file mode 100644
index 0000000..93f8ae6
--- /dev/null
+++ b/src/fan/meson.build
@@ -0,0 +1,17 @@
+src_inc = include_directories('..')
+
+executable(
+    'fansensor',
+    'FanMain.cpp',
+    'PresenceGpio.cpp',
+    'TachSensor.cpp',
+    '../PwmSensor.cpp',
+    dependencies: [
+        default_deps,
+        gpiodcxx,
+        thresholds_dep,
+        utils_dep,
+    ],
+    include_directories: src_inc,
+    install: true,
+)
\ No newline at end of file
