diff --git a/src/ExternalSensorMain.cpp b/src/ExternalSensorMain.cpp
index 477a4c6..a096175 100644
--- a/src/ExternalSensorMain.cpp
+++ b/src/ExternalSensorMain.cpp
@@ -165,177 +165,175 @@
         dbusConnection,
         [&objectServer, &sensors, &dbusConnection, sensorsChanged,
          &reaperTimer](const ManagedObjectType& sensorConfigurations) {
-            bool firstScan = (sensorsChanged == nullptr);
+        bool firstScan = (sensorsChanged == nullptr);
 
-            for (const std::pair<sdbusplus::message::object_path, SensorData>&
-                     sensor : sensorConfigurations)
+        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())
             {
-                const std::string& interfacePath = sensor.first.str;
-                const SensorData& sensorData = sensor.second;
+                std::cerr << "Base configuration not found for "
+                          << interfacePath << "\n";
+                continue;
+            }
 
-                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;
 
-                const SensorBaseConfiguration& baseConfiguration = *sensorBase;
-                const SensorBaseConfigMap& baseConfigMap =
-                    baseConfiguration.second;
+            // 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;
+            }
+            double minValue =
+                std::visit(VariantToDoubleVisitor(), minFound->second);
+            if (!std::isfinite(minValue))
+            {
+                std::cerr << "MinValue parameter not parsed for "
+                          << interfacePath << "\n";
+                continue;
+            }
 
-                // 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;
-                }
-                double 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;
+            }
+            double maxValue =
+                std::visit(VariantToDoubleVisitor(), maxFound->second);
+            if (!std::isfinite(maxValue))
+            {
+                std::cerr << "MaxValue 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;
-                }
-                double maxValue =
-                    std::visit(VariantToDoubleVisitor(), maxFound->second);
-                if (!std::isfinite(maxValue))
-                {
-                    std::cerr << "MaxValue parameter not parsed for "
-                              << interfacePath << "\n";
-                    continue;
-                }
+            double timeoutSecs = 0.0;
 
-                double timeoutSecs = 0.0;
+            // Timeout is an optional numeric parameter
+            auto timeoutFound = baseConfigMap.find("Timeout");
+            if (timeoutFound != baseConfigMap.end())
+            {
+                timeoutSecs =
+                    std::visit(VariantToDoubleVisitor(), timeoutFound->second);
+            }
+            if (!(std::isfinite(timeoutSecs) && (timeoutSecs >= 0.0)))
+            {
+                std::cerr << "Timeout parameter not parsed for "
+                          << interfacePath << "\n";
+                continue;
+            }
 
-                // Timeout is an optional numeric parameter
-                auto timeoutFound = baseConfigMap.find("Timeout");
-                if (timeoutFound != baseConfigMap.end())
-                {
-                    timeoutSecs = std::visit(VariantToDoubleVisitor(),
-                                             timeoutFound->second);
-                }
-                if (!(std::isfinite(timeoutSecs) && (timeoutSecs >= 0.0)))
-                {
-                    std::cerr << "Timeout parameter not parsed for "
-                              << interfacePath << "\n";
-                    continue;
-                }
+            std::string sensorName;
+            std::string sensorUnits;
 
-                std::string sensorName;
-                std::string sensorUnits;
+            // Name and Units 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;
+            }
 
-                // Name and Units 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 unitsFound = baseConfigMap.find("Units");
+            if (unitsFound == baseConfigMap.end())
+            {
+                std::cerr << "Units parameter not found for " << interfacePath
+                          << "\n";
+                continue;
+            }
+            sensorUnits =
+                std::visit(VariantToStringVisitor(), unitsFound->second);
+            if (sensorUnits.empty())
+            {
+                std::cerr << "Units parameter not parsed for " << interfacePath
+                          << "\n";
+                continue;
+            }
 
-                auto unitsFound = baseConfigMap.find("Units");
-                if (unitsFound == baseConfigMap.end())
+            // 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::cerr << "Units parameter not found for "
-                              << interfacePath << "\n";
-                    continue;
-                }
-                sensorUnits =
-                    std::visit(VariantToStringVisitor(), unitsFound->second);
-                if (sensorUnits.empty())
-                {
-                    std::cerr << "Units 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))
                     {
-                        std::string suffixIt = "/";
-                        suffixIt += *it;
-                        if (boost::ends_with(suffixIt, suffixName))
+                        sensorsChanged->erase(it);
+                        findSensor->second = nullptr;
+                        found = true;
+                        if constexpr (debug)
                         {
-                            sensorsChanged->erase(it);
-                            findSensor->second = nullptr;
-                            found = true;
-                            if constexpr (debug)
-                            {
-                                std::cerr << "ExternalSensor " << sensorName
-                                          << " change found\n";
-                            }
-                            break;
+                            std::cerr << "ExternalSensor " << sensorName
+                                      << " change found\n";
                         }
-                    }
-                    if (!found)
-                    {
-                        continue;
+                        break;
                     }
                 }
-
-                std::vector<thresholds::Threshold> sensorThresholds;
-                if (!parseThresholdsFromConfig(sensorData, sensorThresholds))
+                if (!found)
                 {
-                    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,
-                    sensorUnits, std::move(sensorThresholds), interfacePath,
-                    maxValue, minValue, timeoutSecs, readState);
-                sensorEntry->initWriteHook(
-                    [&sensors, &reaperTimer](
-                        const std::chrono::steady_clock::time_point& now) {
-                        updateReaper(sensors, reaperTimer, now);
-                    });
-
-                if constexpr (debug)
-                {
-                    std::cerr << "ExternalSensor " << sensorName
-                              << " created\n";
+                    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,
+                sensorUnits, std::move(sensorThresholds), interfacePath,
+                maxValue, minValue, timeoutSecs, readState);
+            sensorEntry->initWriteHook(
+                [&sensors, &reaperTimer](
+                    const std::chrono::steady_clock::time_point& now) {
+                updateReaper(sensors, reaperTimer, now);
+            });
+
+            if constexpr (debug)
+            {
+                std::cerr << "ExternalSensor " << sensorName << " created\n";
+            }
+        }
         });
 
     getter->getConfiguration(std::vector<std::string>{sensorType});
@@ -367,40 +365,39 @@
     std::function<void(sdbusplus::message::message&)> eventHandler =
         [&objectServer, &sensors, &systemBus, &sensorsChanged, &filterTimer,
          &reaperTimer](sdbusplus::message::message& message) mutable {
-            if (message.is_method_error())
+        if (message.is_method_error())
+        {
+            std::cerr << "callback method error\n";
+            return;
+        }
+
+        auto messagePath = message.get_path();
+        sensorsChanged->insert(messagePath);
+        if constexpr (debug)
+        {
+            std::cerr << "ExternalSensor change event received: " << messagePath
+                      << "\n";
+        }
+
+        // this implicitly cancels the timer
+        filterTimer.expires_from_now(boost::posix_time::seconds(1));
+
+        filterTimer.async_wait(
+            [&objectServer, &sensors, &systemBus, &sensorsChanged,
+             &reaperTimer](const boost::system::error_code& ec) mutable {
+            if (ec != boost::system::errc::success)
             {
-                std::cerr << "callback method error\n";
+                if (ec != boost::asio::error::operation_aborted)
+                {
+                    std::cerr << "callback error: " << ec.message() << "\n";
+                }
                 return;
             }
 
-            auto messagePath = message.get_path();
-            sensorsChanged->insert(messagePath);
-            if constexpr (debug)
-            {
-                std::cerr << "ExternalSensor change event received: "
-                          << messagePath << "\n";
-            }
-
-            // this implicitly cancels the timer
-            filterTimer.expires_from_now(boost::posix_time::seconds(1));
-
-            filterTimer.async_wait(
-                [&objectServer, &sensors, &systemBus, &sensorsChanged,
-                 &reaperTimer](const boost::system::error_code& ec) mutable {
-                    if (ec != boost::system::errc::success)
-                    {
-                        if (ec != boost::asio::error::operation_aborted)
-                        {
-                            std::cerr << "callback error: " << ec.message()
-                                      << "\n";
-                        }
-                        return;
-                    }
-
-                    createSensors(objectServer, sensors, systemBus,
-                                  sensorsChanged, reaperTimer);
-                });
-        };
+            createSensors(objectServer, sensors, systemBus, sensorsChanged,
+                          reaperTimer);
+        });
+    };
 
     auto match = std::make_unique<sdbusplus::bus::match::match>(
         static_cast<sdbusplus::bus::bus&>(*systemBus),
