diff --git a/include/sel_logger.hpp b/include/sel_logger.hpp
new file mode 100644
index 0000000..aa9d8d6
--- /dev/null
+++ b/include/sel_logger.hpp
@@ -0,0 +1,39 @@
+/*
+// 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.
+*/
+
+#pragma once
+
+static constexpr char const *ipmiSelObject = "xyz.openbmc_project.Logging.IPMI";
+static constexpr char const *ipmiSelPath = "/xyz/openbmc_project/Logging/IPMI";
+static constexpr char const *ipmiSelAddInterface =
+    "xyz.openbmc_project.Logging.IPMI";
+
+// ID string generated using journalctl to include in the MESSAGE_ID field for
+// SEL entries.  Helps with filtering SEL entries in the journal.
+static constexpr char const *selMessageId = "b370836ccf2f4850ac5bee185b77893a";
+static constexpr int selPriority = 5; // notice
+static constexpr uint8_t selSystemType = 0x02;
+static constexpr uint16_t selBMCGenID = 0x0020;
+static constexpr uint16_t selInvalidRecID =
+    std::numeric_limits<uint16_t>::max();
+static constexpr size_t selEvtDataMaxSize = 3;
+static constexpr size_t selOemDataMaxSize = 13;
+
+static uint16_t selAddSystemRecord(const std::string &message,
+                                   const std::string &path,
+                                   const std::vector<uint8_t> &selData,
+                                   const bool &assert,
+                                   const uint16_t &genId = selBMCGenID);
diff --git a/include/sensorutils.hpp b/include/sensorutils.hpp
new file mode 100644
index 0000000..8d3ed75
--- /dev/null
+++ b/include/sensorutils.hpp
@@ -0,0 +1,196 @@
+/*
+// Copyright (c) 2017 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.
+*/
+
+#pragma once
+#include <cmath>
+#include <iostream>
+#include <phosphor-logging/log.hpp>
+
+namespace ipmi
+{
+/** @struct VariantToDoubleVisitor
+ *  @brief Visitor to convert variants to doubles
+ *  @details Performs a static cast on the underlying type
+ */
+struct VariantToDoubleVisitor
+{
+    template <typename T> double operator()(const T& t) const
+    {
+        static_assert(std::is_arithmetic_v<T>,
+                      "Cannot translate type to double");
+        return static_cast<double>(t);
+    }
+};
+
+static constexpr int16_t maxInt10 = 0x1FF;
+static constexpr int16_t minInt10 = -0x200;
+static constexpr int8_t maxInt4 = 7;
+static constexpr int8_t minInt4 = -8;
+
+static inline bool getSensorAttributes(const double max, const double min,
+                                       int16_t& mValue, int8_t& rExp,
+                                       int16_t& bValue, int8_t& bExp,
+                                       bool& bSigned)
+{
+    // computing y = (10^rRexp) * (Mx + (B*(10^Bexp)))
+    // check for 0, assume always positive
+    double mDouble;
+    double bDouble;
+    if (max <= min)
+    {
+        phosphor::logging::log<phosphor::logging::level::DEBUG>(
+            "getSensorAttributes: Max must be greater than min");
+        return false;
+    }
+
+    mDouble = (max - min) / 0xFF;
+
+    if (min < 0)
+    {
+        bSigned = true;
+        bDouble = floor(0.5 + ((max + min) / 2));
+    }
+    else
+    {
+        bSigned = false;
+        bDouble = min;
+    }
+
+    rExp = 0;
+
+    // M too big for 10 bit variable
+    while (mDouble > maxInt10)
+    {
+        if (rExp >= maxInt4)
+        {
+            phosphor::logging::log<phosphor::logging::level::DEBUG>(
+                "rExp Too big, Max and Min range too far",
+                phosphor::logging::entry("REXP=%d", rExp));
+            return false;
+        }
+        mDouble /= 10;
+        rExp++;
+    }
+
+    // M too small, loop until we lose less than 1 eight bit count of precision
+    while (((mDouble - floor(mDouble)) / mDouble) > (1.0 / 255))
+    {
+        if (rExp <= minInt4)
+        {
+            phosphor::logging::log<phosphor::logging::level::DEBUG>(
+                "rExp Too Small, Max and Min range too close");
+            return false;
+        }
+        // check to see if we reached the limit of where we can adjust back the
+        // B value
+        if (bDouble / std::pow(10, rExp + minInt4 - 1) > bDouble)
+        {
+            if (mDouble < 1.0)
+            {
+                phosphor::logging::log<phosphor::logging::level::DEBUG>(
+                    "Could not find mValue and B value with enough "
+                    "precision.");
+                return false;
+            }
+            break;
+        }
+        // can't multiply M any more, max precision reached
+        else if (mDouble * 10 > maxInt10)
+        {
+            break;
+        }
+        mDouble *= 10;
+        rExp--;
+    }
+
+    bDouble /= std::pow(10, rExp);
+    bExp = 0;
+
+    // B too big for 10 bit variable
+    while (bDouble > maxInt10 || bDouble < minInt10)
+    {
+        if (bExp >= maxInt4)
+        {
+            phosphor::logging::log<phosphor::logging::level::DEBUG>(
+                "bExp Too Big, Max and Min range need to be adjusted");
+            return false;
+        }
+        bDouble /= 10;
+        bExp++;
+    }
+
+    while (((fabs(bDouble) - floor(fabs(bDouble))) / fabs(bDouble)) >
+           (1.0 / 255))
+    {
+        if (bExp <= minInt4)
+        {
+            phosphor::logging::log<phosphor::logging::level::DEBUG>(
+                "bExp Too Small, Max and Min range need to be adjusted");
+            return false;
+        }
+        bDouble *= 10;
+        bExp -= 1;
+    }
+
+    mValue = static_cast<int16_t>(mDouble) & maxInt10;
+    bValue = static_cast<int16_t>(bDouble) & maxInt10;
+
+    return true;
+}
+
+static inline uint8_t
+    scaleIPMIValueFromDouble(const double value, const uint16_t mValue,
+                             const int8_t rExp, const uint16_t bValue,
+                             const int8_t bExp, const bool bSigned)
+{
+    uint32_t scaledValue =
+        (value - (bValue * std::pow(10, bExp) * std::pow(10, rExp))) /
+        (mValue * std::pow(10, rExp));
+
+    if (scaledValue > std::numeric_limits<uint8_t>::max() ||
+        scaledValue < std::numeric_limits<uint8_t>::lowest())
+    {
+        throw std::out_of_range("Value out of range");
+    }
+    if (bSigned)
+    {
+        return static_cast<int8_t>(scaledValue);
+    }
+    else
+    {
+        return static_cast<uint8_t>(scaledValue);
+    }
+}
+
+static inline uint8_t getScaledIPMIValue(const double value, const double max,
+                                         const double min)
+{
+    int16_t mValue = 0;
+    int8_t rExp = 0;
+    int16_t bValue = 0;
+    int8_t bExp = 0;
+    bool bSigned = 0;
+    bool result = 0;
+
+    result = getSensorAttributes(max, min, mValue, rExp, bValue, bExp, bSigned);
+    if (!result)
+    {
+        throw std::runtime_error("Illegal sensor attributes");
+    }
+    return scaleIPMIValueFromDouble(value, mValue, rExp, bValue, bExp, bSigned);
+}
+
+} // namespace ipmi
\ No newline at end of file
diff --git a/include/threshold_event_monitor.hpp b/include/threshold_event_monitor.hpp
new file mode 100644
index 0000000..de3a867
--- /dev/null
+++ b/include/threshold_event_monitor.hpp
@@ -0,0 +1,203 @@
+/*
+// 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.
+*/
+
+#pragma once
+#include <sel_logger.hpp>
+#include <sensorutils.hpp>
+
+enum class thresholdEventOffsets : uint8_t
+{
+    lowerNonCritGoingLow = 0x00,
+    lowerCritGoingLow = 0x02,
+    upperNonCritGoingHigh = 0x07,
+    upperCritGoingHigh = 0x09,
+};
+
+static constexpr const uint8_t thresholdEventDataTriggerReadingByte2 = (1 << 6);
+static constexpr const uint8_t thresholdEventDataTriggerReadingByte3 = (1 << 4);
+
+inline static sdbusplus::bus::match::match startThresholdEventMonitor(
+    std::shared_ptr<sdbusplus::asio::connection> conn)
+{
+    auto thresholdEventMatcherCallback = [conn](
+                                             sdbusplus::message::message &msg) {
+        // This static set of std::pair<path, event> tracks asserted events to
+        // avoid duplicate logs or deasserts logged without an assert
+        static boost::container::flat_set<std::pair<std::string, std::string>>
+            assertedEvents;
+        // SEL event data is three bytes where 0xFF means unspecified
+        std::vector<uint8_t> eventData(selEvtDataMaxSize, 0xFF);
+
+        // Get the event type and assertion details from the message
+        std::string thresholdInterface;
+        boost::container::flat_map<std::string,
+                                   sdbusplus::message::variant<bool>>
+            propertiesChanged;
+        msg.read(thresholdInterface, propertiesChanged);
+        std::string event = propertiesChanged.begin()->first;
+        bool *pval = sdbusplus::message::variant_ns::get_if<bool>(
+            &propertiesChanged.begin()->second);
+        if (!pval)
+        {
+            std::cerr << "threshold event direction has invalid type\n";
+            return;
+        }
+        bool assert = *pval;
+
+        // Check the asserted events to determine if we should log this event
+        std::pair<std::string, std::string> pathAndEvent(
+            std::string(msg.get_path()), event);
+        if (assert)
+        {
+            // For asserts, add the event to the set and only log it if it's new
+            if (assertedEvents.insert(pathAndEvent).second == false)
+            {
+                // event is already in the set
+                return;
+            }
+        }
+        else
+        {
+            // For deasserts, remove the event and only log the deassert if it
+            // was asserted
+            if (assertedEvents.erase(pathAndEvent) == 0)
+            {
+                // asserted event was not in the set
+                return;
+            }
+        }
+
+        // Set the IPMI threshold event type based on the event details from the
+        // message
+        if (event == "CriticalAlarmLow")
+        {
+            eventData[0] =
+                static_cast<uint8_t>(thresholdEventOffsets::lowerCritGoingLow);
+        }
+        else if (event == "WarningAlarmLow")
+        {
+            eventData[0] = static_cast<uint8_t>(
+                thresholdEventOffsets::lowerNonCritGoingLow);
+        }
+        else if (event == "WarningAlarmHigh")
+        {
+            eventData[0] = static_cast<uint8_t>(
+                thresholdEventOffsets::upperNonCritGoingHigh);
+        }
+        else if (event == "CriticalAlarmHigh")
+        {
+            eventData[0] =
+                static_cast<uint8_t>(thresholdEventOffsets::upperCritGoingHigh);
+        }
+        // Indicate that bytes 2 and 3 are threshold sensor trigger values
+        eventData[0] |= thresholdEventDataTriggerReadingByte2 |
+                        thresholdEventDataTriggerReadingByte3;
+
+        // Get the sensor reading to put in the event data
+        sdbusplus::message::message getSensorValue =
+            conn->new_method_call(msg.get_sender(), msg.get_path(),
+                                  "org.freedesktop.DBus.Properties", "GetAll");
+        getSensorValue.append("xyz.openbmc_project.Sensor.Value");
+        boost::container::flat_map<std::string,
+                                   sdbusplus::message::variant<double>>
+            sensorValue;
+        try
+        {
+            sdbusplus::message::message getSensorValueResp =
+                conn->call(getSensorValue);
+            getSensorValueResp.read(sensorValue);
+        }
+        catch (sdbusplus::exception_t &)
+        {
+            std::cerr << "error getting sensor value from " << msg.get_path()
+                      << "\n";
+            return;
+        }
+        double max = sdbusplus::message::variant_ns::visit(
+            ipmi::VariantToDoubleVisitor(), sensorValue["MaxValue"]);
+        double min = sdbusplus::message::variant_ns::visit(
+            ipmi::VariantToDoubleVisitor(), sensorValue["MinValue"]);
+        double sensorVal = sdbusplus::message::variant_ns::visit(
+            ipmi::VariantToDoubleVisitor(), sensorValue["Value"]);
+        try
+        {
+            eventData[1] = ipmi::getScaledIPMIValue(sensorVal, max, min);
+        }
+        catch (std::runtime_error &e)
+        {
+            std::cerr << e.what();
+            eventData[1] = 0xFF;
+        }
+
+        // Get the threshold value to put in the event data
+        // Get the threshold parameter by removing the "Alarm" text from the
+        // event string
+        std::string alarm("Alarm");
+        if (std::string::size_type pos = event.find(alarm);
+            pos != std::string::npos)
+        {
+            event.erase(pos, alarm.length());
+        }
+        sdbusplus::message::message getThreshold =
+            conn->new_method_call(msg.get_sender(), msg.get_path(),
+                                  "org.freedesktop.DBus.Properties", "Get");
+        getThreshold.append(thresholdInterface, event);
+        sdbusplus::message::variant<double> thresholdValue;
+        try
+        {
+            sdbusplus::message::message getThresholdResp =
+                conn->call(getThreshold);
+            getThresholdResp.read(thresholdValue);
+        }
+        catch (sdbusplus::exception_t &)
+        {
+            std::cerr << "error getting sensor threshold from "
+                      << msg.get_path() << "\n";
+            return;
+        }
+        double thresholdVal = sdbusplus::message::variant_ns::visit(
+            ipmi::VariantToDoubleVisitor(), thresholdValue);
+        try
+        {
+            eventData[2] = ipmi::getScaledIPMIValue(thresholdVal, max, min);
+        }
+        catch (std::runtime_error &e)
+        {
+            std::cerr << e.what();
+            eventData[2] = 0xFF;
+        }
+
+        // Construct a human-readable message of this event for the log
+        std::experimental::string_view sensorName(msg.get_path());
+        sensorName.remove_prefix(
+            std::min(sensorName.find_last_of("/") + 1, sensorName.size()));
+        std::string journalMsg(sensorName.to_string() +
+                               (assert ? " asserted " : " deasserted ") +
+                               propertiesChanged.begin()->first +
+                               ". Reading=" + std::to_string(sensorVal) +
+                               " Threshold=" + std::to_string(thresholdVal));
+
+        selAddSystemRecord(journalMsg, std::string(msg.get_path()), eventData,
+                           assert);
+    };
+    sdbusplus::bus::match::match thresholdEventMatcher(
+        static_cast<sdbusplus::bus::bus &>(*conn),
+        "type='signal',interface='org.freedesktop.DBus.Properties',member='"
+        "PropertiesChanged',arg0namespace='xyz.openbmc_project.Sensor."
+        "Threshold'",
+        std::move(thresholdEventMatcherCallback));
+    return thresholdEventMatcher;
+}
