diff --git a/src/ExternalSensor.cpp b/src/ExternalSensor.cpp
new file mode 100644
index 0000000..13e9415
--- /dev/null
+++ b/src/ExternalSensor.cpp
@@ -0,0 +1,79 @@
+#include "ExternalSensor.hpp"
+
+#include "SensorPaths.hpp"
+
+#include <unistd.h>
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <iostream>
+#include <istream>
+#include <limits>
+#include <memory>
+#include <string>
+#include <vector>
+
+ExternalSensor::ExternalSensor(
+    const std::string& objectType, sdbusplus::asio::object_server& objectServer,
+    std::shared_ptr<sdbusplus::asio::connection>& conn,
+    const std::string& sensorName, const std::string& sensorUnits,
+    std::vector<thresholds::Threshold>&& _thresholds,
+    const std::string& sensorConfiguration, const double& maxReading,
+    const double& minReading, const PowerState& powerState) :
+    // TODO(): When the Mutable feature is integrated,
+    // make sure all ExternalSensor instances are mutable,
+    // because that is the entire point of ExternalSensor,
+    // to accept sensor values written by an external source.
+    Sensor(boost::replace_all_copy(sensorName, " ", "_"),
+           std::move(_thresholds), sensorConfiguration, objectType, maxReading,
+           minReading, conn, powerState),
+    std::enable_shared_from_this<ExternalSensor>(), objServer(objectServer)
+{
+    // The caller must specify what physical characteristic
+    // an external sensor is expected to be measuring, such as temperature,
+    // as, unlike others, this is not implied by device type name.
+    std::string dbusPath = sensors::getPathForUnits(sensorUnits);
+    if (dbusPath.empty())
+    {
+        throw std::runtime_error("Units not in allow list");
+    }
+    std::string objectPath = sensors::objectPathPrefix;
+    objectPath += dbusPath;
+    objectPath += '/';
+    objectPath += sensorName;
+
+    sensorInterface = objectServer.add_interface(
+        objectPath, "xyz.openbmc_project.Sensor.Value");
+
+    if (thresholds::hasWarningInterface(thresholds))
+    {
+        thresholdInterfaceWarning = objectServer.add_interface(
+            objectPath, "xyz.openbmc_project.Sensor.Threshold.Warning");
+    }
+    if (thresholds::hasCriticalInterface(thresholds))
+    {
+        thresholdInterfaceCritical = objectServer.add_interface(
+            objectPath, "xyz.openbmc_project.Sensor.Threshold.Critical");
+    }
+
+    association =
+        objectServer.add_interface(objectPath, association::interface);
+    setInitialProperties(conn);
+}
+
+ExternalSensor::~ExternalSensor()
+{
+    objServer.remove_interface(association);
+    objServer.remove_interface(thresholdInterfaceCritical);
+    objServer.remove_interface(thresholdInterfaceWarning);
+    objServer.remove_interface(sensorInterface);
+}
+
+void ExternalSensor::checkThresholds(void)
+{
+    thresholds::checkThresholds(this);
+}
diff --git a/src/ExternalSensorMain.cpp b/src/ExternalSensorMain.cpp
new file mode 100644
index 0000000..9067d7e
--- /dev/null
+++ b/src/ExternalSensorMain.cpp
@@ -0,0 +1,263 @@
+#include "ExternalSensor.hpp"
+#include "Utils.hpp"
+#include "VariantVisitors.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.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/match.hpp>
+
+#include <array>
+#include <filesystem>
+#include <fstream>
+#include <functional>
+#include <memory>
+#include <regex>
+#include <stdexcept>
+#include <string>
+#include <utility>
+#include <variant>
+#include <vector>
+
+// Copied from HwmonTempSensor and inspired by
+// https://gerrit.openbmc-project.xyz/c/openbmc/dbus-sensors/+/35476
+
+// The ExternalSensor is a sensor whose value is intended to be writable
+// by something external to the BMC, so that the host (or something else)
+// can write to it, perhaps by using an IPMI connection.
+
+// Unlike most other sensors, an external sensor does not correspond
+// to a hwmon file or other kernel/hardware interface,
+// so, after initialization, this module does not have much to do,
+// but it handles reinitialization and thresholds, similar to the others.
+
+// As there is no corresponding driver or hardware to support,
+// all configuration of this sensor comes from the JSON parameters:
+// MinValue, MaxValue, PowerState, Measure, Name
+
+// The purpose of "Measure" is to specify the physical characteristic
+// the external sensor is measuring, because with an external sensor
+// there is no other way to tell, and it will be used for the object path
+// here: /xyz/openbmc_project/sensors/<Measure>/<Name>
+
+static constexpr bool DEBUG = false;
+
+static const char* sensorType =
+    "xyz.openbmc_project.Configuration.ExternalSensor";
+
+void createSensors(
+    boost::asio::io_service& io, sdbusplus::asio::object_server& objectServer,
+    boost::container::flat_map<std::string, std::shared_ptr<ExternalSensor>>&
+        sensors,
+    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
+    const std::shared_ptr<boost::container::flat_set<std::string>>&
+        sensorsChanged)
+{
+    auto getter = std::make_shared<GetSensorConfiguration>(
+        dbusConnection,
+        [&io, &objectServer, &sensors, &dbusConnection,
+         sensorsChanged](const ManagedObjectType& sensorConfigurations) {
+            bool firstScan = (sensorsChanged == nullptr);
+
+            for (const std::pair<sdbusplus::message::object_path, SensorData>&
+                     sensor : sensorConfigurations)
+            {
+                const std::string& interfacePath = sensor.first.str;
+                const SensorData& sensorData = sensor.second;
+
+                auto sensorBase = sensorData.find(sensorType);
+                if (sensorBase == sensorData.end())
+                {
+                    std::cerr << "Base configuration not found for "
+                              << interfacePath << "\n";
+                    continue;
+                }
+
+                const SensorBaseConfiguration& baseConfiguration = *sensorBase;
+                const SensorBaseConfigMap& baseConfigMap =
+                    baseConfiguration.second;
+
+                double minValue;
+                double maxValue;
+
+                // MinValue and MinValue are mandatory numeric parameters
+                auto minFound = baseConfigMap.find("MinValue");
+                if (minFound == baseConfigMap.end())
+                {
+                    std::cerr << "MinValue parameter not found for "
+                              << interfacePath << "\n";
+                    continue;
+                }
+                minValue =
+                    std::visit(VariantToDoubleVisitor(), minFound->second);
+                if (!std::isfinite(minValue))
+                {
+                    std::cerr << "MinValue parameter not parsed for "
+                              << interfacePath << "\n";
+                    continue;
+                }
+
+                auto maxFound = baseConfigMap.find("MaxValue");
+                if (maxFound == baseConfigMap.end())
+                {
+                    std::cerr << "MaxValue parameter not found for "
+                              << interfacePath << "\n";
+                    continue;
+                }
+                maxValue =
+                    std::visit(VariantToDoubleVisitor(), maxFound->second);
+                if (!std::isfinite(maxValue))
+                {
+                    std::cerr << "MaxValue parameter not parsed for "
+                              << interfacePath << "\n";
+                    continue;
+                }
+
+                std::string sensorName;
+                std::string sensorMeasure;
+
+                // Name and Measure are mandatory string parameters
+                auto nameFound = baseConfigMap.find("Name");
+                if (nameFound == baseConfigMap.end())
+                {
+                    std::cerr << "Name parameter not found for "
+                              << interfacePath << "\n";
+                    continue;
+                }
+                sensorName =
+                    std::visit(VariantToStringVisitor(), nameFound->second);
+                if (sensorName.empty())
+                {
+                    std::cerr << "Name parameter not parsed for "
+                              << interfacePath << "\n";
+                    continue;
+                }
+
+                auto measureFound = baseConfigMap.find("Units");
+                if (measureFound == baseConfigMap.end())
+                {
+                    std::cerr << "Units parameter not found for "
+                              << interfacePath << "\n";
+                    continue;
+                }
+                sensorMeasure =
+                    std::visit(VariantToStringVisitor(), measureFound->second);
+                if (sensorMeasure.empty())
+                {
+                    std::cerr << "Measure parameter not parsed for "
+                              << interfacePath << "\n";
+                    continue;
+                }
+
+                // on rescans, only update sensors we were signaled by
+                auto findSensor = sensors.find(sensorName);
+                if (!firstScan && (findSensor != sensors.end()))
+                {
+                    std::string suffixName = "/";
+                    suffixName += findSensor->second->name;
+                    bool found = false;
+                    for (auto it = sensorsChanged->begin();
+                         it != sensorsChanged->end(); it++)
+                    {
+                        std::string suffixIt = "/";
+                        suffixIt += *it;
+                        if (boost::ends_with(suffixIt, suffixName))
+                        {
+                            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 findPowerOn = baseConfiguration.second.find("PowerState");
+                PowerState readState = PowerState::always;
+                if (findPowerOn != baseConfiguration.second.end())
+                {
+                    std::string powerState = std::visit(
+                        VariantToStringVisitor(), findPowerOn->second);
+                    setReadState(powerState, readState);
+                }
+
+                auto& sensorEntry = sensors[sensorName];
+                sensorEntry = nullptr;
+
+                sensorEntry = std::make_shared<ExternalSensor>(
+                    sensorType, objectServer, dbusConnection, sensorName,
+                    sensorMeasure, std::move(sensorThresholds), interfacePath,
+                    maxValue, minValue, readState);
+            }
+        });
+
+    getter->getConfiguration(std::vector<std::string>{sensorType});
+}
+
+int main()
+{
+    boost::asio::io_service io;
+    auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
+    systemBus->request_name("xyz.openbmc_project.ExternalSensor");
+    sdbusplus::asio::object_server objectServer(systemBus);
+    boost::container::flat_map<std::string, std::shared_ptr<ExternalSensor>>
+        sensors;
+    std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
+    auto sensorsChanged =
+        std::make_shared<boost::container::flat_set<std::string>>();
+
+    io.post([&io, &objectServer, &sensors, &systemBus]() {
+        createSensors(io, objectServer, sensors, systemBus, nullptr);
+    });
+
+    boost::asio::deadline_timer filterTimer(io);
+    std::function<void(sdbusplus::message::message&)> eventHandler =
+        [&io, &objectServer, &sensors, &systemBus, &sensorsChanged,
+         &filterTimer](sdbusplus::message::message& 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_from_now(boost::posix_time::seconds(1));
+
+            filterTimer.async_wait([&io, &objectServer, &sensors, &systemBus,
+                                    &sensorsChanged](
+                                       const boost::system::error_code& ec) {
+                if (ec)
+                {
+                    if (ec != boost::asio::error::operation_aborted)
+                    {
+                        std::cerr << "callback error: " << ec.message() << "\n";
+                    }
+                    return;
+                }
+                createSensors(io, objectServer, sensors, systemBus,
+                              sensorsChanged);
+            });
+        };
+
+    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='" + sensorType + "'",
+        eventHandler);
+    matches.emplace_back(std::move(match));
+
+    io.run();
+}
